If invocations are hidden behind config guards the count of how many invocations there are will be wrong. The C compiler will correctly assign the value with enum auto numbering, so there's no need to override that here
182 lines
4.5 KiB
Python
Executable file
182 lines
4.5 KiB
Python
Executable file
#!/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 <sel4/sel4_arch/invocation.h>
|
|
#include <sel4/arch/invocation.h>
|
|
{{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 <api/invocation.h>
|
|
{{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 <arch/api/sel4_invocation.h>
|
|
{{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)
|
|
|