diff options
Diffstat (limited to 'docs/doxygen/swig_doc.py')
-rw-r--r-- | docs/doxygen/swig_doc.py | 157 |
1 files changed, 117 insertions, 40 deletions
diff --git a/docs/doxygen/swig_doc.py b/docs/doxygen/swig_doc.py index 4e1ce2e..b9f4e6e 100644 --- a/docs/doxygen/swig_doc.py +++ b/docs/doxygen/swig_doc.py @@ -1,7 +1,8 @@ # -# Copyright 2010,2011 Free Software Foundation, Inc. +# Copyright 2010-2012 Free Software Foundation, Inc. # -# This file is part of GNU Radio +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-gsm # # GNU Radio is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -26,14 +27,12 @@ The file instructs SWIG to transfer the doxygen comments into the python docstrings. """ +from __future__ import unicode_literals -import sys - -try: - from doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile, base -except ImportError: - from gnuradio.doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile, base +import sys, time +from doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile +from doxyxml import DoxyOther, base def py_name(name): bits = name.split('_') @@ -56,18 +55,41 @@ class Block(object): # Check for a parsing error. if item.error(): return False - return item.has_member(make_name(item.name()), DoxyFriend) + friendname = make_name(item.name()) + is_a_block = item.has_member(friendname, DoxyFriend) + # But now sometimes the make function isn't a friend so check again. + if not is_a_block: + is_a_block = di.has_member(friendname, DoxyFunction) + return is_a_block + +class Block2(object): + """ + Checks if doxyxml produced objects correspond to a new style + gnuradio block. + """ + + @classmethod + def includes(cls, item): + if not isinstance(item, DoxyClass): + return False + # Check for a parsing error. + if item.error(): + return False + is_a_block2 = item.has_member('make', DoxyFunction) and item.has_member('sptr', DoxyOther) + return is_a_block2 def utoascii(text): """ - Convert unicode text into ascii and escape quotes. + Convert unicode text into ascii and escape quotes and backslashes. """ if text is None: return '' out = text.encode('ascii', 'replace') - out = out.replace('"', '\\"') - return out + # swig will require us to replace blackslash with 4 backslashes + out = out.replace(b'\\', b'\\\\\\\\') + out = out.replace(b'"', b'\\"').decode('ascii') + return str(out) def combine_descriptions(obj): @@ -83,9 +105,15 @@ def combine_descriptions(obj): description.append(dd) return utoascii('\n\n'.join(description)).strip() +def format_params(parameteritems): + output = ['Args:'] + template = ' {0} : {1}' + for pi in parameteritems: + output.append(template.format(pi.name, pi.description)) + return '\n'.join(output) entry_templ = '%feature("docstring") {name} "{docstring}"' -def make_entry(obj, name=None, templ="{description}", description=None): +def make_entry(obj, name=None, templ="{description}", description=None, params=[]): """ Create a docstring entry for a swig interface file. @@ -102,6 +130,9 @@ def make_entry(obj, name=None, templ="{description}", description=None): return '' if description is None: description = combine_descriptions(obj) + if params: + description += '\n\n' + description += utoascii(format_params(params)) docstring = templ.format(description=description) if not docstring: return '' @@ -121,27 +152,31 @@ def make_func_entry(func, name=None, description=None, params=None): used as the description instead of extracting it from func. params - a parameter list that overrides using func.params. """ - if params is None: - params = func.params - params = [prm.declname for prm in params] - if params: - sig = "Params: (%s)" % ", ".join(params) - else: - sig = "Params: (NONE)" - templ = "{description}\n\n" + sig - return make_entry(func, name=name, templ=utoascii(templ), - description=description) - - -def make_class_entry(klass, description=None): + #if params is None: + # params = func.params + #params = [prm.declname for prm in params] + #if params: + # sig = "Params: (%s)" % ", ".join(params) + #else: + # sig = "Params: (NONE)" + #templ = "{description}\n\n" + sig + #return make_entry(func, name=name, templ=utoascii(templ), + # description=description) + return make_entry(func, name=name, description=description, params=params) + + +def make_class_entry(klass, description=None, ignored_methods=[], params=None): """ Create a class docstring for a swig interface file. """ + if params is None: + params = klass.params output = [] - output.append(make_entry(klass, description=description)) + output.append(make_entry(klass, description=description, params=params)) for func in klass.in_category(DoxyFunction): - name = klass.name() + '::' + func.name() - output.append(make_func_entry(func, name=name)) + if func.name() not in ignored_methods: + name = klass.name() + '::' + func.name() + output.append(make_func_entry(func, name=name)) return "\n\n".join(output) @@ -175,11 +210,33 @@ def make_block_entry(di, block): # the make function. output = [] output.append(make_class_entry(block, description=super_description)) - creator = block.get_member(block.name(), DoxyFunction) output.append(make_func_entry(make_func, description=super_description, - params=creator.params)) + params=block.params)) return "\n\n".join(output) +def make_block2_entry(di, block): + """ + Create class and function docstrings of a new style gnuradio block for a + swig interface file. + """ + descriptions = [] + # For new style blocks all the relevant documentation should be + # associated with the 'make' method. + class_description = combine_descriptions(block) + make_func = block.get_member('make', DoxyFunction) + make_description = combine_descriptions(make_func) + description = class_description + "\n\nConstructor Specific Documentation:\n\n" + make_description + # Associate the combined description with the class and + # the make function. + output = [] + output.append(make_class_entry( + block, description=description, + ignored_methods=['make'], params=make_func.params)) + makename = block.name() + '::make' + output.append(make_func_entry( + make_func, name=makename, description=description, + params=make_func.params)) + return "\n\n".join(output) def make_swig_interface_file(di, swigdocfilename, custom_output=None): @@ -196,39 +253,59 @@ def make_swig_interface_file(di, swigdocfilename, custom_output=None): # Create docstrings for the blocks. blocks = di.in_category(Block) + blocks2 = di.in_category(Block2) + make_funcs = set([]) for block in blocks: try: make_func = di.get_member(make_name(block.name()), DoxyFunction) - make_funcs.add(make_func.name()) - output.append(make_block_entry(di, block)) + # Don't want to risk writing to output twice. + if make_func.name() not in make_funcs: + make_funcs.add(make_func.name()) + output.append(make_block_entry(di, block)) + except block.ParsingError: + sys.stderr.write('Parsing error for block {0}\n'.format(block.name())) + raise + + for block in blocks2: + try: + make_func = block.get_member('make', DoxyFunction) + make_func_name = block.name() +'::make' + # Don't want to risk writing to output twice. + if make_func_name not in make_funcs: + make_funcs.add(make_func_name) + output.append(make_block2_entry(di, block)) except block.ParsingError: - print('Parsing error for block %s' % block.name()) + sys.stderr.write('Parsing error for block {0}\n'.format(block.name())) + raise # Create docstrings for functions # Don't include the make functions since they have already been dealt with. - funcs = [f for f in di.in_category(DoxyFunction) if f.name() not in make_funcs] + funcs = [f for f in di.in_category(DoxyFunction) + if f.name() not in make_funcs and not f.name().startswith('std::')] for f in funcs: try: output.append(make_func_entry(f)) except f.ParsingError: - print('Parsing error for function %s' % f.name()) + sys.stderr.write('Parsing error for function {0}\n'.format(f.name())) # Create docstrings for classes block_names = [block.name() for block in blocks] - klasses = [k for k in di.in_category(DoxyClass) if k.name() not in block_names] + block_names += [block.name() for block in blocks2] + klasses = [k for k in di.in_category(DoxyClass) + if k.name() not in block_names and not k.name().startswith('std::')] for k in klasses: try: output.append(make_class_entry(k)) except k.ParsingError: - print('Parsing error for class %s' % k.name()) + sys.stderr.write('Parsing error for class {0}\n'.format(k.name())) # Docstrings are not created for anything that is not a function or a class. # If this excludes anything important please add it here. output = "\n\n".join(output) - swig_doc = file(swigdocfilename, 'w') + swig_doc = open(swigdocfilename, 'w') swig_doc.write(output) swig_doc.close() @@ -236,7 +313,7 @@ if __name__ == "__main__": # Parse command line options and set up doxyxml. err_msg = "Execute using: python swig_doc.py xml_path outputfilename" if len(sys.argv) != 3: - raise StandardError(err_msg) + raise Exception(err_msg) xml_path = sys.argv[1] swigdocfilename = sys.argv[2] di = DoxyIndex(xml_path) |