From efd4b95fab1be1a6c58d4a8379dde24bc516c58d Mon Sep 17 00:00:00 2001 From: Aaryan Shukla Date: Mon, 1 Jul 2024 22:55:42 +0000 Subject: [PATCH] [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 00000000000000..4dcb693c353e46 --- /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 + +__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 00000000000000..1bd2687db2beac --- /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 00000000000000..2754f856bc8077 --- /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 00000000000000..ca485dc0377c1d --- /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 9b52c9cf9bb7c7..65a990c8a87678 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"],