[libc-commits] [libc] [libc] created integration tests for newhdrgen (PR #97361)

via libc-commits libc-commits at lists.llvm.org
Wed Jul 3 11:09:57 PDT 2024


https://github.com/aaryanshukla updated https://github.com/llvm/llvm-project/pull/97361

>From efd4b95fab1be1a6c58d4a8379dde24bc516c58d Mon Sep 17 00:00:00 2001
From: Aaryan Shukla <aaryanshukla at google.com>
Date: Mon, 1 Jul 2024 22:55:42 +0000
Subject: [PATCH 01/14] [libc] created integration tests for hdrgen

- added sorting to script so C headers are outputted in alpha order
---
 libc/newhdrgen/tests/expected_output/string.h | 102 ++++++
 libc/newhdrgen/tests/input/string.h.def       |  18 ++
 libc/newhdrgen/tests/input/test_string.yaml   | 303 ++++++++++++++++++
 libc/newhdrgen/tests/test_integration.py      |  42 +++
 libc/newhdrgen/yaml_to_classes.py             |   6 +-
 5 files changed, 469 insertions(+), 2 deletions(-)
 create mode 100644 libc/newhdrgen/tests/expected_output/string.h
 create mode 100644 libc/newhdrgen/tests/input/string.h.def
 create mode 100644 libc/newhdrgen/tests/input/test_string.yaml
 create mode 100644 libc/newhdrgen/tests/test_integration.py

diff --git a/libc/newhdrgen/tests/expected_output/string.h b/libc/newhdrgen/tests/expected_output/string.h
new file mode 100644
index 0000000000000..4dcb693c353e4
--- /dev/null
+++ b/libc/newhdrgen/tests/expected_output/string.h
@@ -0,0 +1,102 @@
+//===-- C standard library header string.h --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_STRING_H
+#define LLVM_LIBC_STRING_H
+
+#include "__llvm-libc-common.h"
+
+#include "llvm-libc-macros/null-macro.h"
+
+#include <llvm-libc-types/size_t.h>
+
+__BEGIN_C_DECLS
+
+void * memccpy(void *__restrict, const void *__restrict, int, size_t);
+
+void * memchr(const void *, int, size_t);
+
+int memcmp(const void *, const void *, size_t);
+
+void * memcpy(void *__restrict, const void *__restrict, size_t);
+
+void * memmem(const void *, size_t, const void *, size_t);
+
+void * memmove(void *, const void *, size_t);
+
+void * mempcpy(void *__restrict, const void *__restrict, size_t);
+
+void * memrchr(const void *, int, size_t);
+
+void * memset(void *, int, size_t);
+
+void * memset_explicit(void *, int, size_t);
+
+char * stpcpy(char *__restrict, const char *__restrict);
+
+char * stpncpy(char *__restrict, const char *__restrict, size_t);
+
+char * strcasestr(const char *, const char *);
+
+char * strcat(char *__restrict, const char *__restrict);
+
+char * strchr(const char *, int);
+
+char * strchrnul(const char *, int);
+
+int strcmp(const char *, const char *);
+
+int strcoll(const char *, const char *);
+
+char * strcpy(char *__restrict, const char *__restrict);
+
+size_t strcspn(const char *, const char *);
+
+char * strdup(const char *);
+
+char * strerror(int);
+
+char * strerror_r(int, char *, size_t);
+
+size_t strlcat(const char *__restrict, const char *__restrict, size_t);
+
+size_t strlcpy(const char *__restrict, const char *__restrict, size_t);
+
+size_t strlen(const char *);
+
+char * strncat(char *, const char *, size_t);
+
+int strncmp(const char *, const char *, size_t);
+
+char * strncpy(char *__restrict, const char *__restrict, size_t);
+
+char * strndup(const char *, size_t);
+
+size_t strnlen(const char *, size_t);
+
+char * strpbrk(const char *, const char *);
+
+char * strrchr(const char *, int);
+
+char * strsep(char * *__restrict, const char *__restrict);
+
+char * strsignal(int);
+
+size_t strspn(const char *, const char *);
+
+char * strstr(const char *, const char *);
+
+char * strtok(char *__restrict, const char *__restrict);
+
+char * strtok_r(char *__restrict, const char *__restrict, char * *__restrict);
+
+size_t strxfrm(char *__restrict, const char *__restrict, size_t);
+
+__END_C_DECLS
+
+#endif // LLVM_LIBC_STRING_H
diff --git a/libc/newhdrgen/tests/input/string.h.def b/libc/newhdrgen/tests/input/string.h.def
new file mode 100644
index 0000000000000..1bd2687db2bea
--- /dev/null
+++ b/libc/newhdrgen/tests/input/string.h.def
@@ -0,0 +1,18 @@
+//===-- C standard library header string.h --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_STRING_H
+#define LLVM_LIBC_STRING_H
+
+#include "__llvm-libc-common.h"
+
+#include "llvm-libc-macros/null-macro.h"
+
+%%public_api()
+
+#endif // LLVM_LIBC_STRING_H
diff --git a/libc/newhdrgen/tests/input/test_string.yaml b/libc/newhdrgen/tests/input/test_string.yaml
new file mode 100644
index 0000000000000..2754f856bc807
--- /dev/null
+++ b/libc/newhdrgen/tests/input/test_string.yaml
@@ -0,0 +1,303 @@
+header: string.h
+macros: []
+types:
+  - type_name: size_t
+enums: []
+objects: []
+functions:
+  - name: memcpy
+    standards: 
+      - stdc
+    return_type: void *
+    arguments:
+      - type: void *__restrict
+      - type: const void *__restrict
+      - type: size_t
+  - name: memmove
+    standards: 
+      - stdc
+    return_type: void *
+    arguments:
+      - type: void *
+      - type: const void *
+      - type: size_t
+  - name: memcmp
+    standards: 
+      - stdc
+    return_type: int
+    arguments:
+      - type: const void *
+      - type: const void *
+      - type: size_t
+  - name: memchr
+    standards: 
+      - stdc
+    return_type: void *
+    arguments:
+      - type: const void *
+      - type: int
+      - type: size_t
+  - name: memset
+    standards: 
+      - stdc
+    return_type: void *
+    arguments:
+      - type: void *
+      - type: int
+      - type: size_t
+  - name: memset_explicit
+    standards: 
+      - stdc
+    return_type: void *
+    arguments:
+      - type: void *
+      - type: int
+      - type: size_t
+  - name: strcpy
+    standards: 
+      - stdc
+    return_type: char
+    arguments:
+      - type: char *__restrict
+      - type: const char *__restrict
+  - name: strncpy
+    standards: 
+      - stdc
+    return_type: char *
+    arguments:
+      - type: char *__restrict
+      - type: const char *__restrict
+      - type: size_t
+  - name: strcat
+    standards: 
+      - stdc
+    return_type: char *
+    arguments:
+      - type: char *__restrict
+      - type: const char *__restrict
+  - name: strncat
+    standards: 
+      - stdc
+    return_type: char *
+    arguments:
+      - type: char *
+      - type: const char *
+      - type: size_t
+  - name: strcmp
+    standards: 
+      - stdc
+    return_type: int
+    arguments:
+      - type: const char *
+      - type: const char *
+  - name: strcoll
+    standards: 
+      - stdc
+    return_type: int
+    arguments:
+      - type: const char *
+      - type: const char *
+  - name: strncmp
+    standards: 
+      - stdc
+    return_type: int
+    arguments:
+      - type: const char *
+      - type: const char *
+      - type: size_t
+  - name: strxfrm
+    standards: 
+      - stdc
+    return_type: size_t
+    arguments:
+      - type: char *__restrict
+      - type: const char *__restrict
+      - type: size_t
+  - name: strchr
+    standards: 
+      - stdc
+    return_type: char *
+    arguments:
+      - type: const char *
+      - type: int
+  - name: strcspn
+    standards: 
+      - stdc
+    return_type: size_t
+    arguments:
+      - type: const char *
+      - type: const char *
+  - name: strdup
+    return_type: char *
+    arguments:
+      - type: const char *
+  - name: strndup
+    standards: 
+      - stdc
+    return_type: char *
+    arguments:
+      - type: const char *
+      - type: size_t
+  - name: strpbrk
+    standards: 
+      - stdc
+    return_type: char *
+    arguments:
+      - type: const char *
+      - type: const char *
+  - name: strrchr
+    standards: 
+      - stdc
+    return_type: char *
+    arguments:
+      - type: const char *
+      - type: int
+  - name: strspn
+    standards: 
+      - stdc
+    return_type: size_t
+    arguments:
+      - type: const char *
+      - type: const char *
+  - name: strstr
+    standards: 
+      - stdc
+    return_type: char *
+    arguments:
+      - type: const char *
+      - type: const char *
+  - name: strtok
+    standards: 
+      - stdc
+    return_type: char *
+    arguments:
+      - type: char *__restrict
+      - type: const char *__restrict
+  - name: strerror
+    standards: 
+      - stdc
+    return_type: char *
+    arguments:
+      - type: int
+  - name: strlen
+    standards: 
+      - stdc
+    return_type: size_t
+    arguments:
+      - type: const char *
+  - name: memccpy
+    standards: 
+      - POSIX
+    return_type: void *
+    arguments:
+      - type: void *__restrict
+      - type: const void *__restrict
+      - type: int
+      - type: size_t
+  - name: mempcpy
+    standards: 
+      - POSIX
+    return_type: void *
+    arguments:
+      - type: void *__restrict
+      - type: const void *__restrict
+      - type: size_t
+  - name: stpcpy
+    standards: 
+      - POSIX
+    return_type: char *
+    arguments:
+      - type: char *__restrict
+      - type: const char *__restrict
+  - name: stpncpy
+    standards: 
+      - POSIX
+    return_type: char *
+    arguments:
+      - type: char *__restrict
+      - type: const char *__restrict
+      - type: size_t
+  - name: strnlen
+    standards: 
+      - POSIX
+    return_type: size_t
+    arguments:
+      - type: const char *
+      - type: size_t
+  - name: strtok_r
+    standards: 
+      - POSIX
+    return_type: char *
+    arguments:
+      - type: char *__restrict
+      - type: const char *__restrict
+      - type: char ** __restrict
+  - name: strsignal
+    standards: 
+      - POSIX
+    return_type: char *
+    arguments:
+      - type: int
+  - name: memmem
+    standards: 
+      - GNUExtensions
+    return_type: void *
+    arguments:
+      - type: const void *
+      - type: size_t
+      - type: const void *
+      - type: size_t
+  - name: memrchr
+    standards: 
+      - GNUExtensions
+    return_type: void *
+    arguments:
+      - type: const void *
+      - type: int
+      - type: size_t
+  - name: strerror_r
+    standards: 
+      - GNUExtensions
+    return_type: char *
+    arguments:
+      - type: int
+      - type: char *
+      - type: size_t
+  - name: strcasestr
+    standards: 
+      - GNUExtensions
+    return_type: char *
+    arguments:
+      - type: const char *
+      - type: const char *
+  - name: strchrnul
+    standards: 
+      - GNUExtensions
+    return_type: char *
+    arguments:
+      - type: const char *
+      - type: int
+  - name: strlcat
+    standards: 
+      - BSDExtensions
+    return_type: size_t
+    arguments:
+      - type: char *__restrict
+      - type: char *__restrict
+      - type: size_t
+  - name: strlcpy
+    standards: 
+      - BSDExtensions
+    return_type: size_t
+    arguments:
+      - type: char *__restrict
+      - type: char *__restrict
+      - type: size_t
+  - name: strsep
+    standards: 
+      - BSDExtensions
+    return_type: char *
+    arguments:
+      - type: char **__restrict
+      - type: char *__restrict
+
diff --git a/libc/newhdrgen/tests/test_integration.py b/libc/newhdrgen/tests/test_integration.py
new file mode 100644
index 0000000000000..ca485dc0377c1
--- /dev/null
+++ b/libc/newhdrgen/tests/test_integration.py
@@ -0,0 +1,42 @@
+import subprocess
+import unittest
+from pathlib import Path
+
+class TestHeaderGenIntegration(unittest.TestCase):
+    def setUp(self):
+        self.output_dir = Path('tests/output')
+        self.maxDiff = None  
+
+    def run_script(self, yaml_file, h_def_file, output_dir):
+        result = subprocess.run([
+            'python3', 'yaml_to_classes.py', yaml_file, h_def_file, '--output_dir', str(output_dir)
+        ], capture_output=True, text=True)
+
+        print("STDOUT:", result.stdout)
+        print("STDERR:", result.stderr)
+        result.check_returncode() 
+
+    def compare_files(self, generated_file, expected_file):
+        with generated_file.open('r') as gen_file:
+            gen_content = gen_file.read()
+        with expected_file.open('r') as exp_file:
+            exp_content = exp_file.read()
+        
+        self.assertEqual(gen_content, exp_content)
+
+    def test_generate_header(self):
+        # this is for example, will find a way to test everything at once
+        yaml_file = Path('tests/input/test_string.yaml')
+        h_def_file = Path('tests/input/string.h.def')
+        expected_output_file = Path('tests/expected_output/string.h')
+        output_file = self.output_dir / 'string.h'
+
+        if not self.output_dir.exists():
+            self.output_dir.mkdir(parents=True)
+
+        self.run_script(yaml_file, h_def_file, self.output_dir)
+
+        self.compare_files(output_file, expected_output_file)
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/libc/newhdrgen/yaml_to_classes.py b/libc/newhdrgen/yaml_to_classes.py
index 9b52c9cf9bb7c..65a990c8a8767 100644
--- a/libc/newhdrgen/yaml_to_classes.py
+++ b/libc/newhdrgen/yaml_to_classes.py
@@ -46,11 +46,13 @@ def yaml_to_classes(yaml_data):
             Enumeration(enum_data["name"], enum_data.get("value", None))
         )
 
-    for function_data in yaml_data.get("functions", []):
+    functions = yaml_data.get("functions", [])
+    sorted_functions = sorted(functions, key=lambda x: x['name'])
+    for function_data in sorted_functions:
         arguments = [arg["type"] for arg in function_data["arguments"]]
         guard = function_data.get("guard", None)
         attributes = function_data.get("attributes", None)
-        standards = (function_data.get("standards", None),)
+        standards = function_data.get("standards", None)
         header.add_function(
             Function(
                 function_data["return_type"],

>From f86c14bbf243b9d25daedbd0021ffa3b8058f7ea Mon Sep 17 00:00:00 2001
From: Aaryan Shukla <aaryanshukla at google.com>
Date: Mon, 1 Jul 2024 22:55:42 +0000
Subject: [PATCH 02/14] [libc] created integration tests for hdrgen

- added sorting to script so C headers are outputted in alpha order

>From 722a2eea3b11070b5436d1f402107cd76dbaab3d Mon Sep 17 00:00:00 2001
From: Aaryan Shukla <aaryanshukla at google.com>
Date: Mon, 1 Jul 2024 23:15:37 +0000
Subject: [PATCH 03/14] fixed formatting

---
 libc/newhdrgen/tests/test_integration.py | 39 +++++++++++++++---------
 libc/newhdrgen/yaml_to_classes.py        |  2 +-
 2 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/libc/newhdrgen/tests/test_integration.py b/libc/newhdrgen/tests/test_integration.py
index ca485dc0377c1..1a942b461ad02 100644
--- a/libc/newhdrgen/tests/test_integration.py
+++ b/libc/newhdrgen/tests/test_integration.py
@@ -2,34 +2,44 @@
 import unittest
 from pathlib import Path
 
+
 class TestHeaderGenIntegration(unittest.TestCase):
     def setUp(self):
-        self.output_dir = Path('tests/output')
-        self.maxDiff = None  
+        self.output_dir = Path("tests/output")
+        self.maxDiff = None
 
     def run_script(self, yaml_file, h_def_file, output_dir):
-        result = subprocess.run([
-            'python3', 'yaml_to_classes.py', yaml_file, h_def_file, '--output_dir', str(output_dir)
-        ], capture_output=True, text=True)
+        result = subprocess.run(
+            [
+                "python3",
+                "yaml_to_classes.py",
+                yaml_file,
+                h_def_file,
+                "--output_dir",
+                str(output_dir),
+            ],
+            capture_output=True,
+            text=True,
+        )
 
         print("STDOUT:", result.stdout)
         print("STDERR:", result.stderr)
-        result.check_returncode() 
+        result.check_returncode()
 
     def compare_files(self, generated_file, expected_file):
-        with generated_file.open('r') as gen_file:
+        with generated_file.open("r") as gen_file:
             gen_content = gen_file.read()
-        with expected_file.open('r') as exp_file:
+        with expected_file.open("r") as exp_file:
             exp_content = exp_file.read()
-        
+
         self.assertEqual(gen_content, exp_content)
 
     def test_generate_header(self):
         # this is for example, will find a way to test everything at once
-        yaml_file = Path('tests/input/test_string.yaml')
-        h_def_file = Path('tests/input/string.h.def')
-        expected_output_file = Path('tests/expected_output/string.h')
-        output_file = self.output_dir / 'string.h'
+        yaml_file = Path("tests/input/test_string.yaml")
+        h_def_file = Path("tests/input/string.h.def")
+        expected_output_file = Path("tests/expected_output/string.h")
+        output_file = self.output_dir / "string.h"
 
         if not self.output_dir.exists():
             self.output_dir.mkdir(parents=True)
@@ -38,5 +48,6 @@ def test_generate_header(self):
 
         self.compare_files(output_file, expected_output_file)
 
-if __name__ == '__main__':
+
+if __name__ == "__main__":
     unittest.main()
diff --git a/libc/newhdrgen/yaml_to_classes.py b/libc/newhdrgen/yaml_to_classes.py
index 65a990c8a8767..e489c7f509b8e 100644
--- a/libc/newhdrgen/yaml_to_classes.py
+++ b/libc/newhdrgen/yaml_to_classes.py
@@ -47,7 +47,7 @@ def yaml_to_classes(yaml_data):
         )
 
     functions = yaml_data.get("functions", [])
-    sorted_functions = sorted(functions, key=lambda x: x['name'])
+    sorted_functions = sorted(functions, key=lambda x: x["name"])
     for function_data in sorted_functions:
         arguments = [arg["type"] for arg in function_data["arguments"]]
         guard = function_data.get("guard", None)

>From 62b6d624aaa7897bea05448548ea6039f8e6d06f Mon Sep 17 00:00:00 2001
From: Aaryan Shukla <aaryanshukla at google.com>
Date: Mon, 1 Jul 2024 23:21:39 +0000
Subject: [PATCH 04/14] clang formatter on string.h

---
 libc/newhdrgen/tests/expected_output/string.h | 58 +++++++++----------
 1 file changed, 29 insertions(+), 29 deletions(-)

diff --git a/libc/newhdrgen/tests/expected_output/string.h b/libc/newhdrgen/tests/expected_output/string.h
index 4dcb693c353e4..12ec66e4ff55b 100644
--- a/libc/newhdrgen/tests/expected_output/string.h
+++ b/libc/newhdrgen/tests/expected_output/string.h
@@ -17,51 +17,51 @@
 
 __BEGIN_C_DECLS
 
-void * memccpy(void *__restrict, const void *__restrict, int, size_t);
+void *memccpy(void *__restrict, const void *__restrict, int, size_t);
 
-void * memchr(const void *, int, size_t);
+void *memchr(const void *, int, size_t);
 
 int memcmp(const void *, const void *, size_t);
 
-void * memcpy(void *__restrict, const void *__restrict, size_t);
+void *memcpy(void *__restrict, const void *__restrict, size_t);
 
-void * memmem(const void *, size_t, const void *, size_t);
+void *memmem(const void *, size_t, const void *, size_t);
 
-void * memmove(void *, const void *, size_t);
+void *memmove(void *, const void *, size_t);
 
-void * mempcpy(void *__restrict, const void *__restrict, size_t);
+void *mempcpy(void *__restrict, const void *__restrict, size_t);
 
-void * memrchr(const void *, int, size_t);
+void *memrchr(const void *, int, size_t);
 
-void * memset(void *, int, size_t);
+void *memset(void *, int, size_t);
 
-void * memset_explicit(void *, int, size_t);
+void *memset_explicit(void *, int, size_t);
 
-char * stpcpy(char *__restrict, const char *__restrict);
+char *stpcpy(char *__restrict, const char *__restrict);
 
-char * stpncpy(char *__restrict, const char *__restrict, size_t);
+char *stpncpy(char *__restrict, const char *__restrict, size_t);
 
-char * strcasestr(const char *, const char *);
+char *strcasestr(const char *, const char *);
 
-char * strcat(char *__restrict, const char *__restrict);
+char *strcat(char *__restrict, const char *__restrict);
 
-char * strchr(const char *, int);
+char *strchr(const char *, int);
 
-char * strchrnul(const char *, int);
+char *strchrnul(const char *, int);
 
 int strcmp(const char *, const char *);
 
 int strcoll(const char *, const char *);
 
-char * strcpy(char *__restrict, const char *__restrict);
+char *strcpy(char *__restrict, const char *__restrict);
 
 size_t strcspn(const char *, const char *);
 
-char * strdup(const char *);
+char *strdup(const char *);
 
-char * strerror(int);
+char *strerror(int);
 
-char * strerror_r(int, char *, size_t);
+char *strerror_r(int, char *, size_t);
 
 size_t strlcat(const char *__restrict, const char *__restrict, size_t);
 
@@ -69,31 +69,31 @@ size_t strlcpy(const char *__restrict, const char *__restrict, size_t);
 
 size_t strlen(const char *);
 
-char * strncat(char *, const char *, size_t);
+char *strncat(char *, const char *, size_t);
 
 int strncmp(const char *, const char *, size_t);
 
-char * strncpy(char *__restrict, const char *__restrict, size_t);
+char *strncpy(char *__restrict, const char *__restrict, size_t);
 
-char * strndup(const char *, size_t);
+char *strndup(const char *, size_t);
 
 size_t strnlen(const char *, size_t);
 
-char * strpbrk(const char *, const char *);
+char *strpbrk(const char *, const char *);
 
-char * strrchr(const char *, int);
+char *strrchr(const char *, int);
 
-char * strsep(char * *__restrict, const char *__restrict);
+char *strsep(char **__restrict, const char *__restrict);
 
-char * strsignal(int);
+char *strsignal(int);
 
 size_t strspn(const char *, const char *);
 
-char * strstr(const char *, const char *);
+char *strstr(const char *, const char *);
 
-char * strtok(char *__restrict, const char *__restrict);
+char *strtok(char *__restrict, const char *__restrict);
 
-char * strtok_r(char *__restrict, const char *__restrict, char * *__restrict);
+char *strtok_r(char *__restrict, const char *__restrict, char **__restrict);
 
 size_t strxfrm(char *__restrict, const char *__restrict, size_t);
 

>From 80650e02396028acc1d844aba4b2da3a75fbc5d3 Mon Sep 17 00:00:00 2001
From: Aaryan Shukla <aaryanshukla at google.com>
Date: Tue, 2 Jul 2024 20:21:54 +0000
Subject: [PATCH 05/14] using small testing files instead

changed header.py for spacing issues
added .strip to script for spacing issues
---
 libc/newhdrgen/header.py                      |  12 +-
 libc/newhdrgen/tests/expected_output/string.h | 102 ------
 .../tests/expected_output/test_header.h       |  36 +++
 .../input/{string.h.def => test_small.h.def}  |  11 +-
 libc/newhdrgen/tests/input/test_small.yaml    |  32 ++
 libc/newhdrgen/tests/input/test_string.yaml   | 303 ------------------
 libc/newhdrgen/tests/test_integration.py      |  35 +-
 libc/newhdrgen/yaml_to_classes.py             |   1 +
 8 files changed, 106 insertions(+), 426 deletions(-)
 delete mode 100644 libc/newhdrgen/tests/expected_output/string.h
 create mode 100644 libc/newhdrgen/tests/expected_output/test_header.h
 rename libc/newhdrgen/tests/input/{string.h.def => test_small.h.def} (60%)
 create mode 100644 libc/newhdrgen/tests/input/test_small.yaml
 delete mode 100644 libc/newhdrgen/tests/input/test_string.yaml

diff --git a/libc/newhdrgen/header.py b/libc/newhdrgen/header.py
index 7ce356831677e..f12afdc4c9728 100644
--- a/libc/newhdrgen/header.py
+++ b/libc/newhdrgen/header.py
@@ -46,9 +46,6 @@ def __str__(self):
         for macro in self.macros:
             content.append(str(macro))
 
-        for object in self.objects:
-            content.append(str(object))
-
         for type_ in self.types:
             content.append(str(type_))
 
@@ -58,10 +55,13 @@ def __str__(self):
                 content.append(f"\t{str(enum)},")
             content.append("};")
 
-        # TODO: replace line below with common.h functionality
-        content.append("__BEGIN_C_DECLS\n")
+        content.append("\n__BEGIN_C_DECLS\n")
+
         for function in self.functions:
             content.append(str(function))
             content.append("")
-        content.append("__END_C_DECLS\n")
+        for object in self.objects:
+            content.append(str(object))
+        content.append("__END_C_DECLS")
+
         return "\n".join(content)
diff --git a/libc/newhdrgen/tests/expected_output/string.h b/libc/newhdrgen/tests/expected_output/string.h
deleted file mode 100644
index 12ec66e4ff55b..0000000000000
--- a/libc/newhdrgen/tests/expected_output/string.h
+++ /dev/null
@@ -1,102 +0,0 @@
-//===-- C standard library header string.h --------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIBC_STRING_H
-#define LLVM_LIBC_STRING_H
-
-#include "__llvm-libc-common.h"
-
-#include "llvm-libc-macros/null-macro.h"
-
-#include <llvm-libc-types/size_t.h>
-
-__BEGIN_C_DECLS
-
-void *memccpy(void *__restrict, const void *__restrict, int, size_t);
-
-void *memchr(const void *, int, size_t);
-
-int memcmp(const void *, const void *, size_t);
-
-void *memcpy(void *__restrict, const void *__restrict, size_t);
-
-void *memmem(const void *, size_t, const void *, size_t);
-
-void *memmove(void *, const void *, size_t);
-
-void *mempcpy(void *__restrict, const void *__restrict, size_t);
-
-void *memrchr(const void *, int, size_t);
-
-void *memset(void *, int, size_t);
-
-void *memset_explicit(void *, int, size_t);
-
-char *stpcpy(char *__restrict, const char *__restrict);
-
-char *stpncpy(char *__restrict, const char *__restrict, size_t);
-
-char *strcasestr(const char *, const char *);
-
-char *strcat(char *__restrict, const char *__restrict);
-
-char *strchr(const char *, int);
-
-char *strchrnul(const char *, int);
-
-int strcmp(const char *, const char *);
-
-int strcoll(const char *, const char *);
-
-char *strcpy(char *__restrict, const char *__restrict);
-
-size_t strcspn(const char *, const char *);
-
-char *strdup(const char *);
-
-char *strerror(int);
-
-char *strerror_r(int, char *, size_t);
-
-size_t strlcat(const char *__restrict, const char *__restrict, size_t);
-
-size_t strlcpy(const char *__restrict, const char *__restrict, size_t);
-
-size_t strlen(const char *);
-
-char *strncat(char *, const char *, size_t);
-
-int strncmp(const char *, const char *, size_t);
-
-char *strncpy(char *__restrict, const char *__restrict, size_t);
-
-char *strndup(const char *, size_t);
-
-size_t strnlen(const char *, size_t);
-
-char *strpbrk(const char *, const char *);
-
-char *strrchr(const char *, int);
-
-char *strsep(char **__restrict, const char *__restrict);
-
-char *strsignal(int);
-
-size_t strspn(const char *, const char *);
-
-char *strstr(const char *, const char *);
-
-char *strtok(char *__restrict, const char *__restrict);
-
-char *strtok_r(char *__restrict, const char *__restrict, char **__restrict);
-
-size_t strxfrm(char *__restrict, const char *__restrict, size_t);
-
-__END_C_DECLS
-
-#endif // LLVM_LIBC_STRING_H
diff --git a/libc/newhdrgen/tests/expected_output/test_header.h b/libc/newhdrgen/tests/expected_output/test_header.h
new file mode 100644
index 0000000000000..552f93eadf44d
--- /dev/null
+++ b/libc/newhdrgen/tests/expected_output/test_header.h
@@ -0,0 +1,36 @@
+//===-- C standard library header test_small-------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TEST_SMALL_H
+#define LLVM_LIBC_TEST_SMALL_H
+
+#include "__llvm-libc-common.h"
+#include "llvm-libc-macros/test_small-macros.h"
+
+#define MACRO_A 1
+#define MACRO_B 2
+
+#include <llvm-libc-types/type_a.h>
+#include <llvm-libc-types/type_b.h>
+
+enum {
+  enum_a = value_1,
+  enum_b = value_2,
+};
+
+__BEGIN_C_DECLS
+
+void func_a();
+
+int func_b(int, float);
+
+extern obj object_1 extern obj object_2
+
+    __END_C_DECLS
+
+#endif // LLVM_LIBC_TEST_SMALL_H
diff --git a/libc/newhdrgen/tests/input/string.h.def b/libc/newhdrgen/tests/input/test_small.h.def
similarity index 60%
rename from libc/newhdrgen/tests/input/string.h.def
rename to libc/newhdrgen/tests/input/test_small.h.def
index 1bd2687db2bea..38f86699840c7 100644
--- a/libc/newhdrgen/tests/input/string.h.def
+++ b/libc/newhdrgen/tests/input/test_small.h.def
@@ -1,4 +1,4 @@
-//===-- C standard library header string.h --------------------------------===//
+ //===-- C standard library header test_small-------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,13 +6,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_LIBC_STRING_H
-#define LLVM_LIBC_STRING_H
+#ifndef LLVM_LIBC_TEST_SMALL_H
+#define LLVM_LIBC_TEST_SMALL_H
 
 #include "__llvm-libc-common.h"
-
-#include "llvm-libc-macros/null-macro.h"
+#include "llvm-libc-macros/test_small-macros.h"
 
 %%public_api()
 
-#endif // LLVM_LIBC_STRING_H
+#endif // LLVM_LIBC_TEST_SMALL_H
diff --git a/libc/newhdrgen/tests/input/test_small.yaml b/libc/newhdrgen/tests/input/test_small.yaml
new file mode 100644
index 0000000000000..a3cbd2e21327a
--- /dev/null
+++ b/libc/newhdrgen/tests/input/test_small.yaml
@@ -0,0 +1,32 @@
+header: test_header.h
+macros:
+  - macro_name: MACRO_A
+    macro_value: 1
+  - macro_name: MACRO_B
+    macro_value: 2
+types:
+  - type_name: type_a
+  - type_name: type_b
+enums:
+  - name: enum_a
+    value: value_1
+  - name: enum_b
+    value: value_3
+objects:
+  - object_name: object_1
+    object_type: obj
+  - object_name: object_2
+    object_type: obj
+functions:
+  - name: func_a
+    return_type: void
+    arguments: []
+    standards: 
+      - stdc
+  - name: func_b
+    return_type: int
+    arguments:
+      - type: int
+      - type: float
+    standards: 
+      - stdc
diff --git a/libc/newhdrgen/tests/input/test_string.yaml b/libc/newhdrgen/tests/input/test_string.yaml
deleted file mode 100644
index 2754f856bc807..0000000000000
--- a/libc/newhdrgen/tests/input/test_string.yaml
+++ /dev/null
@@ -1,303 +0,0 @@
-header: string.h
-macros: []
-types:
-  - type_name: size_t
-enums: []
-objects: []
-functions:
-  - name: memcpy
-    standards: 
-      - stdc
-    return_type: void *
-    arguments:
-      - type: void *__restrict
-      - type: const void *__restrict
-      - type: size_t
-  - name: memmove
-    standards: 
-      - stdc
-    return_type: void *
-    arguments:
-      - type: void *
-      - type: const void *
-      - type: size_t
-  - name: memcmp
-    standards: 
-      - stdc
-    return_type: int
-    arguments:
-      - type: const void *
-      - type: const void *
-      - type: size_t
-  - name: memchr
-    standards: 
-      - stdc
-    return_type: void *
-    arguments:
-      - type: const void *
-      - type: int
-      - type: size_t
-  - name: memset
-    standards: 
-      - stdc
-    return_type: void *
-    arguments:
-      - type: void *
-      - type: int
-      - type: size_t
-  - name: memset_explicit
-    standards: 
-      - stdc
-    return_type: void *
-    arguments:
-      - type: void *
-      - type: int
-      - type: size_t
-  - name: strcpy
-    standards: 
-      - stdc
-    return_type: char
-    arguments:
-      - type: char *__restrict
-      - type: const char *__restrict
-  - name: strncpy
-    standards: 
-      - stdc
-    return_type: char *
-    arguments:
-      - type: char *__restrict
-      - type: const char *__restrict
-      - type: size_t
-  - name: strcat
-    standards: 
-      - stdc
-    return_type: char *
-    arguments:
-      - type: char *__restrict
-      - type: const char *__restrict
-  - name: strncat
-    standards: 
-      - stdc
-    return_type: char *
-    arguments:
-      - type: char *
-      - type: const char *
-      - type: size_t
-  - name: strcmp
-    standards: 
-      - stdc
-    return_type: int
-    arguments:
-      - type: const char *
-      - type: const char *
-  - name: strcoll
-    standards: 
-      - stdc
-    return_type: int
-    arguments:
-      - type: const char *
-      - type: const char *
-  - name: strncmp
-    standards: 
-      - stdc
-    return_type: int
-    arguments:
-      - type: const char *
-      - type: const char *
-      - type: size_t
-  - name: strxfrm
-    standards: 
-      - stdc
-    return_type: size_t
-    arguments:
-      - type: char *__restrict
-      - type: const char *__restrict
-      - type: size_t
-  - name: strchr
-    standards: 
-      - stdc
-    return_type: char *
-    arguments:
-      - type: const char *
-      - type: int
-  - name: strcspn
-    standards: 
-      - stdc
-    return_type: size_t
-    arguments:
-      - type: const char *
-      - type: const char *
-  - name: strdup
-    return_type: char *
-    arguments:
-      - type: const char *
-  - name: strndup
-    standards: 
-      - stdc
-    return_type: char *
-    arguments:
-      - type: const char *
-      - type: size_t
-  - name: strpbrk
-    standards: 
-      - stdc
-    return_type: char *
-    arguments:
-      - type: const char *
-      - type: const char *
-  - name: strrchr
-    standards: 
-      - stdc
-    return_type: char *
-    arguments:
-      - type: const char *
-      - type: int
-  - name: strspn
-    standards: 
-      - stdc
-    return_type: size_t
-    arguments:
-      - type: const char *
-      - type: const char *
-  - name: strstr
-    standards: 
-      - stdc
-    return_type: char *
-    arguments:
-      - type: const char *
-      - type: const char *
-  - name: strtok
-    standards: 
-      - stdc
-    return_type: char *
-    arguments:
-      - type: char *__restrict
-      - type: const char *__restrict
-  - name: strerror
-    standards: 
-      - stdc
-    return_type: char *
-    arguments:
-      - type: int
-  - name: strlen
-    standards: 
-      - stdc
-    return_type: size_t
-    arguments:
-      - type: const char *
-  - name: memccpy
-    standards: 
-      - POSIX
-    return_type: void *
-    arguments:
-      - type: void *__restrict
-      - type: const void *__restrict
-      - type: int
-      - type: size_t
-  - name: mempcpy
-    standards: 
-      - POSIX
-    return_type: void *
-    arguments:
-      - type: void *__restrict
-      - type: const void *__restrict
-      - type: size_t
-  - name: stpcpy
-    standards: 
-      - POSIX
-    return_type: char *
-    arguments:
-      - type: char *__restrict
-      - type: const char *__restrict
-  - name: stpncpy
-    standards: 
-      - POSIX
-    return_type: char *
-    arguments:
-      - type: char *__restrict
-      - type: const char *__restrict
-      - type: size_t
-  - name: strnlen
-    standards: 
-      - POSIX
-    return_type: size_t
-    arguments:
-      - type: const char *
-      - type: size_t
-  - name: strtok_r
-    standards: 
-      - POSIX
-    return_type: char *
-    arguments:
-      - type: char *__restrict
-      - type: const char *__restrict
-      - type: char ** __restrict
-  - name: strsignal
-    standards: 
-      - POSIX
-    return_type: char *
-    arguments:
-      - type: int
-  - name: memmem
-    standards: 
-      - GNUExtensions
-    return_type: void *
-    arguments:
-      - type: const void *
-      - type: size_t
-      - type: const void *
-      - type: size_t
-  - name: memrchr
-    standards: 
-      - GNUExtensions
-    return_type: void *
-    arguments:
-      - type: const void *
-      - type: int
-      - type: size_t
-  - name: strerror_r
-    standards: 
-      - GNUExtensions
-    return_type: char *
-    arguments:
-      - type: int
-      - type: char *
-      - type: size_t
-  - name: strcasestr
-    standards: 
-      - GNUExtensions
-    return_type: char *
-    arguments:
-      - type: const char *
-      - type: const char *
-  - name: strchrnul
-    standards: 
-      - GNUExtensions
-    return_type: char *
-    arguments:
-      - type: const char *
-      - type: int
-  - name: strlcat
-    standards: 
-      - BSDExtensions
-    return_type: size_t
-    arguments:
-      - type: char *__restrict
-      - type: char *__restrict
-      - type: size_t
-  - name: strlcpy
-    standards: 
-      - BSDExtensions
-    return_type: size_t
-    arguments:
-      - type: char *__restrict
-      - type: char *__restrict
-      - type: size_t
-  - name: strsep
-    standards: 
-      - BSDExtensions
-    return_type: char *
-    arguments:
-      - type: char **__restrict
-      - type: char *__restrict
-
diff --git a/libc/newhdrgen/tests/test_integration.py b/libc/newhdrgen/tests/test_integration.py
index 1a942b461ad02..1aa7e550520aa 100644
--- a/libc/newhdrgen/tests/test_integration.py
+++ b/libc/newhdrgen/tests/test_integration.py
@@ -1,20 +1,36 @@
 import subprocess
 import unittest
 from pathlib import Path
+import os
+import argparse
 
 
 class TestHeaderGenIntegration(unittest.TestCase):
     def setUp(self):
-        self.output_dir = Path("tests/output")
+        parser = argparse.ArgumentParser(
+            description="TestHeaderGenIntegration arguments"
+        )
+        parser.add_argument(
+            "--output_dir", type=str, help="Output directory for generated headers"
+        )
+        args, _ = parser.parse_known_args()
+        output_dir_env = os.getenv("TEST_OUTPUT_DIR")
+
+        self.output_dir = Path(
+            args.output_dir
+            if args.output_dir
+            else output_dir_env if output_dir_env else "libc/newhdrgen/tests/output"
+        )
+
         self.maxDiff = None
 
     def run_script(self, yaml_file, h_def_file, output_dir):
         result = subprocess.run(
             [
                 "python3",
-                "yaml_to_classes.py",
-                yaml_file,
-                h_def_file,
+                "libc/newhdrgen/yaml_to_classes.py",
+                str(yaml_file),
+                str(h_def_file),
                 "--output_dir",
                 str(output_dir),
             ],
@@ -35,11 +51,12 @@ def compare_files(self, generated_file, expected_file):
         self.assertEqual(gen_content, exp_content)
 
     def test_generate_header(self):
-        # this is for example, will find a way to test everything at once
-        yaml_file = Path("tests/input/test_string.yaml")
-        h_def_file = Path("tests/input/string.h.def")
-        expected_output_file = Path("tests/expected_output/string.h")
-        output_file = self.output_dir / "string.h"
+        yaml_file = Path("libc/newhdrgen/tests/input/test_small.yaml")
+        h_def_file = Path("libc/newhdrgen/tests/input/test_small.h.def")
+        expected_output_file = Path(
+            "libc/newhdrgen/tests/expected_output/test_header.h"
+        )
+        output_file = self.output_dir / "test_small.h"
 
         if not self.output_dir.exists():
             self.output_dir.mkdir(parents=True)
diff --git a/libc/newhdrgen/yaml_to_classes.py b/libc/newhdrgen/yaml_to_classes.py
index e489c7f509b8e..9e0337f4a308e 100644
--- a/libc/newhdrgen/yaml_to_classes.py
+++ b/libc/newhdrgen/yaml_to_classes.py
@@ -101,6 +101,7 @@ def fill_public_api(header_str, h_def_content):
     Returns:
         The final header content with the public API filled in.
     """
+    header_str = header_str.strip()
     return h_def_content.replace("%%public_api()", header_str, 1)
 
 

>From e104bc35f1f423d64cce52d0eba3664a4c234191 Mon Sep 17 00:00:00 2001
From: Aaryan Shukla <aaryanshukla at google.com>
Date: Tue, 2 Jul 2024 20:51:53 +0000
Subject: [PATCH 06/14] fixed formatting

---
 libc/newhdrgen/tests/test_integration.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libc/newhdrgen/tests/test_integration.py b/libc/newhdrgen/tests/test_integration.py
index 1aa7e550520aa..88db65f5d4f61 100644
--- a/libc/newhdrgen/tests/test_integration.py
+++ b/libc/newhdrgen/tests/test_integration.py
@@ -19,7 +19,9 @@ def setUp(self):
         self.output_dir = Path(
             args.output_dir
             if args.output_dir
-            else output_dir_env if output_dir_env else "libc/newhdrgen/tests/output"
+            else output_dir_env 
+            if output_dir_env 
+            else "libc/newhdrgen/tests/output"
         )
 
         self.maxDiff = None

>From 1faa3fa1c3cd40bd09b6fbfa82b4454278390c9b Mon Sep 17 00:00:00 2001
From: Aaryan Shukla <aaryanshukla at google.com>
Date: Tue, 2 Jul 2024 22:40:11 +0000
Subject: [PATCH 07/14] fixed formatting and fixed header.py for format

fixed object class to add ";"
---
 .../classes/enumeration.py                    |  7 +---
 .../class_implementation/classes/function.py  |  4 +-
 .../class_implementation/classes/object.py    |  2 +-
 libc/newhdrgen/header.py                      | 14 +++----
 .../tests/expected_output/test_header.h       |  6 ++-
 libc/newhdrgen/tests/input/test_small.h.def   |  2 +-
 libc/newhdrgen/tests/input/test_small.yaml    |  2 +-
 libc/newhdrgen/tests/output/test_small.h      | 38 +++++++++++++++++++
 libc/newhdrgen/tests/test_integration.py      | 15 +++++---
 9 files changed, 66 insertions(+), 24 deletions(-)
 create mode 100644 libc/newhdrgen/tests/output/test_small.h

diff --git a/libc/newhdrgen/class_implementation/classes/enumeration.py b/libc/newhdrgen/class_implementation/classes/enumeration.py
index be03dbf603c2b..da65e04d836fc 100644
--- a/libc/newhdrgen/class_implementation/classes/enumeration.py
+++ b/libc/newhdrgen/class_implementation/classes/enumeration.py
@@ -10,12 +10,9 @@
 
 
 class Enumeration:
-    def __init__(self, name, value=None):
+    def __init__(self, name, value):
         self.name = name
         self.value = value
 
     def __str__(self):
-        if self.value != None:
-            return f"{self.name} = {self.value}"
-        else:
-            return f"{self.name}"
+        return f"{self.name} = {self.value}"
diff --git a/libc/newhdrgen/class_implementation/classes/function.py b/libc/newhdrgen/class_implementation/classes/function.py
index 3c464e48b6e3b..27219bfd3f611 100644
--- a/libc/newhdrgen/class_implementation/classes/function.py
+++ b/libc/newhdrgen/class_implementation/classes/function.py
@@ -11,14 +11,14 @@
 
 class Function:
     def __init__(
-        self, standards, return_type, name, arguments, guard=None, attributes=[]
+        self, return_type, name, arguments, standards, guard=None, attributes=[]
     ):
-        self.standards = standards
         self.return_type = return_type
         self.name = name
         self.arguments = [
             arg if isinstance(arg, str) else arg["type"] for arg in arguments
         ]
+        self.standards = standards
         self.guard = guard
         self.attributes = attributes or []
 
diff --git a/libc/newhdrgen/class_implementation/classes/object.py b/libc/newhdrgen/class_implementation/classes/object.py
index c65a82e1a660d..02f30cba1c48c 100644
--- a/libc/newhdrgen/class_implementation/classes/object.py
+++ b/libc/newhdrgen/class_implementation/classes/object.py
@@ -15,4 +15,4 @@ def __init__(self, name, type):
         self.type = type
 
     def __str__(self):
-        return f"extern {self.type} {self.name}"
+        return f"extern {self.type} {self.name};"
diff --git a/libc/newhdrgen/header.py b/libc/newhdrgen/header.py
index f12afdc4c9728..4eaf7dccca9e8 100644
--- a/libc/newhdrgen/header.py
+++ b/libc/newhdrgen/header.py
@@ -44,16 +44,16 @@ def __str__(self):
             content.append(str(include))
 
         for macro in self.macros:
-            content.append(str(macro))
+            content.append(f"{macro}\n")
 
         for type_ in self.types:
-            content.append(str(type_))
+            content.append(f"{type_}")
 
         if self.enumerations:
-            content.append("enum {")
-            for enum in self.enumerations:
-                content.append(f"\t{str(enum)},")
-            content.append("};")
+            combined_enum_content = ",\n  ".join(
+                str(enum) for enum in self.enumerations
+            )
+            content.append(f"\nenum {{\n  {combined_enum_content},\n}};")
 
         content.append("\n__BEGIN_C_DECLS\n")
 
@@ -62,6 +62,6 @@ def __str__(self):
             content.append("")
         for object in self.objects:
             content.append(str(object))
-        content.append("__END_C_DECLS")
+        content.append("\n__END_C_DECLS")
 
         return "\n".join(content)
diff --git a/libc/newhdrgen/tests/expected_output/test_header.h b/libc/newhdrgen/tests/expected_output/test_header.h
index 552f93eadf44d..eed6f4cfa2491 100644
--- a/libc/newhdrgen/tests/expected_output/test_header.h
+++ b/libc/newhdrgen/tests/expected_output/test_header.h
@@ -13,6 +13,7 @@
 #include "llvm-libc-macros/test_small-macros.h"
 
 #define MACRO_A 1
+
 #define MACRO_B 2
 
 #include <llvm-libc-types/type_a.h>
@@ -29,8 +30,9 @@ void func_a();
 
 int func_b(int, float);
 
-extern obj object_1 extern obj object_2
+extern obj object_1;
+extern obj object_2;
 
-    __END_C_DECLS
+__END_C_DECLS
 
 #endif // LLVM_LIBC_TEST_SMALL_H
diff --git a/libc/newhdrgen/tests/input/test_small.h.def b/libc/newhdrgen/tests/input/test_small.h.def
index 38f86699840c7..de39a8b7e254d 100644
--- a/libc/newhdrgen/tests/input/test_small.h.def
+++ b/libc/newhdrgen/tests/input/test_small.h.def
@@ -1,4 +1,4 @@
- //===-- C standard library header test_small-------------------------------===//
+//===-- C standard library header test_small-------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
diff --git a/libc/newhdrgen/tests/input/test_small.yaml b/libc/newhdrgen/tests/input/test_small.yaml
index a3cbd2e21327a..719469b5dc30b 100644
--- a/libc/newhdrgen/tests/input/test_small.yaml
+++ b/libc/newhdrgen/tests/input/test_small.yaml
@@ -11,7 +11,7 @@ enums:
   - name: enum_a
     value: value_1
   - name: enum_b
-    value: value_3
+    value: value_2
 objects:
   - object_name: object_1
     object_type: obj
diff --git a/libc/newhdrgen/tests/output/test_small.h b/libc/newhdrgen/tests/output/test_small.h
new file mode 100644
index 0000000000000..eed6f4cfa2491
--- /dev/null
+++ b/libc/newhdrgen/tests/output/test_small.h
@@ -0,0 +1,38 @@
+//===-- C standard library header test_small-------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TEST_SMALL_H
+#define LLVM_LIBC_TEST_SMALL_H
+
+#include "__llvm-libc-common.h"
+#include "llvm-libc-macros/test_small-macros.h"
+
+#define MACRO_A 1
+
+#define MACRO_B 2
+
+#include <llvm-libc-types/type_a.h>
+#include <llvm-libc-types/type_b.h>
+
+enum {
+  enum_a = value_1,
+  enum_b = value_2,
+};
+
+__BEGIN_C_DECLS
+
+void func_a();
+
+int func_b(int, float);
+
+extern obj object_1;
+extern obj object_2;
+
+__END_C_DECLS
+
+#endif // LLVM_LIBC_TEST_SMALL_H
diff --git a/libc/newhdrgen/tests/test_integration.py b/libc/newhdrgen/tests/test_integration.py
index 88db65f5d4f61..27470d9635979 100644
--- a/libc/newhdrgen/tests/test_integration.py
+++ b/libc/newhdrgen/tests/test_integration.py
@@ -19,9 +19,7 @@ def setUp(self):
         self.output_dir = Path(
             args.output_dir
             if args.output_dir
-            else output_dir_env 
-            if output_dir_env 
-            else "libc/newhdrgen/tests/output"
+            else output_dir_env if output_dir_env else "libc/newhdrgen/tests/output"
         )
 
         self.maxDiff = None
@@ -50,7 +48,11 @@ def compare_files(self, generated_file, expected_file):
         with expected_file.open("r") as exp_file:
             exp_content = exp_file.read()
 
-        self.assertEqual(gen_content, exp_content)
+        self.assertEqual(
+            gen_content,
+            exp_content,
+            f"Generated file {generated_file} does not match expected file {expected_file}",
+        )
 
     def test_generate_header(self):
         yaml_file = Path("libc/newhdrgen/tests/input/test_small.yaml")
@@ -63,7 +65,10 @@ def test_generate_header(self):
         if not self.output_dir.exists():
             self.output_dir.mkdir(parents=True)
 
-        self.run_script(yaml_file, h_def_file, self.output_dir)
+        try:
+            self.run_script(yaml_file, h_def_file, self.output_dir)
+        except subprocess.CalledProcessError as e:
+            self.fail(f"Subprocess failed with return code {e.returncode}")
 
         self.compare_files(output_file, expected_output_file)
 

>From 900e8914721bda2e0fa2806217812d27480175d2 Mon Sep 17 00:00:00 2001
From: Aaryan Shukla <aaryanshukla at google.com>
Date: Tue, 2 Jul 2024 23:46:28 +0000
Subject: [PATCH 08/14] added CMakeLists.txt for testing

ninja check-hdrgen works
---
 libc/CMakeLists.txt                      |  1 +
 libc/newhdrgen/CMakeLists.txt            | 19 +++++++++++++++
 libc/newhdrgen/tests/test_integration.py | 30 ++++++++++--------------
 3 files changed, 32 insertions(+), 18 deletions(-)
 create mode 100644 libc/newhdrgen/CMakeLists.txt

diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt
index 4ffcd55ba9500..fd61d2917eea2 100644
--- a/libc/CMakeLists.txt
+++ b/libc/CMakeLists.txt
@@ -385,6 +385,7 @@ add_subdirectory(config)
 add_subdirectory(hdr)
 add_subdirectory(src)
 add_subdirectory(utils)
+add_subdirectory(newhdrgen)
 
 if(LLVM_LIBC_FULL_BUILD)
   # The startup system can potentially depend on the library components so add
diff --git a/libc/newhdrgen/CMakeLists.txt b/libc/newhdrgen/CMakeLists.txt
new file mode 100644
index 0000000000000..159c430d2ff43
--- /dev/null
+++ b/libc/newhdrgen/CMakeLists.txt
@@ -0,0 +1,19 @@
+project(newhdrgen LANGUAGES CXX)
+
+enable_testing()
+
+set(NEWHDGEN_TESTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/tests)
+
+add_test(
+  NAME newhdrgen_integration_test
+  COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${CMAKE_CURRENT_SOURCE_DIR} python3 ${NEWHDGEN_TESTS_DIR}/test_integration.py
+)
+
+file(COPY ${NEWHDGEN_TESTS_DIR}/input DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tests)
+file(COPY ${NEWHDGEN_TESTS_DIR}/expected_output DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tests)
+
+add_custom_target(check-newhdrgen
+  COMMAND ${CMAKE_CTEST_COMMAND} -R newhdrgen_integration_test
+)
+#will remove once configuration done
+message(STATUS "Integration test for newhdrgen added.")
diff --git a/libc/newhdrgen/tests/test_integration.py b/libc/newhdrgen/tests/test_integration.py
index 27470d9635979..350acb5d625ea 100644
--- a/libc/newhdrgen/tests/test_integration.py
+++ b/libc/newhdrgen/tests/test_integration.py
@@ -4,7 +4,6 @@
 import os
 import argparse
 
-
 class TestHeaderGenIntegration(unittest.TestCase):
     def setUp(self):
         parser = argparse.ArgumentParser(
@@ -19,16 +18,21 @@ def setUp(self):
         self.output_dir = Path(
             args.output_dir
             if args.output_dir
-            else output_dir_env if output_dir_env else "libc/newhdrgen/tests/output"
+            else output_dir_env 
+            if output_dir_env 
+            else "libc/newhdrgen/tests/output"
         )
 
         self.maxDiff = None
+        self.source_dir = Path(__file__).resolve().parent.parent.parent.parent  # Adjust based on your directory structure
 
     def run_script(self, yaml_file, h_def_file, output_dir):
+        yaml_file = self.source_dir / yaml_file
+        h_def_file = self.source_dir / h_def_file
         result = subprocess.run(
             [
                 "python3",
-                "libc/newhdrgen/yaml_to_classes.py",
+                str(self.source_dir / "libc/newhdrgen/yaml_to_classes.py"),
                 str(yaml_file),
                 str(h_def_file),
                 "--output_dir",
@@ -48,30 +52,20 @@ def compare_files(self, generated_file, expected_file):
         with expected_file.open("r") as exp_file:
             exp_content = exp_file.read()
 
-        self.assertEqual(
-            gen_content,
-            exp_content,
-            f"Generated file {generated_file} does not match expected file {expected_file}",
-        )
+        self.assertEqual(gen_content, exp_content)
 
     def test_generate_header(self):
-        yaml_file = Path("libc/newhdrgen/tests/input/test_small.yaml")
-        h_def_file = Path("libc/newhdrgen/tests/input/test_small.h.def")
-        expected_output_file = Path(
-            "libc/newhdrgen/tests/expected_output/test_header.h"
-        )
+        yaml_file = "libc/newhdrgen/tests/input/test_small.yaml"
+        h_def_file = "libc/newhdrgen/tests/input/test_small.h.def"
+        expected_output_file = self.source_dir / "libc/newhdrgen/tests/expected_output/test_header.h"
         output_file = self.output_dir / "test_small.h"
 
         if not self.output_dir.exists():
             self.output_dir.mkdir(parents=True)
 
-        try:
-            self.run_script(yaml_file, h_def_file, self.output_dir)
-        except subprocess.CalledProcessError as e:
-            self.fail(f"Subprocess failed with return code {e.returncode}")
+        self.run_script(yaml_file, h_def_file, self.output_dir)
 
         self.compare_files(output_file, expected_output_file)
 
-
 if __name__ == "__main__":
     unittest.main()

>From c3cd6ffc93fdfca1b57a5447ce39d13668632a96 Mon Sep 17 00:00:00 2001
From: Aaryan Shukla <aaryanshukla at google.com>
Date: Tue, 2 Jul 2024 23:49:18 +0000
Subject: [PATCH 09/14] black formatting and changed comment area

---
 libc/newhdrgen/tests/test_integration.py | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/libc/newhdrgen/tests/test_integration.py b/libc/newhdrgen/tests/test_integration.py
index 350acb5d625ea..228fecc7f41c0 100644
--- a/libc/newhdrgen/tests/test_integration.py
+++ b/libc/newhdrgen/tests/test_integration.py
@@ -4,6 +4,7 @@
 import os
 import argparse
 
+
 class TestHeaderGenIntegration(unittest.TestCase):
     def setUp(self):
         parser = argparse.ArgumentParser(
@@ -18,13 +19,12 @@ def setUp(self):
         self.output_dir = Path(
             args.output_dir
             if args.output_dir
-            else output_dir_env 
-            if output_dir_env 
-            else "libc/newhdrgen/tests/output"
+            else output_dir_env if output_dir_env else "libc/newhdrgen/tests/output"
         )
 
         self.maxDiff = None
-        self.source_dir = Path(__file__).resolve().parent.parent.parent.parent  # Adjust based on your directory structure
+        # Adjust based on your directory structure such as being in build etc.
+        self.source_dir = Path(__file__).resolve().parent.parent.parent.parent
 
     def run_script(self, yaml_file, h_def_file, output_dir):
         yaml_file = self.source_dir / yaml_file
@@ -57,7 +57,9 @@ def compare_files(self, generated_file, expected_file):
     def test_generate_header(self):
         yaml_file = "libc/newhdrgen/tests/input/test_small.yaml"
         h_def_file = "libc/newhdrgen/tests/input/test_small.h.def"
-        expected_output_file = self.source_dir / "libc/newhdrgen/tests/expected_output/test_header.h"
+        expected_output_file = (
+            self.source_dir / "libc/newhdrgen/tests/expected_output/test_header.h"
+        )
         output_file = self.output_dir / "test_small.h"
 
         if not self.output_dir.exists():
@@ -67,5 +69,6 @@ def test_generate_header(self):
 
         self.compare_files(output_file, expected_output_file)
 
+
 if __name__ == "__main__":
     unittest.main()

>From 0876dbba38e302aae6ae3e6c4d23d6bd6f94ab1f Mon Sep 17 00:00:00 2001
From: Aaryan Shukla <aaryanshukla at google.com>
Date: Wed, 3 Jul 2024 16:23:25 +0000
Subject: [PATCH 10/14] fixed cmakelists

---
 libc/CMakeLists.txt           | 5 ++++-
 libc/newhdrgen/CMakeLists.txt | 7 -------
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt
index fd61d2917eea2..933133a1639de 100644
--- a/libc/CMakeLists.txt
+++ b/libc/CMakeLists.txt
@@ -48,6 +48,10 @@ set(LIBC_NAMESPACE ${default_namespace}
   CACHE STRING "The namespace to use to enclose internal implementations. Must start with '__llvm_libc'."
 )
 
+if(LLVM_LIBC_FULL_BUILD)
+  add_subdirectory(newhdrgen)
+endif()
+
 if(LLVM_LIBC_FULL_BUILD OR LLVM_LIBC_GPU_BUILD)
   if(NOT LIBC_HDRGEN_EXE)
     # We need to set up hdrgen first since other targets depend on it.
@@ -385,7 +389,6 @@ add_subdirectory(config)
 add_subdirectory(hdr)
 add_subdirectory(src)
 add_subdirectory(utils)
-add_subdirectory(newhdrgen)
 
 if(LLVM_LIBC_FULL_BUILD)
   # The startup system can potentially depend on the library components so add
diff --git a/libc/newhdrgen/CMakeLists.txt b/libc/newhdrgen/CMakeLists.txt
index 159c430d2ff43..9be63b68c2e25 100644
--- a/libc/newhdrgen/CMakeLists.txt
+++ b/libc/newhdrgen/CMakeLists.txt
@@ -1,7 +1,3 @@
-project(newhdrgen LANGUAGES CXX)
-
-enable_testing()
-
 set(NEWHDGEN_TESTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/tests)
 
 add_test(
@@ -9,9 +5,6 @@ add_test(
   COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${CMAKE_CURRENT_SOURCE_DIR} python3 ${NEWHDGEN_TESTS_DIR}/test_integration.py
 )
 
-file(COPY ${NEWHDGEN_TESTS_DIR}/input DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tests)
-file(COPY ${NEWHDGEN_TESTS_DIR}/expected_output DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tests)
-
 add_custom_target(check-newhdrgen
   COMMAND ${CMAKE_CTEST_COMMAND} -R newhdrgen_integration_test
 )

>From 45975aaae1aec3ac7ef7321c6b0ebac691fef41c Mon Sep 17 00:00:00 2001
From: Aaryan Shukla <aaryanshukla at google.com>
Date: Wed, 3 Jul 2024 17:14:08 +0000
Subject: [PATCH 11/14] added full-build mode for newhdrgen

---
 libc/newhdrgen/CMakeLists.txt            | 32 ++++++++++++--------
 libc/newhdrgen/tests/output/test_small.h | 38 ------------------------
 2 files changed, 20 insertions(+), 50 deletions(-)
 delete mode 100644 libc/newhdrgen/tests/output/test_small.h

diff --git a/libc/newhdrgen/CMakeLists.txt b/libc/newhdrgen/CMakeLists.txt
index 9be63b68c2e25..66f1605bc6edf 100644
--- a/libc/newhdrgen/CMakeLists.txt
+++ b/libc/newhdrgen/CMakeLists.txt
@@ -1,12 +1,20 @@
-set(NEWHDGEN_TESTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/tests)
-
-add_test(
-  NAME newhdrgen_integration_test
-  COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${CMAKE_CURRENT_SOURCE_DIR} python3 ${NEWHDGEN_TESTS_DIR}/test_integration.py
-)
-
-add_custom_target(check-newhdrgen
-  COMMAND ${CMAKE_CTEST_COMMAND} -R newhdrgen_integration_test
-)
-#will remove once configuration done
-message(STATUS "Integration test for newhdrgen added.")
+if(LLVM_LIBC_FULL_BUILD)
+
+  enable_testing()
+
+  set(NEWHDGEN_TESTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/tests)
+
+  add_test(
+    NAME newhdrgen_integration_test
+    COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${CMAKE_CURRENT_SOURCE_DIR} python3 ${NEWHDGEN_TESTS_DIR}/test_integration.py
+  )
+
+  file(COPY ${NEWHDGEN_TESTS_DIR}/input DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tests)
+  file(COPY ${NEWHDGEN_TESTS_DIR}/expected_output DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/tests)
+
+  add_custom_target(check-newhdrgen
+    COMMAND ${CMAKE_CTEST_COMMAND} -R newhdrgen_integration_test
+  )
+
+  message(STATUS "Integration test for newhdrgen added.")
+endif()
diff --git a/libc/newhdrgen/tests/output/test_small.h b/libc/newhdrgen/tests/output/test_small.h
deleted file mode 100644
index eed6f4cfa2491..0000000000000
--- a/libc/newhdrgen/tests/output/test_small.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//===-- C standard library header test_small-------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIBC_TEST_SMALL_H
-#define LLVM_LIBC_TEST_SMALL_H
-
-#include "__llvm-libc-common.h"
-#include "llvm-libc-macros/test_small-macros.h"
-
-#define MACRO_A 1
-
-#define MACRO_B 2
-
-#include <llvm-libc-types/type_a.h>
-#include <llvm-libc-types/type_b.h>
-
-enum {
-  enum_a = value_1,
-  enum_b = value_2,
-};
-
-__BEGIN_C_DECLS
-
-void func_a();
-
-int func_b(int, float);
-
-extern obj object_1;
-extern obj object_2;
-
-__END_C_DECLS
-
-#endif // LLVM_LIBC_TEST_SMALL_H

>From 6d89c0c47ba9cfde69cb5c2bc59029fe5acee193 Mon Sep 17 00:00:00 2001
From: Aaryan Shukla <aaryanshukla at google.com>
Date: Wed, 3 Jul 2024 17:23:04 +0000
Subject: [PATCH 12/14] deleted change in enumeration.py

---
 libc/newhdrgen/class_implementation/classes/enumeration.py | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/libc/newhdrgen/class_implementation/classes/enumeration.py b/libc/newhdrgen/class_implementation/classes/enumeration.py
index da65e04d836fc..a01fa74210101 100644
--- a/libc/newhdrgen/class_implementation/classes/enumeration.py
+++ b/libc/newhdrgen/class_implementation/classes/enumeration.py
@@ -15,4 +15,7 @@ def __init__(self, name, value):
         self.value = value
 
     def __str__(self):
-        return f"{self.name} = {self.value}"
+        if self.value != None:
+            return f"{self.name} = {self.value}"
+        else:
+            return f"{self.name}"

>From 231874ed6be798710eb5a88a336ed5ee14fa3186 Mon Sep 17 00:00:00 2001
From: Aaryan Shukla <aaryanshukla at google.com>
Date: Wed, 3 Jul 2024 17:33:50 +0000
Subject: [PATCH 13/14] fixed spacing for header.py

---
 libc/newhdrgen/header.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/newhdrgen/header.py b/libc/newhdrgen/header.py
index 4eaf7dccca9e8..d9e9c68dfc5f4 100644
--- a/libc/newhdrgen/header.py
+++ b/libc/newhdrgen/header.py
@@ -62,6 +62,6 @@ def __str__(self):
             content.append("")
         for object in self.objects:
             content.append(str(object))
-        content.append("\n__END_C_DECLS")
+        content.append("__END_C_DECLS")
 
         return "\n".join(content)

>From d65081e440880940cbb420e58973d64475d1d860 Mon Sep 17 00:00:00 2001
From: Aaryan Shukla <aaryanshukla at google.com>
Date: Wed, 3 Jul 2024 18:04:21 +0000
Subject: [PATCH 14/14] fixed header.py for spacing

---
 libc/newhdrgen/header.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/newhdrgen/header.py b/libc/newhdrgen/header.py
index d9e9c68dfc5f4..4eaf7dccca9e8 100644
--- a/libc/newhdrgen/header.py
+++ b/libc/newhdrgen/header.py
@@ -62,6 +62,6 @@ def __str__(self):
             content.append("")
         for object in self.objects:
             content.append(str(object))
-        content.append("__END_C_DECLS")
+        content.append("\n__END_C_DECLS")
 
         return "\n".join(content)



More information about the libc-commits mailing list