[core] Split lt_api.c into separate units

This commit is contained in:
Kuba Szczodrzyński
2023-06-22 18:30:14 +02:00
parent b38a4d5d46
commit e38e53bac0
45 changed files with 947 additions and 865 deletions

13
docs/contrib/lt-api.md Normal file
View File

@@ -0,0 +1,13 @@
# API functions guide
The [LibreTiny C API](../dev/lt-api.md) functions are split between three types: common, weak and family.
- Common functions are implemented in the base, common core and are the same between all families.
- Weak functions are provided in the common core, but can (and sometimes should) be overridden by family cores. They sometimes provide usable default implementations (which *can* be overriden to provide e.g. a better way to do something), otherwise they're empty (e.g. if a family doesn't support such a feature).
- Family functions are not provided in the common core and have to be implemented in the family core.
A quick outline of all available functions and their types:
{%
include-markdown "lt-api-functions.md"
%}

View File

@@ -31,6 +31,7 @@ Here's what has to be done to make that work:
5. Add base core code.
- `lt_defs.h`, `lt_family.h` and `lt_api.c` files need to be created, and initialized with (even empty) functions and definitions.
- The list of family functions can be found [here](lt-api.md).
- Make the SDK call `lt_main()` as the entrypoint. If needed, use fixups.
6. Write a binary manipulation tool.

6
docs/script.js Normal file
View File

@@ -0,0 +1,6 @@
document$.subscribe(function () {
var tables = document.querySelectorAll("article table:not([class])")
tables.forEach(function (table) {
new Tablesort(table)
})
})

View File

@@ -1,7 +1,7 @@
import json
from ltchiptool import Board
from update_docs import board_obj_sort
from write_boards import board_obj_sort
boards = map(Board, Board.get_list())
boards = list(sorted(boards, key=board_obj_sort))

125
docs/scripts/write_apis.py Normal file
View File

@@ -0,0 +1,125 @@
# Copyright (c) Kuba Szczodrzyński 2023-06-22.
import re
from glob import glob
from os.path import dirname, join
import colorama
from colorama import Fore, Style
from markdown import Markdown
if __name__ == "__main__":
colorama.init()
api_path = join(dirname(__file__), "..", "..", "cores/common/base/api/lt_*.*")
out_path = join(dirname(__file__), "..", "contrib")
declaration = ""
implementation = ""
for file in glob(api_path):
with open(file, "r") as f:
data = f.read()
if file.endswith(".h"):
declaration += data
elif file.endswith(".c"):
implementation += data
block_comment_regex = r"\/\*[\d\D]+?\*\/"
line_comment_regex = r"\/\/.+?$"
macro_regex = r"#(?:[^\n\\]|\\\n)+$"
line_regex = r"\n+"
declaration = re.sub(block_comment_regex, "", declaration)
declaration = re.sub(line_comment_regex, "", declaration, flags=re.MULTILINE)
declaration = re.sub(macro_regex, "", declaration, flags=re.MULTILINE)
declaration = re.sub(line_regex, "\n", declaration)
implementation = re.sub(block_comment_regex, "", implementation)
implementation = re.sub(line_comment_regex, "", implementation, flags=re.MULTILINE)
implementation = re.sub(macro_regex, "", implementation, flags=re.MULTILINE)
implementation = re.sub(line_regex, "\n", implementation)
declaration_regex = r"^([\d\w\s]+ \*?)([\S]+?)\(.*?\);$"
implementation_regex = r"^(__attribute__\(\(weak\)\) )?([\w\d* ]+?)([\w\d]+)\(.+?{"
function_types = {}
decl_functions = set()
impl_functions = set()
weak_functions = set()
for match in re.finditer(
pattern=declaration_regex,
string=declaration,
flags=re.DOTALL | re.MULTILINE,
):
function_type = match[1].strip()
function_name = match[2].strip()
if function_types.get(function_name, function_type) != function_type:
print(
Fore.YELLOW
+ "WARNING: Wrong return type: "
+ f"'{function_types[function_name]} {function_name}'"
+ f"vs '{function_type} {function_name}'"
+ Style.RESET_ALL
)
function_types[function_name] = function_type
decl_functions.add(function_name)
for match in re.finditer(
pattern=implementation_regex,
string=implementation,
flags=re.DOTALL | re.MULTILINE,
):
is_weak = match[1]
function_type = match[2].strip()
function_name = match[3].strip()
function_types[function_name] = function_type
if function_types.get(function_name, function_type) != function_type:
print(
Fore.YELLOW
+ "WARNING: Wrong return type: "
+ f"'{function_types[function_name]} {function_name}'"
+ f"vs '{function_type} {function_name}'"
+ Style.RESET_ALL
)
if is_weak:
weak_functions.add(function_name)
else:
impl_functions.add(function_name)
common_functions = impl_functions.union(weak_functions)
family_functions = decl_functions - common_functions
undecl_functions = common_functions - decl_functions
if undecl_functions:
print(Fore.RED + "ERROR: Undeclared functions: " + ", ".join(undecl_functions))
exit(1)
md = Markdown(out_path, "lt-api-functions")
header = [
"Type",
"Function",
"Common",
"Weak",
"Family",
]
rows = []
for function in (
sorted(family_functions) + sorted(weak_functions) + sorted(impl_functions)
):
rows.append(
[
f"`{function_types[function]}`",
f"{function}()",
"✔️" if function in impl_functions else "",
"✔️" if function in weak_functions else "",
"✔️" if function not in common_functions else "",
]
)
md.add_table(header, *rows)
md.write()