Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • card10/firmware
  • annejan/firmware
  • astro/firmware
  • fpletz/firmware
  • gerd/firmware
  • fleur/firmware
  • swym/firmware
  • l/firmware
  • uberardy/firmware
  • wink/firmware
  • madonius/firmware
  • mot/firmware
  • filid/firmware
  • q3k/firmware
  • hauke/firmware
  • Woazboat/firmware
  • pink/firmware
  • mossmann/firmware
  • omniskop/firmware
  • zenox/firmware
  • trilader/firmware
  • Danukeru/firmware
  • shoragan/firmware
  • zlatko/firmware
  • sistason/firmware
  • datenwolf/firmware
  • bene/firmware
  • amedee/firmware
  • martinling/firmware
  • griffon/firmware
  • chris007/firmware
  • adisbladis/firmware
  • dbrgn/firmware
  • jelly/firmware
  • rnestler/firmware
  • mh/firmware
  • ln/firmware
  • penguineer/firmware
  • monkeydom/firmware
  • jens/firmware
  • jnaulty/firmware
  • jeffmakes/firmware
  • marekventur/firmware
  • pete/firmware
  • h2obrain/firmware
  • DooMMasteR/firmware
  • jackie/firmware
  • prof_r/firmware
  • Draradech/firmware
  • Kartoffel/firmware
  • hinerk/firmware
  • abbradar/firmware
  • JustTB/firmware
  • LuKaRo/firmware
  • iggy/firmware
  • ente/firmware
  • flgr/firmware
  • Lorphos/firmware
  • matejo/firmware
  • ceddral7/firmware
  • danb/firmware
  • joshi/firmware
  • melle/firmware
  • fitch/firmware
  • deurknop/firmware
  • sargon/firmware
  • markus/firmware
  • kloenk/firmware
  • lucaswerkmeister/firmware
  • derf/firmware
  • meh/firmware
  • dx/card10-firmware
  • torben/firmware
  • yuvadm/firmware
  • AndyBS/firmware
  • klausdieter1/firmware
  • katzenparadoxon/firmware
  • xiretza/firmware
  • ole/firmware
  • techy/firmware
  • thor77/firmware
  • TilCreator/firmware
  • fuchsi/firmware
  • dos/firmware
  • yrlf/firmware
  • PetePriority/firmware
  • SuperVirus/firmware
  • sur5r/firmware
  • tazz/firmware
  • Alienmaster/firmware
  • flo_h/firmware
  • baldo/firmware
  • mmu_man/firmware
  • Foaly/firmware
  • sodoku/firmware
  • Guinness/firmware
  • ssp/firmware
  • led02/firmware
  • Stormwind/firmware
  • arist/firmware
  • coon/firmware
  • mdik/firmware
  • pippin/firmware
  • royrobotiks/firmware
  • zigot83/firmware
  • mo_k/firmware
106 results
Select Git revision
Show changes
Commits on Source (1)
......@@ -4,33 +4,76 @@ import os
import re
import subprocess
api_src_fmt = """\
#define API(id, def) __GENERATE_API $ __GEN_ID_##id $ def $
#include "{header}"
"""
def main():
parser = argparse.ArgumentParser(
description="Generate the API stubs from a header file."
)
parser.add_argument(
"-H", "--header", required=True, help="The header to base the definitions on."
)
parser.add_argument(
"-c", "--client", required=True, help="The output client-side c source file."
)
parser.add_argument(
"-s", "--server", required=True, help="The output server-side c source file."
"""Generated Client file"""
api_func_start_fmt = """\
/* Autogenerated stub for {id} */
void {cdecl}({cargs})
{{
const int size = {total_size};
void*buffer;
buffer = api_call_start({id}, size);
/* TODO: Check if buffer is no NULL */
"""
serialise_arg_fmt = """ *({type}*)(buffer + {offset}) = {arg};"""
bother_dispatcher_fmt = """
printf("Sending call {id}\\nBUF: ");
for (int i = 0; i < size; i++) {{
printf("0x%02x ", ((char*)buffer)[i]);
}}
printf("\\n");
api_call_bother_dispatcher(buffer);
}}
"""
"""Generated Service file"""
api_dispatch_call_start = """\
void __api_dispatch_call(uint32_t id, void*buffer)
{
switch (id) {"""
dispatch_case_fmt = """\
case {id}:
{cdecl}("""
deserialise_arg_fmt = """\
*({type}*)(buffer + {offset})"""
insert_switch_case_break_str = """
);
break;"""
switch_add_default_fmt = """\
default:
printf("Error: API function %x is unknown!!\\n", {id});
break;
}}
}}"""
def api_func_iter (header:str):
# Parse the header for API definitions
matcher = re.compile(
r"__GENERATE_API \$ __GEN_ID_(?P<id>\w+) \$ void (?P<decl>.+?)\((?P<args>.*?)\) \$",
re.DOTALL | re.MULTILINE,
)
args = parser.parse_args()
with contextlib.ExitStack() as cx:
# Run the preprocessor on the header file to get the API definitions.
#
# For this, we first need a source to include the header which contains
# an alternative definition of the `API` macro that marks definitions in
# a way we can find later on.
api_src = """\
#define API(id, def) __GENERATE_API $ __GEN_ID_##id $ def $
#include "{header}"
""".format(
header=os.path.relpath(args.header)
api_src = api_src_fmt.format(
header=os.path.relpath(header)
)
# Evaluate the preprocessor
......@@ -38,130 +81,133 @@ def main():
["gcc", "-E", "-"], input=api_src.encode()
).decode()
# Parse the header for API definitions
matcher = re.compile(
r"__GENERATE_API \$ __GEN_ID_(?P<id>\w+) \$ void (?P<decl>.+?)\((?P<args>.*?)\) \$",
re.DOTALL | re.MULTILINE,
)
args_matcher = re.compile(r"(?P<type>\w+(?:\*+|\s+))(?P<name>\w+),")
return matcher.finditer(source)
# Open output files
f_client = cx.enter_context(open(args.client, "w"))
f_server = cx.enter_context(open(args.server, "w"))
def include_header (header:str, file):
print('#include "{}"\n'.format(
os.path.basename(args.header)
), file=f_client)
os.path.basename(header)
), file=file)
print("""\
#include "{}"
void __api_dispatch_call(uint32_t id, void*buffer)
{{
switch (id) {{""".format(
os.path.basename(args.header)
), file=f_server)
for match in matcher.finditer(source):
api_id = match.group("id")
api_decl = match.group("decl")
api_args = match.group("args")
def destructure_args (api_args:str):
api_args_names = []
api_args_types = []
api_args_sizes = []
args_matcher = re.compile(r"(?P<type>\w+(?:\*+|\s+))(?P<name>\w+),")
# Destructure args
for match in args_matcher.finditer(api_args + ","):
arg_type = match.group("type").strip()
arg_name = match.group("name")
for arg in args_matcher.finditer(api_args + ","):
arg_type = arg.group("type").strip()
arg_name = arg.group("name")
api_args_names.append(arg_name)
api_args_types.append(arg_type)
api_args_sizes.append("sizeof({})".format(arg_type))
print(
"""\
/* Autogenerated stub for {id} */
void {cdecl}({cargs})
{{
const int size = {total_size};
void*buffer;
buffer = api_call_start({id}, size);
/* TODO: Check if buffer is no NULL */
""".format(
id=api_id,
cdecl=api_decl,
cargs=api_args,
total_size=" + ".join(api_args_sizes),
),
file=f_client,
)
return (api_args_names, api_args_types, api_args_sizes)
print("""\
case {id}:
{cdecl}(""".format(id=api_id, cdecl=api_decl),
file=f_server,
)
for i, (arg, ty) in enumerate(zip(api_args_names, api_args_types)):
def serialise_arg (ty:str, api_args_sizes:list, arg_idx:int, arg:str, file):
print(
""" *({type}*)(buffer + {offset}) = {arg};""".format(
serialise_arg_fmt.format(
type=ty,
offset=" + ".join(api_args_sizes[:i]) if i > 0 else "0",
offset=" + ".join(api_args_sizes[:arg_idx]) if arg_idx > 0 else "0",
arg=arg,
),
file=f_client,
file=file,
)
if i != 0:
print(",", file=f_server)
def deserialise_arg (ty:str, api_args_sizes:list, arg_idx:int, file):
if arg_idx != 0:
print(",", file=file)
print(
"""\
*({type}*)(buffer + {offset})""".format(
deserialise_arg_fmt.format(
type=ty,
offset=" + ".join(api_args_sizes[:i]) if i > 0 else "0",
offset=" + ".join(api_args_sizes[:arg_idx]) if arg_idx > 0 else "0",
),
file=f_server,
file=file,
end="",
)
print("""
);
break;""".format(
cdecl=api_decl,
args=", ".join(api_args_names),
),
file=f_server,
def insert_switch_case_break (file):
print(insert_switch_case_break_str,
file=file,
)
print(
"""
printf("Sending call {id}\\nBUF: ");
for (int i = 0; i < size; i++) {{
printf("0x%02x ", ((char*)buffer)[i]);
}}
printf("\\n");
api_call_bother_dispatcher(buffer);
}}
""".format(
def bother_dispatcher (api_id:str, file):
print(bother_dispatcher_fmt.format(
id=api_id
),
file=f_client,
file=file,
)
print("""\
default:
printf("Error: API function %x is unknown!!\\n", {id});
break;
}}
}}""".format(
def switch_add_default (api_id:str, file):
print(switch_add_default_fmt.format(
id=api_id,
), file=f_server)
), file=file)
def main():
parser = argparse.ArgumentParser(
description="Generate the API stubs from a header file."
)
parser.add_argument(
"-H", "--header", required=True, help="The header to base the definitions on."
)
parser.add_argument(
"-c", "--client", required=True, help="The output client-side c source file."
)
parser.add_argument(
"-s", "--server", required=True, help="The output server-side c source file."
)
args = parser.parse_args()
# Open output files
cx = contextlib.ExitStack()
f_client = cx.enter_context(open(args.client, "w"))
f_server = cx.enter_context(open(args.server, "w"))
include_header (args.header, f_client)
include_header (args.header, f_server)
print(api_dispatch_call_start, file=f_server)
for api_func in api_func_iter (args.header):
api_id = api_func.group("id")
api_decl = api_func.group("decl")
api_args = api_func.group("args")
(api_args_names, api_args_types, api_args_sizes) = \
destructure_args (api_args)
print(api_func_start_fmt.format(
id=api_id,
cdecl=api_decl,
cargs=api_args,
total_size=" + ".join(api_args_sizes),
),
file=f_client,
)
print(dispatch_case_fmt.format(id=api_id, cdecl=api_decl),
file=f_server,
)
for i, (arg, ty) in enumerate(zip(api_args_names, api_args_types)):
serialise_arg (ty, api_args_sizes, i, arg, f_client)
deserialise_arg (ty, api_args_sizes, i, f_server)
insert_switch_case_break (f_server)
bother_dispatcher (api_id, f_client)
switch_add_default (api_id, f_server)
if __name__ == "__main__":
......