#!/usr/bin/env python # # Copyright 2014, NICTA # # This software may be distributed and modified according to the terms of # the BSD 2-Clause license. Note that NO WARRANTY is provided. # See "LICENSE_BSD2.txt" for details. # # @TAG(NICTA_BSD) # # seL4 Invocation ID Generator # ============================ from __future__ import print_function import argparse import sys # install tempita using sudo apt-get install python-tempita or similar for your distro import tempita import xml.dom.minidom COMMON_HEADER = """ {{if libsel4}} /* @LICENSE(NICTA) */ {{else}} /* @LICENSE(OKL_CORE) */ {{endif}} /* This header was generated by kernel/tools/invocation_header_gen.py. * * To add an invocation call number, edit libsel4/include/interfaces/sel4.xml. * */""" INVOCATION_TEMPLATE = COMMON_HEADER + """ #ifndef __{{header_title}}_INVOCATION_H #define __{{header_title}}_INVOCATION_H enum invocation_label { InvalidInvocation, {{for label, condition in invocations}} {{if condition}} #if {{condition}} {{endif}} {{label}}, {{if condition}} #endif {{endif}} {{endfor}} nInvocationLabels }; {{if libsel4}} #include #include {{endif}} #endif /* __{{header_title}}_INVOCATION_H */ """ SEL4_ARCH_INVOCATION_TEMPLATE = COMMON_HEADER + """ #ifndef __{{header_title}}_SEL4_ARCH_INVOCATION_H #define __{{header_title}}_SEL4_ARCH_INVOCATION_H {{if not libsel4}} #include {{endif}} {{py:first = 1}} enum sel4_arch_invocation_label { {{for label, condition in invocations}} {{if condition}} {{if first}} #error "First sel4_arch invocation label cannot be conditional" {{endif}} #if {{condition}} {{endif}} {{if first}} {{py:first = 0}} {{label}} = nInvocationLabels, {{else}} {{label}}, {{endif}} {{if condition}} #endif {{endif}} {{endfor}} nSeL4ArchInvocationLabels }; #endif /* __{{header_title}}_SEL4_ARCH_INVOCATION_H */ """ ARCH_INVOCATION_TEMPLATE = COMMON_HEADER + """ #ifndef __{{header_title}}_ARCH_INVOCATION_H #define __{{header_title}}_ARCH_INVOCATION_H {{if not libsel4}} #include {{endif}} {{py:first = 1}} enum arch_invocation_label { {{for label, condition in invocations}} {{if condition}} {{if first}} #error "First arch invocation label cannot be conditional" {{endif}} #if {{condition}} {{endif}} {{if first}} {{label}} = nSeL4ArchInvocationLabels, {{py:first = 0}} {{else}} {{label}}, {{endif}} {{if condition}} #endif {{endif}} {{endfor}} nArchInvocationLabels }; #endif /* __{{header_title}}_ARCH_INVOCATION_H */ """ def parse_args(): parser = argparse.ArgumentParser(description='Generate seL4 invocation API \ constants and header files') parser.add_argument('--xml', type=argparse.FileType('r'), help='Name of xml file with invocation definitions', required=True) parser.add_argument('--dest', type=argparse.FileType('w'), help='Name of file to create', required=True) parser.add_argument('--libsel4', action='store_true', help='Is this being generated for libsel4?') group = parser.add_mutually_exclusive_group() group.add_argument('--arch', action='store_true', help='Is this being generated for the arch layer?') group.add_argument('--sel4_arch', action='store_true', help='Is this being generated for the seL4 arch layer?') return parser.parse_args() def parse_xml(xml_file): try: doc = xml.dom.minidom.parse(xml_file) except: print("Error: invalid xml file", file=sys.stderr) sys.exit(-1) invocation_labels = [] for method in doc.getElementsByTagName("method"): invocation_labels.append((str(method.getAttribute("id")), str(method.getAttribute("config")))) return invocation_labels def generate(args, invocations): header_title = "API" if args.libsel4: header_title = "LIBSEL4" if args.arch: template = tempita.Template(ARCH_INVOCATION_TEMPLATE) elif args.sel4_arch: template = tempita.Template(SEL4_ARCH_INVOCATION_TEMPLATE) else: template = tempita.Template(INVOCATION_TEMPLATE) args.dest.write(template.substitute(header_title=header_title, libsel4=args.libsel4,invocations=invocations,num_invocations=len(invocations))) args.dest.close() if __name__ == "__main__": args = parse_args() invocations = parse_xml(args.xml) args.xml.close() generate(args, invocations)