Commit 9add72c2 authored by François Grisez's avatar François Grisez

C++ wrapper: add doxygen docstrings in the API

parent 18678159
......@@ -177,7 +177,7 @@ SHORT_NAMES = NO
# description.)
# The default value is: NO.
JAVADOC_AUTOBRIEF = NO
JAVADOC_AUTOBRIEF = YES
# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
# line (until the first dot) of a Qt-style comment as the brief description. If
......
......@@ -23,6 +23,7 @@ import string
import sys
import xml.etree.ElementTree as ET
import xml.dom.minidom as minidom
import metadoc
class CObject:
......@@ -31,6 +32,7 @@ class CObject:
self.briefDescription = ''
self.detailedDescription = None
self.deprecated = False
self.briefDoc = None
class CEnumValue(CObject):
......@@ -381,6 +383,7 @@ class Project:
if deprecatedNode is not None:
ev.deprecated = True
ev.briefDescription = ''.join(node.find('./briefdescription').itertext()).strip()
ev.briefDoc = metadoc.Description(node.find('./briefdescription'))
ev.detailedDescription = self.__cleanDescription(node.find('./detaileddescription'))
return ev
......@@ -392,6 +395,7 @@ class Project:
if deprecatedNode is not None:
e.deprecated = True
e.briefDescription = ''.join(node.find('./briefdescription').itertext()).strip()
e.briefDoc = metadoc.Description(node.find('./briefdescription'))
e.detailedDescription = self.__cleanDescription(node.find('./detaileddescription'))
enumvalues = node.findall("enumvalue[@prot='public']")
for enumvalue in enumvalues:
......@@ -414,6 +418,7 @@ class Project:
if deprecatedNode is not None:
sm.deprecated = True
sm.briefDescription = ''.join(node.find('./briefdescription').itertext()).strip()
sm.briefDoc = metadoc.Description(node.find('./briefdescription'))
sm.detailedDescription = self.__cleanDescription(node.find('./detaileddescription'))
return sm
......@@ -423,6 +428,7 @@ class Project:
if deprecatedNode is not None:
s.deprecated = True
s.briefDescription = ''.join(node.find('./briefdescription').itertext()).strip()
s.briefDoc = metadoc.Description(node.find('./briefdescription'))
s.detailedDescription = self.__cleanDescription(node.find('./detaileddescription'))
structmembers = node.findall("sectiondef/memberdef[@kind='variable'][@prot='public']")
for structmember in structmembers:
......@@ -561,6 +567,7 @@ class Project:
if deprecatedNode is not None:
f.deprecated = True
f.briefDescription = ''.join(node.find('./briefdescription').itertext()).strip()
f.briefDoc = metadoc.Description(node.find('./briefdescription'))
f.detailedDescription = self.__cleanDescription(node.find('./detaileddescription'))
if f.briefDescription == '' and ''.join(f.detailedDescription.itertext()).strip() == '':
return None
......
#!/usr/bin/python
# Copyright (C) 2017 Belledonne Communications SARL
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class Nil:
pass
class Reference:
def __init__(self, name):
self.cObjectName = name
class Paragraph:
def __init__(self, node=None):
self.parts = []
if node is not None:
self.parse_doxygen_node(node)
def parse_doxygen_node(self, node):
for partNode in node.iter():
text = partNode.text
if text is not None:
self.parts.append(text)
if partNode is not node:
tail = partNode.tail
if tail is not None:
self.parts.append(tail)
class Description:
def __init__(self, node=None):
self.paragraphs = []
if node is not None:
self.parse_doxygen_node(node)
def parse_doxygen_node(self, node):
for paraNode in node.findall('./para'):
self.paragraphs.append(Paragraph(paraNode))
class Translator:
def translate(self, description):
lines = []
for para in description.paragraphs:
if para is not description.paragraphs[0]:
lines.append('')
lines.append(''.join(para.parts))
self._tag_as_brief(lines)
translatedDoc = {'lines': []}
for line in lines:
translatedDoc['lines'].append({'line': line})
return translatedDoc
class DoxygenCppTranslator(Translator):
def _tag_as_brief(self, lines):
if len(lines) > 0:
lines[0] = '@brief ' + lines[0]
class SandcastleCSharpTranslator(Translator):
def _tag_as_brief(self, lines):
if len(lines) > 0:
lines[0] = '<summary>' + lines[0]
lines[-1] = lines[-1] + '</summary>'
......@@ -23,6 +23,7 @@
add_custom_command(OUTPUT include/linphone++/linphone.hh src/linphone++.cc
COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/genwrapper.py" "${PROJECT_BINARY_DIR}/coreapi/help/doc/xml"
DEPENDS ${PROJECT_SOURCE_DIR}/tools/genapixml.py
"${PROJECT_SOURCE_DIR}/tools/metadoc.py"
abstractapi.py
genwrapper.py
class_header.mustache
......
......@@ -586,6 +586,7 @@ class CParser(object):
name = EnumName()
name.from_camel_case(nameStr, namespace=self.namespace.name)
enum = Enum(name)
enum.briefDescription = cenum.briefDoc
self.namespace.add_child(enum)
for cEnumValue in cenum.values:
......@@ -619,6 +620,7 @@ class CParser(object):
name = ClassName()
name.from_camel_case(cclass.name, namespace=self.namespace.name)
_class = Class(name)
_class.briefDescription = cclass.briefDoc
_class.refcountable = self._class_is_refcountable(cclass)
for cproperty in cclass.properties.values():
......@@ -686,6 +688,7 @@ class CParser(object):
raise Error('{0} is not a listener'.format(cclass.name))
listener = Interface(name)
listener.briefDescription = cclass.briefDoc
for property in cclass.properties.values():
if property.name != 'user_data':
......@@ -733,6 +736,7 @@ class CParser(object):
raise BlacklistedException('{0} is blacklisted'.format(name.to_c()));
method = Method(name, type=type)
method.briefDescription = cfunction.briefDoc
method.deprecated = cfunction.deprecated
method.returnType = self.parse_type(cfunction.returnArgument)
......
......@@ -84,10 +84,24 @@ namespace linphone {
{{#methods}}
{{#doc}}
/**
{{#lines}}
* {{{line}}}
{{/lines}}
*/
{{/doc}}
{{{prototype}}}
{{/methods}}
{{#staticMethods}}
{{#doc}}
/**
{{#lines}}
* {{{line}}}
{{/lines}}
*/
{{/doc}}
{{{prototype}}}
{{/staticMethods}}
......
......@@ -26,6 +26,7 @@ import errno
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', 'tools'))
import genapixml as CApi
import abstractapi as AbsApi
import metadoc
class CppTranslator(object):
......@@ -240,6 +241,9 @@ class CppTranslator(object):
methodDict['implPrototype'] = '{implReturn} {longname}({implParams}){const}'.format(**methodElems)
methodDict['sourceCode' ] = self._generate_source_code(method, usedNamespace=namespace)
t = metadoc.DoxygenCppTranslator()
methodDict['doc'] = t.translate(method.briefDescription) if method.briefDescription is not None else None
return methodDict
def _generate_source_code(self, method, usedNamespace=None):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment