commit
43ba312593
|
@ -18,7 +18,7 @@ from docutils.parsers.rst import Directive
|
|||
from sphinx import addnodes
|
||||
from sphinx import version_info
|
||||
from sphinx.roles import XRefRole
|
||||
from sphinx.locale import l_, _
|
||||
from sphinx.locale import _
|
||||
from sphinx.domains import Domain, ObjType, Index
|
||||
from sphinx.directives import ObjectDescription
|
||||
from sphinx.util.nodes import make_refnode
|
||||
|
|
148
doc/mkapiref.py
148
doc/mkapiref.py
|
@ -1,9 +1,11 @@
|
|||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# nghttp2 - HTTP/2 C Library
|
||||
|
||||
#
|
||||
# Copyright (c) 2020 nghttp2 contributors
|
||||
# Copyright (c) 2020 ngtcp2 contributors
|
||||
# Copyright (c) 2012 Tatsuhiro Tsujikawa
|
||||
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
|
@ -25,17 +27,16 @@
|
|||
|
||||
# Generates API reference from C source code.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
from __future__ import print_function # At least python 2.6 is required
|
||||
import re, sys, argparse, os.path
|
||||
|
||||
class FunctionDoc:
|
||||
def __init__(self, name, content, domain):
|
||||
def __init__(self, name, content, domain, filename):
|
||||
self.name = name
|
||||
self.content = content
|
||||
self.domain = domain
|
||||
if self.domain == 'function':
|
||||
self.funcname = re.search(r'(nghttp2_[^ )]+)\(', self.name).group(1)
|
||||
self.filename = filename
|
||||
|
||||
def write(self, out):
|
||||
out.write('.. {}:: {}\n'.format(self.domain, self.name))
|
||||
|
@ -64,6 +65,26 @@ class StructDoc:
|
|||
out.write(' {}\n'.format(line))
|
||||
out.write('\n')
|
||||
|
||||
class EnumDoc:
|
||||
def __init__(self, name, content, members):
|
||||
self.name = name
|
||||
self.content = content
|
||||
self.members = members
|
||||
|
||||
def write(self, out):
|
||||
if self.name:
|
||||
out.write('.. type:: {}\n'.format(self.name))
|
||||
out.write('\n')
|
||||
for line in self.content:
|
||||
out.write(' {}\n'.format(line))
|
||||
out.write('\n')
|
||||
for name, content in self.members:
|
||||
out.write(' .. enum:: {}\n'.format(name))
|
||||
out.write('\n')
|
||||
for line in content:
|
||||
out.write(' {}\n'.format(line))
|
||||
out.write('\n')
|
||||
|
||||
class MacroDoc:
|
||||
def __init__(self, name, content):
|
||||
self.name = name
|
||||
|
@ -75,50 +96,76 @@ class MacroDoc:
|
|||
for line in self.content:
|
||||
out.write(' {}\n'.format(line))
|
||||
|
||||
def make_api_ref(infiles):
|
||||
class MacroSectionDoc:
|
||||
def __init__(self, content):
|
||||
self.content = content
|
||||
|
||||
def write(self, out):
|
||||
out.write('\n')
|
||||
c = ' '.join(self.content).strip()
|
||||
out.write(c)
|
||||
out.write('\n')
|
||||
out.write('-' * len(c))
|
||||
out.write('\n\n')
|
||||
|
||||
class TypedefDoc:
|
||||
def __init__(self, name, content):
|
||||
self.name = name
|
||||
self.content = content
|
||||
|
||||
def write(self, out):
|
||||
out.write('''.. type:: {}\n'''.format(self.name))
|
||||
out.write('\n')
|
||||
for line in self.content:
|
||||
out.write(' {}\n'.format(line))
|
||||
|
||||
def make_api_ref(infile):
|
||||
macros = []
|
||||
enums = []
|
||||
types = []
|
||||
functions = []
|
||||
for infile in infiles:
|
||||
while True:
|
||||
while True:
|
||||
line = infile.readline()
|
||||
if not line:
|
||||
break
|
||||
elif line == '/**\n':
|
||||
line = infile.readline()
|
||||
if not line:
|
||||
break
|
||||
elif line == '/**\n':
|
||||
line = infile.readline()
|
||||
doctype = line.split()[1]
|
||||
if doctype == '@function':
|
||||
functions.append(process_function('function', infile))
|
||||
elif doctype == '@functypedef':
|
||||
types.append(process_function('type', infile))
|
||||
elif doctype == '@struct' or doctype == '@union':
|
||||
types.append(process_struct(infile))
|
||||
elif doctype == '@enum':
|
||||
enums.append(process_enum(infile))
|
||||
elif doctype == '@macro':
|
||||
macros.append(process_macro(infile))
|
||||
doctype = line.split()[1]
|
||||
if doctype == '@function':
|
||||
functions.append(process_function('function', infile))
|
||||
elif doctype == '@functypedef':
|
||||
types.append(process_function('type', infile))
|
||||
elif doctype == '@struct' or doctype == '@union':
|
||||
types.append(process_struct(infile))
|
||||
elif doctype == '@enum':
|
||||
enums.append(process_enum(infile))
|
||||
elif doctype == '@macro':
|
||||
macros.append(process_macro(infile))
|
||||
elif doctype == '@macrosection':
|
||||
macros.append(process_macrosection(infile))
|
||||
elif doctype == '@typedef':
|
||||
types.append(process_typedef(infile))
|
||||
return macros, enums, types, functions
|
||||
|
||||
alldocs = [('Macros', macros),
|
||||
('Enums', enums),
|
||||
('Types (structs, unions and typedefs)', types),
|
||||
('Functions', functions)]
|
||||
|
||||
def output(
|
||||
indexfile, macrosfile, enumsfile, typesfile, funcsdir,
|
||||
title, indexfile, macrosfile, enumsfile, typesfile, funcsdir,
|
||||
macros, enums, types, functions):
|
||||
indexfile.write('''
|
||||
API Reference
|
||||
=============
|
||||
{title}
|
||||
{titledecoration}
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
macros
|
||||
enums
|
||||
types
|
||||
''')
|
||||
{macros}
|
||||
{enums}
|
||||
{types}
|
||||
'''.format(
|
||||
title=title, titledecoration='='*len(title),
|
||||
macros=os.path.splitext(os.path.basename(macrosfile.name))[0],
|
||||
enums=os.path.splitext(os.path.basename(enumsfile.name))[0],
|
||||
types=os.path.splitext(os.path.basename(typesfile.name))[0],
|
||||
))
|
||||
|
||||
for doc in functions:
|
||||
indexfile.write(' {}\n'.format(doc.funcname))
|
||||
|
@ -153,9 +200,10 @@ Types (structs, unions and typedefs)
|
|||
Synopsis
|
||||
--------
|
||||
|
||||
*#include <nghttp2/nghttp2.h>*
|
||||
*#include <nghttp2/{filename}>*
|
||||
|
||||
'''.format(funcname=doc.funcname, secul='='*len(doc.funcname)))
|
||||
'''.format(funcname=doc.funcname, secul='='*len(doc.funcname),
|
||||
filename=doc.filename))
|
||||
doc.write(f)
|
||||
|
||||
def process_macro(infile):
|
||||
|
@ -164,6 +212,17 @@ def process_macro(infile):
|
|||
macro_name = line.split()[1]
|
||||
return MacroDoc(macro_name, content)
|
||||
|
||||
def process_macrosection(infile):
|
||||
content = read_content(infile)
|
||||
return MacroSectionDoc(content)
|
||||
|
||||
def process_typedef(infile):
|
||||
content = read_content(infile)
|
||||
typedef = infile.readline()
|
||||
typedef = re.sub(r';\n$', '', typedef)
|
||||
typedef = re.sub(r'typedef ', '', typedef)
|
||||
return TypedefDoc(typedef, content)
|
||||
|
||||
def process_enum(infile):
|
||||
members = []
|
||||
enum_name = None
|
||||
|
@ -176,7 +235,7 @@ def process_enum(infile):
|
|||
member_content = read_content(infile)
|
||||
line = infile.readline()
|
||||
items = line.split()
|
||||
member_name = items[0]
|
||||
member_name = items[0].rstrip(',')
|
||||
if len(items) >= 3:
|
||||
member_content.insert(0, '(``{}``) '\
|
||||
.format(' '.join(items[2:]).rstrip(',')))
|
||||
|
@ -185,7 +244,7 @@ def process_enum(infile):
|
|||
enum_name = line.rstrip().split()[1]
|
||||
enum_name = re.sub(r';$', '', enum_name)
|
||||
break
|
||||
return StructDoc(enum_name, content, members, 'macro')
|
||||
return EnumDoc(enum_name, content, members)
|
||||
|
||||
def process_struct(infile):
|
||||
members = []
|
||||
|
@ -226,7 +285,9 @@ def process_function(domain, infile):
|
|||
func_proto = re.sub(r';\n$', '', func_proto)
|
||||
func_proto = re.sub(r'\s+', ' ', func_proto)
|
||||
func_proto = re.sub(r'NGHTTP2_EXTERN ', '', func_proto)
|
||||
return FunctionDoc(func_proto, content, domain)
|
||||
func_proto = re.sub(r'typedef ', '', func_proto)
|
||||
filename = os.path.basename(infile.name)
|
||||
return FunctionDoc(func_proto, content, domain, filename)
|
||||
|
||||
def read_content(infile):
|
||||
content = []
|
||||
|
@ -251,6 +312,8 @@ def transform_content(content):
|
|||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description="Generate API reference")
|
||||
parser.add_argument('--title', default='API Reference',
|
||||
help='title of index page')
|
||||
parser.add_argument('index', type=argparse.FileType('w'),
|
||||
help='index output file')
|
||||
parser.add_argument('macros', type=argparse.FileType('w'),
|
||||
|
@ -269,12 +332,13 @@ if __name__ == '__main__':
|
|||
types = []
|
||||
funcs = []
|
||||
for infile in args.files:
|
||||
m, e, t, f = make_api_ref(args.files)
|
||||
m, e, t, f = make_api_ref(infile)
|
||||
macros.extend(m)
|
||||
enums.extend(e)
|
||||
types.extend(t)
|
||||
funcs.extend(f)
|
||||
funcs.sort(key=lambda x: x.funcname)
|
||||
output(
|
||||
args.title,
|
||||
args.index, args.macros, args.enums, args.types, args.funcsdir,
|
||||
macros, enums, types, funcs)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue