Syscalls docs in manual generated by doxygen

This adds a dummy header with syscall prototypes with doxygen comments.
The build process for the manual includes parsing these comments using
doxygen. Doxygen produces an xml file which is parsed by a script to
generate latex which is included in the manual. This approach was chosen
over doxygen's native latex output to gain greater control over the
formatting of the generated documentation, and to take advantage of
existing api-formatting support in the sel4 manual.

Related issue: SELFOUR-606
This commit is contained in:
Stephen Sherratt 2016-09-13 16:34:51 +10:00
parent 5a0bdb7480
commit c464470d6c
17 changed files with 2895 additions and 264 deletions

View file

@ -13,6 +13,7 @@
#include <sel4/types.h>
#include <sel4/syscalls.h>
#include <sel4/arch/syscalls.h>
#include <sel4/sel4_arch/syscalls.h>

View file

@ -0,0 +1,235 @@
/*
* Copyright 2016, 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)
*/
#ifndef __LIBSEL4_SYSCALLS_H
#define __LIBSEL4_SYSCALLS_H
#include <autoconf.h>
/**
* @defgroup SystemCalls System Calls
* @{
*
* @defgroup GeneralSystemCalls General System Calls
* @{
*/
/**
* @xmlonly <manual name="Send" label="sel4_send"/> @endxmlonly
* @brief Send to a capability
*
* @xmlonly
* See <autoref sec="sys_send"/>
* @endxmlonly
*
* @param[in] dest The capability to be invoked.
* @param[in] msgInfo The messageinfo structure for the IPC.
*/
static inline void
seL4_Send(seL4_CPtr dest, seL4_MessageInfo_t msgInfo);
/**
* @xmlonly <manual name="Recv" label="sel4_recv"/> @endxmlonly
* @brief Block until a message is received on an endpoint
*
* @xmlonly
* See <autoref sec="sys_recv"/>
* @endxmlonly
*
* @param[in] src The capability to be invoked.
* @param[out] sender The address to write sender information to.
* The sender information is the badge of the
* endpoint capability that was invoked by the
* sender, or the notification word of the
* notification object that was signalled.
* This parameter is ignored if `NULL`.
*
* @return A `seL4_MessageInfo_t` structure
* @xmlonly
* as described in <autoref sec="messageinfo"/>
* @endxmlonly
*/
static inline seL4_MessageInfo_t
seL4_Recv(seL4_CPtr src, seL4_Word* sender);
/**
* @xmlonly <manual name="Call" label="sel4_call"/> @endxmlonly
* @brief Call a capability
*
* @xmlonly
* See <autoref sec="sys_call"/>
* @endxmlonly
*
* @param[in] dest The capability to be invoked.
* @param[in] msgInfo The messageinfo structure for the IPC.
*
* @return A `seL4_MessageInfo_t` structure
* @xmlonly
* as described in <autoref sec="messageinfo"/>
* @endxmlonly
*/
static inline seL4_MessageInfo_t
seL4_Call(seL4_CPtr dest, seL4_MessageInfo_t msgInfo);
/**
* @xmlonly <manual name="Reply" label="sel4_reply"/> @endxmlonly
* @brief Perform a send to a one-off reply capability stored when
* the thread was last called
*
* @xmlonly
* See <autoref sec="sys_reply"/>
* @endxmlonly
*
* @param[in] msgInfo The messageinfo structure for the IPC.
*/
static inline void
seL4_Reply(seL4_MessageInfo_t msgInfo);
/**
* @xmlonly <manual name="Polling Send" label="sel4_nbsend"/> @endxmlonly
* @brief Perform a polling send to a capability
*
* @xmlonly
* See <autoref sec="sys_nbsend"/>
* @endxmlonly
*
* @param[in] dest The capability to be invoked.
* @param[in] msgInfo The messageinfo structure for the IPC.
*/
static inline void
seL4_NBSend(seL4_CPtr dest, seL4_MessageInfo_t msgInfo);
/**
* @xmlonly <manual name="Reply Recv" label="sel4_replyrecv"/> @endxmlonly
* @brief Perform a reply followed by a receive in one system call
*
* @xmlonly
* See <autoref sec="sys_replyrecv"/>
* @endxmlonly
*
* @param[in] dest The capability to be invoked.
* @param[in] msgInfo The messageinfo structure for the IPC.
* @param[out] sender The address to write sender information to.
* The sender information is the badge of the
* endpoint capability that was invoked by the
* sender, or the notification word of the
* notification object that was signalled.
* This parameter is ignored if `NULL`.
*
* @return A `seL4_MessageInfo_t` structure
* @xmlonly
* as described in <autoref sec="messageinfo"/>
* @endxmlonly
*/
static inline seL4_MessageInfo_t
seL4_ReplyRecv(seL4_CPtr dest, seL4_MessageInfo_t msgInfo, seL4_Word *sender);
/**
* @xmlonly <manual name="NBRecv" label="sel4_nbrecv"/> @endxmlonly
* @brief Receive a message from an endpoint but do not block
* in the case that no messages are pending
*
* @xmlonly
* See <autoref sec="sys_nbrecv"/>
* @endxmlonly
*
* @param[in] src The capability to be invoked.
* @param[out] sender The address to write sender information to.
* The sender information is the badge of the
* endpoint capability that was invoked by the
* sender, or the notification word of the
* notification object that was signalled.
* This parameter is ignored if `NULL`.
*
* @return A `seL4_MessageInfo_t` structure
* @xmlonly
* as described in <autoref sec="messageinfo"/>
* @endxmlonly
*/
static inline seL4_MessageInfo_t
seL4_NBRecv(seL4_CPtr src, seL4_Word* sender);
/**
* @xmlonly <manual name="Yield" label="sel4_yield"/> @endxmlonly
* @brief Donate the remaining timeslice to a thread of the same priority
*
* @xmlonly
* See <autoref sec="sys_yield"/>
* @endxmlonly
*/
static inline void
seL4_Yield(void);
/**
* @xmlonly <manual name="Signal" label="sel4_signal"/> @endxmlonly
* @brief Signal a notification
*
* This is not a proper system call known by the kernel. Rather, it is a
* convenience wrapper which calls seL4_Send().
* It is useful for signalling a notification.
*
* @xmlonly
* See the description of <nameref name="seL4_Send"/> in <autoref sec="sys_send"/>.
* @endxmlonly
*
* @param[in] dest The capability to be invoked.
*/
static inline void
seL4_Signal(seL4_CPtr dest);
/**
* @xmlonly <manual name="Wait" label="sel4_wait"/> @endxmlonly
* @brief Perform a receive on a notification object
*
* This is not a proper system call known by the kernel. Rather, it is a
* convenience wrapper which calls seL4_Recv().
*
* @xmlonly
* See the description of <nameref name="seL4_Recv"/> in <autoref sec="sys_recv"/>.
* @endxmlonly
*
* @param[in] src The capability to be invoked.
* @param[out] sender The address to write sender information to.
* The sender information is the badge of the
* endpoint capability that was invoked by the
* sender, or the notification word of the
* notification object that was signalled.
* This parameter is ignored if `NULL`.
*/
static inline void
seL4_Wait(seL4_CPtr src, seL4_Word *sender);
/**
* @xmlonly <manual name="Poll" label="sel4_poll"/> @endxmlonly
* @brief Perform a non-blocking recv on a notification object
*
* This is not a proper system call known by the kernel. Rather, it is a
* convenience wrapper which calls seL4_NBRecv().
* It is useful for doing a non-blocking wait on a notification.
*
* @xmlonly
* See the description of <nameref name="seL4_NBRecv"/> in <autoref sec="sys_nbrecv"/>.
* @endxmlonly
*
* @param[in] src The capability to be invoked.
* @param[out] sender The address to write sender information to.
* The sender information is the badge of the
* endpoint capability that was invoked by the
* sender, or the notification word of the
* notification object that was signalled.
* This parameter is ignored if `NULL`.
*/
static inline seL4_MessageInfo_t
seL4_Poll(seL4_CPtr src, seL4_Word *sender);
/** @} */
/** @} */
#endif /* __LIBSEL4_SYSCALLS_H */

2406
manual/Doxyfile Normal file

File diff suppressed because it is too large Load diff

View file

@ -39,6 +39,7 @@ Lpr = lpr
mv = mv
awk = awk
R = R
doxygen = doxygen
# To add a second target, simply append the basename of the .tex file here
Targets = manual
@ -73,13 +74,21 @@ Bib = references.bib
Tex = $(addsuffix .tex, $(Targets))
Diff_Pdf = $(addsuffix .pdf, $(Optional))
DoxygenOutput = doxygen-output
DoxygenXml = $(DoxygenOutput)/xml
GeneratedLatexDir = generated
GeneratedLatex = $(wildcard $(GeneratedLatexDir)/*.tex)
GenerateLatexTool = tools/parse_doxygen_xml.py
.PHONY: FORCE
all: pdf
diff: diff_pdf
FORCE:
ps: $(Ps)
pdf: $(Figures) Makefile $(Pdf)
pdf: generated-latex $(Figures) Makefile $(Pdf)
diff_pdf: $(Figures) Makefile $(Diff_Pdf)
# Verbosity.
@ -89,6 +98,21 @@ else
Q:=@
endif
.PHONY: doxygen
doxygen:
$(doxygen)
# Xml files generated by doxygen
${DoxygenXml}/group__GeneralSystemCalls.xml: doxygen
# Latex files translatef from doxygen-generated xml
${GeneratedLatexDir}/general_syscalls.tex: ${DoxygenXml}/group__GeneralSystemCalls.xml
${Q}python ${GenerateLatexTool} --input $< --output $@
# Collect generated latex files into single rule
generated-latex: ${GeneratedLatexDir}/general_syscalls.tex
# Fetch information from the environment that needs to go into the document.
env.tex: FORCE
@echo 'ENV ->' $@
@ -142,6 +166,7 @@ print: pdf
clean:
rm -f *.aux *.toc *.bbl *.blg *.dvi *.log *.pstex* *.eps *.cb *.brf \
*.out *.ps *-diff.tex *.mps .log *.pdf *.tgz *~ *.lof *.lot env.tex
rm -rf ${DoxygenOutput} ${GeneratedLatexDir}
tar: clean
( p=`pwd` && d=`basename "$$p"` && cd .. && \

View file

@ -12,6 +12,7 @@
\newcommand{\param}[3]{\texttt{#1}&\texttt{#2}&#3\\ }
\newcommand{\inputapidoc}[1] {\input{parts/api/#1.tex}}
\newcommand{\inputgeneratedapidoc}[1] {\input{generated/#1.tex}}
\newcommand{\apidoc}[7]
{
@ -240,17 +241,7 @@ complete the \apifunc{seL4\_Untyped\_Retype}{untyped_retype} request.
\vfill
\section{System Calls}
\inputapidoc{sel4_send}
\inputapidoc{sel4_recv}
\inputapidoc{sel4_call}
\inputapidoc{sel4_reply}
\inputapidoc{sel4_nbsend}
\inputapidoc{sel4_replyrecv}
\inputapidoc{sel4_nbrecv}
\inputapidoc{sel4_yield}
\inputapidoc{sel4_signal}
\inputapidoc{sel4_wait}
\inputapidoc{sel4_poll}
\inputgeneratedapidoc{general_syscalls}
\clearpage
\section{Architecture-Independent Object Methods}

View file

@ -1,21 +0,0 @@
%
% Copyright 2014, General Dynamics C4 Systems
%
% This software may be distributed and modified according to the terms of
% the GNU General Public License version 2. Note that NO WARRANTY is provided.
% See "LICENSE_GPLv2.txt" for details.
%
% @TAG(GD_GPL)
%
\apidoc
{sel4_call}
{Call}
{Call a capability}
{static inline seL4\_MessageInfo\_t seL4\_Call}
{
\param{seL4\_CPtr}{dest}{\invokedcapdesc}
\param{seL4\_MessageInfo\_t}{msgInfo}{\messageinfodesc}
}
{\messageinforetdesc}
{See \autoref{sec:sys_call} }

View file

@ -1,21 +0,0 @@
%
% Copyright 2014, General Dynamics C4 Systems
%
% This software may be distributed and modified according to the terms of
% the GNU General Public License version 2. Note that NO WARRANTY is provided.
% See "LICENSE_GPLv2.txt" for details.
%
% @TAG(GD_GPL)
%
\apidoc
{sel4_nbrecv}
{NBRecv}
{Receive a message from an endpoint but do not block in the case that no messages are pending}
{static inline seL4\_MessageInfo\_t seL4\_NBRecv}
{
\param{seL4\_CPtr}{src}{\invokedcapdesc}
\param{seL4\_Word*}{sender}{\senderdesc}
}
{\messageinforetdesc}
{See \autoref{sec:sys_nbrecv}}

View file

@ -1,21 +0,0 @@
%
% Copyright 2014, General Dynamics C4 Systems
%
% This software may be distributed and modified according to the terms of
% the GNU General Public License version 2. Note that NO WARRANTY is provided.
% See "LICENSE_GPLv2.txt" for details.
%
% @TAG(GD_GPL)
%
\apidoc
{sel4_nbsend}
{Polling Send}
{Perform a polling send to a capability}
{static inline void seL4\_NBSend}
{
\param{seL4\_CPtr}{dest}{\invokedcapdesc}
\param{seL4\_MessageInfo\_t}{msgInfo}{\messageinfodesc}
}
{\noret}
{See \autoref{sec:sys_nbsend}}

View file

@ -1,29 +0,0 @@
%
% Copyright 2014, General Dynamics C4 Systems
%
% This software may be distributed and modified according to the terms of
% the GNU General Public License version 2. Note that NO WARRANTY is provided.
% See "LICENSE_GPLv2.txt" for details.
%
% @TAG(GD_GPL)
%
\apidoc
{sel4_poll}
{Poll}
{Perform a non-blocking recv on a notification object.}
{static inline void seL4\_Poll}
{
\param{seL4\_CPtr}{src}{\invokedcapdesc}
\param{seL4\_Word*}{sender}{\senderdesc}
}
{\noret}
{
This is not a proper system call
known by the kernel. Rather, it is a convenience
wrapper provided by the seL4 userland library which calls
\apifunc{seL4\_NBRecv}{sel4_nbrecv}. It is
useful for doing a non-blocking wait on a notification.
See the description of \apifunc{seL4\_NBRecv}{sel4_nbrecv} in \autoref{sec:sys_nbrecv}
}

View file

@ -1,21 +0,0 @@
%
% Copyright 2014, General Dynamics C4 Systems
%
% This software may be distributed and modified according to the terms of
% the GNU General Public License version 2. Note that NO WARRANTY is provided.
% See "LICENSE_GPLv2.txt" for details.
%
% @TAG(GD_GPL)
%
\apidoc
{sel4_recv}
{Recv}
{Block until a message is received on an endpoint}
{static inline seL4\_MessageInfo\_t seL4\_Recv}
{
\param{seL4\_CPtr}{src}{\invokedcapdesc}
\param{seL4\_Word*}{sender}{\senderdesc}
}
{\messageinforetdesc}
{See \autoref{sec:sys_recv}}

View file

@ -1,20 +0,0 @@
%
% Copyright 2014, General Dynamics C4 Systems
%
% This software may be distributed and modified according to the terms of
% the GNU General Public License version 2. Note that NO WARRANTY is provided.
% See "LICENSE_GPLv2.txt" for details.
%
% @TAG(GD_GPL)
%
\apidoc
{sel4_reply}
{Reply}
{Perform a send to a one-off reply capability stored when the thread was last called}
{static inline void seL4\_Reply}
{
\param{seL4\_MessageInfo\_t}{msgInfo}{\messageinfodesc}
}
{\noret}
{See \autoref{sec:sys_reply}}

View file

@ -1,22 +0,0 @@
%
% Copyright 2014, General Dynamics C4 Systems
%
% This software may be distributed and modified according to the terms of
% the GNU General Public License version 2. Note that NO WARRANTY is provided.
% See "LICENSE_GPLv2.txt" for details.
%
% @TAG(GD_GPL)
%
\apidoc
{sel4_replyrecv}
{Reply Recv}
{Perform a reply followed by a receive in one system call}
{static inline seL4\_MessageInfo\_t seL4\_ReplyRecv}
{
\param{seL4\_CPtr}{dest}{\invokedcapdesc}
\param{seL4\_MessageInfo\_t}{msgInfo}{\messageinfodesc}
\param{seL4\_Word*}{sender}{\senderdesc}
}
{\messageinforetdesc}
{See \autoref{sec:sys_replyrecv}}

View file

@ -1,21 +0,0 @@
%
% Copyright 2014, General Dynamics C4 Systems
%
% This software may be distributed and modified according to the terms of
% the GNU General Public License version 2. Note that NO WARRANTY is provided.
% See "LICENSE_GPLv2.txt" for details.
%
% @TAG(GD_GPL)
%
\apidoc
{sel4_send}
{Send}
{Send to a capability}
{static inline void seL4\_Send}
{
\param{seL4\_CPtr}{dest}{\invokedcapdesc}
\param{seL4\_MessageInfo\_t}{msgInfo}{\messageinfodesc}
}
{\noret}
{See \autoref{sec:sys_send}}

View file

@ -1,28 +0,0 @@
%
% Copyright 2014, General Dynamics C4 Systems
%
% This software may be distributed and modified according to the terms of
% the GNU General Public License version 2. Note that NO WARRANTY is provided.
% See "LICENSE_GPLv2.txt" for details.
%
% @TAG(GD_GPL)
%
\apidoc
{sel4_signal}
{Signal}
{Signal a notification}
{static inline void seL4\_Signal}
{
\param{seL4\_CPtr}{dest}{\invokedcapdesc}
}
{\noret}
{
This is not a proper system call
known by the kernel. Rather, it is a convenience
wrapper provided by the seL4 userland library which calls
\apifunc{seL4\_Send}{sel4_send}. It is
useful for signalling a notification.
See the description of \apifunc{seL4\_Send}{sel4_send} in \autoref{sec:sys_send}
}

View file

@ -1,28 +0,0 @@
%
% Copyright 2014, General Dynamics C4 Systems
%
% This software may be distributed and modified according to the terms of
% the GNU General Public License version 2. Note that NO WARRANTY is provided.
% See "LICENSE_GPLv2.txt" for details.
%
% @TAG(GD_GPL)
%
\apidoc
{sel4_wait}
{Wait}
{Perform a receive on a notification object.}
{static inline void seL4\_Wait}
{
\param{seL4\_CPtr}{src}{\invokedcapdesc}
\param{seL4\_Word*}{sender}{\senderdesc}
}
{\noret}
{This is not a proper system call
known by the kernel. Rather, it is a convenience
wrapper provided by the seL4 userland library which calls
\apifunc{seL4\_Recv}{sel4_recv}.
See the description of \apifunc{seL4\_Recv}{sel4_recv} in \autoref{sec:sys_recv}
}

View file

@ -1,20 +0,0 @@
%
% Copyright 2014, General Dynamics C4 Systems
%
% This software may be distributed and modified according to the terms of
% the GNU General Public License version 2. Note that NO WARRANTY is provided.
% See "LICENSE_GPLv2.txt" for details.
%
% @TAG(GD_GPL)
%
\apidoc
{sel4_yield}
{Yield}
{Donate the remaining timeslice to a thread of the same priority}
{static inline void seL4\_Yield}
{
\param{void}{}{}
}
{\noret}
{See \autoref{sec:sys_yield}}

225
manual/tools/parse_doxygen_xml.py Executable file
View file

@ -0,0 +1,225 @@
#!/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)
#
# Script for generating latex from doxygen-generated xml files.
# The generatetd latex files are compatible with the seL4 manual.
import xml.dom.minidom
import argparse
import sys
import os
import re
# Dict mapping characters to their escape sequence in latex
LATEX_ESCAPE_PATTERNS = {
"_": "\\_",
}
LATEX_ESCAPE_REGEX = re.compile('|'.join(LATEX_ESCAPE_PATTERNS.keys()))
# Return a string with latex special characters escaped
def latex_escape(string):
return LATEX_ESCAPE_REGEX.sub(lambda p: LATEX_ESCAPE_PATTERNS[p.group()], string)
# Return the first node with a given tag inside parent
def get_node(parent, tagname):
return parent.getElementsByTagName(tagname)[0]
# Return a string containing a concatenation of a nodes text node
# children, recursing into non-text nodes or escaping latex if
# necessary.
def get_text(node, recur=False, escape=True):
output = ""
for n in node.childNodes:
if n.nodeType == xml.dom.Node.TEXT_NODE:
if escape:
output += latex_escape(n.data)
else:
output += n.data
elif recur:
output += get_text(n, True, escape)
return output
# Parse a paragraph node, handling special doxygen node types
# that may appear inside a paragraph.
def parse_para(para_node, ref_dict={}):
output = ""
for n in para_node.childNodes:
if n.nodeType == xml.dom.Node.TEXT_NODE:
output += latex_escape(n.data)
elif n.tagName == "para":
output += parse_para(n, ref_dict)
elif n.tagName == "computeroutput":
output += "\\texttt{%s}" % get_text(n)
elif len(ref_dict) != 0 and n.tagName == "ref":
refid = n.getAttribute("refid")
ref = ref_dict[refid]
output += "\\apifunc{%(name)s}{%(label)s}" % ref
elif n.tagName == "nameref":
name = n.getAttribute("name")
ref = ref_dict[name]
output += "\\apifunc{%(name)s}{%(label)s}" % ref
elif n.tagName == "autoref":
output += "\\autoref{sec:%s}" % n.getAttribute("sec")
return output
# Parse the "brief description" section of a doxygen member.
def parse_brief(parent):
para_nodes = get_node(parent, "briefdescription").getElementsByTagName("para")
para_text = "\n\n".join([parse_para(n) for n in para_nodes])
return para_text
# Parse the "detailed description" section of a doxygen member.
def parse_detailed_desc(parent, ref_dict):
param_nodes = parent.getElementsByTagName("param")
params = {}
for n in param_nodes:
param_type = get_text(n.getElementsByTagName("type")[0], True)
if param_type == "void":
continue
param_name = get_text(n.getElementsByTagName("declname")[0], True)
params[param_name] = {"type": param_type}
detailed_desc = parent.getElementsByTagName("detaileddescription")[0]
param_items = detailed_desc.getElementsByTagName("parameteritem")
for param_item in param_items:
param_name_node = param_item.getElementsByTagName("parametername")[0]
param_desc_node = param_item.getElementsByTagName("parameterdescription")[0]
param_name = parse_para(param_name_node, ref_dict)
param_desc = parse_para(param_desc_node, ref_dict)
params[param_name]["desc"] = param_desc
if len(params) == 0:
params_str = "\\param{void}{}{}"
else:
params_str = ""
for param_name, param_info in params.items():
params_str += "\\param{%(type)s}{%(name)s}{%(desc)s}\n" % {
"type": param_info["type"],
"name": param_name,
"desc": param_info["desc"]
}
details = ""
for n in detailed_desc.childNodes:
if n.nodeType == xml.dom.Node.ELEMENT_NODE and \
n.tagName == "para":
details += parse_para(n, ref_dict)
ret = "\\noret"
simplesects = detailed_desc.getElementsByTagName("simplesect")
for n in simplesects:
if n.nodeType == xml.dom.Node.ELEMENT_NODE and \
n.getAttribute("kind") == "return":
ret = parse_para(n, ref_dict)
return (details, params_str, ret)
# Extract a function prototype from a doxygen member.
def parse_prototype(parent):
inline = parent.getAttribute("inline") == "yes"
static = parent.getAttribute("static") == "yes"
ret_type = get_text(parent.getElementsByTagName("type")[0])
name = get_text(parent.getElementsByTagName("name")[0])
output = "%s %s" % (ret_type, name)
if inline:
output = "inline " + output
if static:
output = "static " + output
return output
# Return a dict mapping reference ids and reference names
# to details about the referee.
def build_ref_dict(doc):
ret = {}
for member in doc.getElementsByTagName("memberdef"):
manual_node = get_node(member, "manual")
name = get_text(get_node(member, "name"), escape=False)
manual_node = get_node(member, "manual")
label = manual_node.getAttribute("label")
ref_id = member.getAttribute("id")
data = {
"name": latex_escape(name),
"label": label,
"ref": ref_id,
}
ret[ref_id] = data
ret[name] = data
return ret
# Takes a path to a file containing doxygen-generated xml,
# and return a string containing latex suitable for inclusion
# in the sel4 manual.
def generate_general_syscall_doc(input_file_name):
with open(input_file_name, "r") as f:
output = ""
doc = xml.dom.minidom.parse(f)
ref_dict = build_ref_dict(doc)
for member in doc.getElementsByTagName("memberdef"):
manual_node = get_node(member, "manual")
details, params, ret = parse_detailed_desc(member, ref_dict)
output += """
\\apidoc
{%(label)s}
{%(name)s}
{%(brief)s}
{%(prototype)s}
{%(params)s}
{%(ret)s}
{%(details)s}
""" % {
"label": manual_node.getAttribute("label"),
"name": latex_escape(manual_node.getAttribute("name")),
"brief": parse_brief(member),
"prototype": parse_prototype(member),
"params": params,
"ret": ret,
"details": details,
}
return output
def process_args():
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--input", dest="input", type=str,
help="File containing doxygen-generated xml.")
parser.add_argument("-o", "--output", dest="output", type=str,
help="Output latex file.")
return parser
def main():
args = process_args().parse_args()
if not os.path.exists(os.path.dirname(args.output)):
os.makedirs(os.path.dirname(args.output))
output_str = generate_general_syscall_doc(args.input)
with open(args.output, "w") as output_file:
output_file.write(output_str)
if __name__ == "__main__":
sys.exit(main())