diff --git a/libsel4/tools/syscall_stub_gen.py b/libsel4/tools/syscall_stub_gen.py index 227a4ede1..1d629b6c3 100644 --- a/libsel4/tools/syscall_stub_gen.py +++ b/libsel4/tools/syscall_stub_gen.py @@ -820,8 +820,8 @@ def parse_xml_file(input_file, valid_types): # Prefix the label with an api-wide label prefix method_manual_label = "%s%s" % (api.label_prefix, method_manual_label) - comment_lines = ["@xmlonly @endxmlonly" % - (interface_manual_name, method_manual_name, method_manual_label)] + comment_lines = ["@xmlonly @endxmlonly" % + (method_manual_name, method_manual_label)] method_brief = method.getElementsByTagName("brief") if method_brief: diff --git a/manual/tools/gen_invocations.py b/manual/tools/gen_invocations.py index 54324de63..162df778d 100755 --- a/manual/tools/gen_invocations.py +++ b/manual/tools/gen_invocations.py @@ -68,9 +68,27 @@ def gen_invocations(input_files, output_file): for input_file in input_files: methods, _, api = syscall_stub_gen.parse_xml_file(input_file, types) prototypes = [] - for (interface_name, method_name, method_id, inputs, outputs, _, comment) in methods: - prototype = generate_prototype(interface_name, method_name, method_id, inputs, outputs, comment) - prototypes.append(prototype) + + # figure out the prefix to use for an interface group id. This makes groups per arch, + # sel4_arch unique even through the interface name is the same. + prefix = None + if "arch_include" in input_file: + # extract the 2nd last path member + (path, tail) = os.path.split(os.path.dirname(input_file)) + assert tail == "interfaces" + (path, prefix) = os.path.split(path) + + # group the methods in each interface + for interface_name, methods in itertools.groupby(methods, lambda x: x[0]): + group_id = interface_name if prefix is None else prefix + '_' + interface_name + group_name = interface_name + output_file.write("/**\n * @defgroup %s %s\n * @{{\n */\n\n" % (group_id, group_name)) + output_file.write("/** @} */\n") + for (interface_name, method_name, method_id, inputs, outputs, _, comment) in methods: + prototype = "/**\n * @addtogroup %s %s\n * @{{\n */\n\n" % (group_id, group_name) + prototype += generate_prototype(interface_name, method_name, method_id, inputs, outputs, comment) + prototype += "/** @} */\n" + prototypes.append(prototype) prototypes.sort() diff --git a/manual/tools/parse_doxygen_xml.py b/manual/tools/parse_doxygen_xml.py index 6050f2abf..7ab7781e1 100755 --- a/manual/tools/parse_doxygen_xml.py +++ b/manual/tools/parse_doxygen_xml.py @@ -345,6 +345,9 @@ class LatexGenerator(Generator): else: return 'paragraph' + def level_to_heading(self, level, name): + return '\\' + self.level_to_header(level) + '{' + self.text_escape(name) + '}' + class MarkdownGenerator(Generator): """ A class that represents the generator for Doxygen to Markdown. A child of the Generator class @@ -489,6 +492,9 @@ Type | Name | Description def level_to_header(self, level): return (level + 1) * '#' + def level_to_heading(self, level, name): + return self.level_to_header(level) + ' ' + self.text_escape(name) + def generate_general_syscall_doc(generator, input_file_name, level): """ Takes a path to a file containing doxygen-generated xml, @@ -496,6 +502,7 @@ def generate_general_syscall_doc(generator, input_file_name, level): in the sel4 manual. """ + dir_name = os.path.dirname(input_file_name) with open(input_file_name, "r") as f: output = "" soup = BeautifulSoup(f, "lxml") @@ -507,8 +514,15 @@ def generate_general_syscall_doc(generator, input_file_name, level): if ddesc.para: output += generator.parse_para(ddesc.para) + # parse any nested groups + for inner_group in soup.find_all("innergroup"): + new_input_file_name = inner_group["refid"] + '.xml' + new_input_file = os.path.join(dir_name, new_input_file_name) + output += generator.level_to_heading(level, inner_group.text) + output += generate_general_syscall_doc(generator, new_input_file, level + 1) + # parse all of the function definitions - if len(elements) == 0: + if len(elements) == 0 and output == "": return "No methods." for member in elements: