Added code for GNU Radio 3.10 --DOES NOT WORK YET--

This is the result of removing the entire gr-droneid folder and recreating it as a GNU Radio 3.10 OOT.  This is currently broken due to something in pybind11 not liking the utils class
gr-droneid-3.10
David Protzman 2022-09-21 23:23:29 -04:00
rodzic 33cbb9c0e1
commit 7f2e2cf6ab
58 zmienionych plików z 3879 dodań i 2884 usunięć

Wyświetl plik

@ -0,0 +1,32 @@
find_package(PkgConfig)
PKG_CHECK_MODULES(PC_GR_DRONEID gnuradio-droneid)
FIND_PATH(
GR_DRONEID_INCLUDE_DIRS
NAMES gnuradio/droneid/api.h
HINTS $ENV{DRONEID_DIR}/include
${PC_DRONEID_INCLUDEDIR}
PATHS ${CMAKE_INSTALL_PREFIX}/include
/usr/local/include
/usr/include
)
FIND_LIBRARY(
GR_DRONEID_LIBRARIES
NAMES gnuradio-droneid
HINTS $ENV{DRONEID_DIR}/lib
${PC_DRONEID_LIBDIR}
PATHS ${CMAKE_INSTALL_PREFIX}/lib
${CMAKE_INSTALL_PREFIX}/lib64
/usr/local/lib
/usr/local/lib64
/usr/lib
/usr/lib64
)
include("${CMAKE_CURRENT_LIST_DIR}/gnuradio-droneidTarget.cmake")
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GR_DRONEID DEFAULT_MSG GR_DRONEID_LIBRARIES GR_DRONEID_INCLUDE_DIRS)
MARK_AS_ADVANCED(GR_DRONEID_LIBRARIES GR_DRONEID_INCLUDE_DIRS)

Wyświetl plik

@ -3,20 +3,8 @@
# This file was generated by gr_modtool, a tool from the GNU Radio framework
# This file is a part of gr-droneid
#
# 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
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
# SPDX-License-Identifier: GPL-3.0-or-later
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
########################################################################
# Setup dependencies

Wyświetl plik

@ -9,25 +9,3 @@ in this package. A quick listing of the details can be found in Python
after importing by using:
help(droneid)
# Notes
This module is currently *very much* an Alpha. Please don't rely on it for *anything*. It tends to trail behind the MATLAB/Octave code by weeks!
It currently does some very basic functions:
- Burst detection by using cross correlating for the ZC sequence
- Burst extraction using the correlation scores from the cross correlation above (see note 1)
- Coarse CFO estimation and correction (see note 2)
- OFDM data carrier extraction
Some things still left to do:
- Channel equalization using the two ZC sequences (https://github.com/proto17/dji_droneid/blob/main/matlab/updated_scripts/process_file.m#L119-L134 and https://github.com/proto17/dji_droneid/blob/main/matlab/updated_scripts/process_file.m#L155-L166)
- Function-izing the Turbo decoder and rate matcher (https://github.com/proto17/dji_droneid/blob/main/cpp/remove_turbo.cc) and using the function(s) to deal with Turbo decoding and rate matching to output full frames
- Parse the frame to spit out something that users can actually use (maybe JSON?)
- Create a more robust timing offset estimator (likely autocorrelating the ZC sequence(s))
- Figure out how to deal with integer frequency offsets (currently just able to detect and correct for fractional offsets)
Note 1:
If there is a large enough frequency offset (on the order of KHz) then the cross correlation of the ZC sequence will produce a spike that's not actually at the start/end of the ZC sequence. It will be off by some number of samples. The issue is that the location of the spike is used to determine the start index of the burst, which will in turn determine where each OFDM symbol is assumed to start. So, having a frequency offset will cause incorrect starting sample offsets which will completely derail the OFDM symbol extraction resulting in garbage constellations
Note 2:
The current coarse CFO estimate cannot deal with very large offsets. It looks at the cyclic prefix of one of the OFDM symbols (second symbol for those signals with 9 symbols, first symbol for those with 8) which has a large gap between samples. This is more useful as a fine frequency offset than coarse. A possible alternative is to use the ZC sequence(s). They are symmetrical about the center in the time (and probably frequency?) domain which means it should autocorrelate with itself if you reverse the second half of the correlation window.

Wyświetl plik

@ -3,32 +3,21 @@
# This file was generated by gr_modtool, a tool from the GNU Radio framework
# This file is a part of gr-droneid
#
# 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
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
# SPDX-License-Identifier: GPL-3.0-or-later
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
########################################################################
# Create the doxygen configuration file
########################################################################
file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} top_srcdir)
file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} top_builddir)
file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} abs_top_srcdir)
file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} abs_top_builddir)
file(TO_NATIVE_PATH ${PROJECT_SOURCE_DIR} top_srcdir)
file(TO_NATIVE_PATH ${PROJECT_BINARY_DIR} top_builddir)
file(TO_NATIVE_PATH ${PROJECT_SOURCE_DIR} abs_top_srcdir)
file(TO_NATIVE_PATH ${PROJECT_BINARY_DIR} abs_top_builddir)
set(HAVE_DOT ${DOXYGEN_DOT_FOUND})
set(enable_html_docs YES)
set(enable_latex_docs NO)
set(enable_mathjax NO)
set(enable_xml_docs YES)
configure_file(

Wyświetl plik

@ -199,13 +199,6 @@ TAB_SIZE = 8
ALIASES =
# This tag can be used to specify a number of word-keyword mappings (TCL only).
# A mapping has the form "name=value". For example adding
# "class=itcl::class" will allow you to use the command class in the
# itcl::class meaning.
TCL_SUBST =
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
# sources only. Doxygen will then generate output that is more tailored for C.
# For instance, some of the names that are used will be different. The list
@ -723,8 +716,6 @@ EXCLUDE_PATTERNS = */.deps/* \
EXCLUDE_SYMBOLS = ad9862 \
numpy \
*swig* \
*Swig* \
*my_top_block* \
*my_graph* \
*app_top_block* \
@ -790,7 +781,7 @@ INPUT_FILTER =
# info on how filters are used. If FILTER_PATTERNS is empty or if
# non of the patterns match the file name, INPUT_FILTER is applied.
FILTER_PATTERNS = *.py="@top_srcdir@"/doc/doxygen/other/doxypy.py
FILTER_PATTERNS = *.py=@top_srcdir@/docs/doxygen/other/doxypy.py
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
# INPUT_FILTER) will be used to filter the input files when producing source
@ -879,12 +870,6 @@ VERBATIM_HEADERS = YES
ALPHABETICAL_INDEX = YES
# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
# in which this list will be split (can be a number in the range [1..20])
COLS_IN_ALPHA_INDEX = 5
# In case all classes in a project start with a common prefix, all
# classes will be put under the same header in the alphabetical index.
# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
@ -1220,14 +1205,14 @@ FORMULA_TRANSPARENT = YES
# output. When enabled you may also need to install MathJax separately and
# configure the path to it using the MATHJAX_RELPATH option.
USE_MATHJAX = NO
USE_MATHJAX = @enable_mathjax@
# When MathJax is enabled you can set the default output format to be used for
# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and
# SVG. The default value is HTML-CSS, which is slower, but has the best
# compatibility.
MATHJAX_FORMAT = HTML-CSS
MATHJAX_FORMAT = SVG
# When MathJax is enabled you need to specify the location relative to the
# HTML output directory using the MATHJAX_RELPATH option. The destination
@ -1239,12 +1224,12 @@ MATHJAX_FORMAT = HTML-CSS
# However, it is strongly recommended to install a local
# copy of MathJax from http://www.mathjax.org before deployment.
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
MATHJAX_RELPATH = @MATHJAX2_PATH@
# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
# names that should be enabled during MathJax rendering.
MATHJAX_EXTENSIONS =
MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript
# pieces of code that will be used on startup of the MathJax code.
@ -1680,11 +1665,6 @@ EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of `which perl').
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
@ -1697,15 +1677,6 @@ PERL_PATH = /usr/bin/perl
CLASS_DIAGRAMS = YES
# You can define message sequence charts within doxygen comments using the \msc
# command. Doxygen will then run the mscgen tool (see
# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
# the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path.
MSCGEN_PATH =
# If set to YES, the inheritance and collaboration graphs will hide
# inheritance and usage relations if the target is undocumented
# or is not a class.
@ -1834,7 +1805,7 @@ DIRECTORY_GRAPH = YES
# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
# visible in IE 9+ (other browsers do not have this requirement).
DOT_IMAGE_FORMAT = png
DOT_IMAGE_FORMAT = svg
# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
# enable generation of interactive SVG images that allow zooming and panning.

Wyświetl plik

@ -4,20 +4,8 @@
# This file was generated by gr_modtool, a tool from the GNU Radio framework
# This file is a part of gr-droneid
#
# 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
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
# SPDX-License-Identifier: GPL-3.0-or-later
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
"""
Python interface to contents of doxygen xml documentation.
@ -64,10 +52,10 @@ This line is uninformative and is only to test line breaks in the comments.
u'Outputs the vital aadvark statistics.'
"""
from __future__ import unicode_literals
from .doxyindex import DoxyIndex, DoxyFunction, DoxyParam, DoxyClass, DoxyFile, DoxyNamespace, DoxyGroup, DoxyFriend, DoxyOther
def _test():
import os
this_dir = os.path.dirname(globals()['__file__'])
@ -79,6 +67,6 @@ def _test():
import doctest
return doctest.testmod()
if __name__ == "__main__":
_test()

Wyświetl plik

@ -4,20 +4,8 @@
# This file was generated by gr_modtool, a tool from the GNU Radio framework
# This file is a part of gr-droneid
#
# 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
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
# SPDX-License-Identifier: GPL-3.0-or-later
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
"""
A base class is created.
@ -25,8 +13,6 @@ A base class is created.
Classes based upon this are used to make more user-friendly interfaces
to the doxygen xml docs than the generated classes provide.
"""
from __future__ import print_function
from __future__ import unicode_literals
import os
import pdb
@ -97,8 +83,8 @@ class Base(object):
for cls in self.mem_classes:
if cls.can_parse(mem):
return cls
raise Exception(("Did not find a class for object '%s'." \
% (mem.get_name())))
raise Exception(("Did not find a class for object '%s'."
% (mem.get_name())))
def convert_mem(self, mem):
try:

Wyświetl plik

@ -4,27 +4,13 @@
# This file was generated by gr_modtool, a tool from the GNU Radio framework
# This file is a part of gr-droneid
#
# 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
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
# SPDX-License-Identifier: GPL-3.0-or-later
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
"""
Classes providing more user-friendly interfaces to the doxygen xml
docs than the generated classes provide.
"""
from __future__ import absolute_import
from __future__ import unicode_literals
import os
@ -32,6 +18,7 @@ from .generated import index
from .base import Base
from .text import description
class DoxyIndex(Base):
"""
Parses a doxygen xml directory.
@ -60,17 +47,8 @@ class DoxyIndex(Base):
self._members.append(converted)
def generate_swig_doc_i(self):
"""
%feature("docstring") gr_make_align_on_samplenumbers_ss::align_state "
Wraps the C++: gr_align_on_samplenumbers_ss::align_state";
"""
pass
class DoxyCompMem(Base):
kind = None
def __init__(self, *args, **kwargs):
@ -106,9 +84,11 @@ class DoxyCompMem(Base):
class DoxyCompound(DoxyCompMem):
pass
class DoxyMember(DoxyCompMem):
pass
class DoxyFunction(DoxyMember):
__module__ = "gnuradio.utils.doxyxml"
@ -129,9 +109,11 @@ class DoxyFunction(DoxyMember):
self._data['params'].append(DoxyParam(prm))
brief_description = property(lambda self: self.data()['brief_description'])
detailed_description = property(lambda self: self.data()['detailed_description'])
detailed_description = property(
lambda self: self.data()['detailed_description'])
params = property(lambda self: self.data()['params'])
Base.mem_classes.append(DoxyFunction)
@ -156,9 +138,11 @@ class DoxyParam(DoxyMember):
return '\n\n'.join(descriptions)
brief_description = property(lambda self: self.data()['brief_description'])
detailed_description = property(lambda self: self.data()['detailed_description'])
detailed_description = property(
lambda self: self.data()['detailed_description'])
name = property(lambda self: self.data()['declname'])
class DoxyParameterItem(DoxyMember):
"""A different representation of a parameter in Doxygen."""
@ -200,9 +184,11 @@ class DoxyClass(DoxyCompound):
self.process_memberdefs()
brief_description = property(lambda self: self.data()['brief_description'])
detailed_description = property(lambda self: self.data()['detailed_description'])
detailed_description = property(
lambda self: self.data()['detailed_description'])
params = property(lambda self: self.data()['params'])
Base.mem_classes.append(DoxyClass)
@ -223,7 +209,9 @@ class DoxyFile(DoxyCompound):
self.process_memberdefs()
brief_description = property(lambda self: self.data()['brief_description'])
detailed_description = property(lambda self: self.data()['detailed_description'])
detailed_description = property(
lambda self: self.data()['detailed_description'])
Base.mem_classes.append(DoxyFile)
@ -244,6 +232,7 @@ class DoxyNamespace(DoxyCompound):
return
self.process_memberdefs()
Base.mem_classes.append(DoxyNamespace)
@ -287,6 +276,7 @@ class DoxyFriend(DoxyMember):
kind = 'friend'
Base.mem_classes.append(DoxyFriend)
@ -301,4 +291,5 @@ class DoxyOther(Base):
def can_parse(cls, obj):
return obj.kind in cls.kinds
Base.mem_classes.append(DoxyOther)

Wyświetl plik

@ -5,4 +5,3 @@ These do the real work of parsing the doxygen xml files but the
resultant classes are not very friendly to navigate so the rest of the
doxyxml module processes them further.
"""
from __future__ import unicode_literals

Wyświetl plik

@ -3,8 +3,6 @@
"""
Generated Mon Feb 9 19:08:05 2009 by generateDS.py.
"""
from __future__ import absolute_import
from __future__ import unicode_literals
from xml.dom import minidom
@ -24,13 +22,15 @@ class DoxygenTypeSub(supermod.DoxygenType):
return self.compounddef.find(details)
supermod.DoxygenType.subclass = DoxygenTypeSub
# end class DoxygenTypeSub
class compounddefTypeSub(supermod.compounddefType):
def __init__(self, kind=None, prot=None, id=None, compoundname='', title='', basecompoundref=None, derivedcompoundref=None, includes=None, includedby=None, incdepgraph=None, invincdepgraph=None, innerdir=None, innerfile=None, innerclass=None, innernamespace=None, innerpage=None, innergroup=None, templateparamlist=None, sectiondef=None, briefdescription=None, detaileddescription=None, inheritancegraph=None, collaborationgraph=None, programlisting=None, location=None, listofallmembers=None):
supermod.compounddefType.__init__(self, kind, prot, id, compoundname, title, basecompoundref, derivedcompoundref, includes, includedby, incdepgraph, invincdepgraph, innerdir, innerfile, innerclass, innernamespace, innerpage, innergroup, templateparamlist, sectiondef, briefdescription, detaileddescription, inheritancegraph, collaborationgraph, programlisting, location, listofallmembers)
supermod.compounddefType.__init__(self, kind, prot, id, compoundname, title, basecompoundref, derivedcompoundref, includes, includedby, incdepgraph, invincdepgraph, innerdir, innerfile, innerclass,
innernamespace, innerpage, innergroup, templateparamlist, sectiondef, briefdescription, detaileddescription, inheritancegraph, collaborationgraph, programlisting, location, listofallmembers)
def find(self, details):
@ -50,13 +50,18 @@ supermod.compounddefType.subclass = compounddefTypeSub
class listofallmembersTypeSub(supermod.listofallmembersType):
def __init__(self, member=None):
supermod.listofallmembersType.__init__(self, member)
supermod.listofallmembersType.subclass = listofallmembersTypeSub
# end class listofallmembersTypeSub
class memberRefTypeSub(supermod.memberRefType):
def __init__(self, virt=None, prot=None, refid=None, ambiguityscope=None, scope='', name=''):
supermod.memberRefType.__init__(self, virt, prot, refid, ambiguityscope, scope, name)
supermod.memberRefType.__init__(
self, virt, prot, refid, ambiguityscope, scope, name)
supermod.memberRefType.subclass = memberRefTypeSub
# end class memberRefTypeSub
@ -64,6 +69,8 @@ supermod.memberRefType.subclass = memberRefTypeSub
class compoundRefTypeSub(supermod.compoundRefType):
def __init__(self, virt=None, prot=None, refid=None, valueOf_='', mixedclass_=None, content_=None):
supermod.compoundRefType.__init__(self, mixedclass_, content_)
supermod.compoundRefType.subclass = compoundRefTypeSub
# end class compoundRefTypeSub
@ -71,6 +78,8 @@ supermod.compoundRefType.subclass = compoundRefTypeSub
class reimplementTypeSub(supermod.reimplementType):
def __init__(self, refid=None, valueOf_='', mixedclass_=None, content_=None):
supermod.reimplementType.__init__(self, mixedclass_, content_)
supermod.reimplementType.subclass = reimplementTypeSub
# end class reimplementTypeSub
@ -78,6 +87,8 @@ supermod.reimplementType.subclass = reimplementTypeSub
class incTypeSub(supermod.incType):
def __init__(self, local=None, refid=None, valueOf_='', mixedclass_=None, content_=None):
supermod.incType.__init__(self, mixedclass_, content_)
supermod.incType.subclass = incTypeSub
# end class incTypeSub
@ -85,23 +96,26 @@ supermod.incType.subclass = incTypeSub
class refTypeSub(supermod.refType):
def __init__(self, prot=None, refid=None, valueOf_='', mixedclass_=None, content_=None):
supermod.refType.__init__(self, mixedclass_, content_)
supermod.refType.subclass = refTypeSub
# end class refTypeSub
class refTextTypeSub(supermod.refTextType):
def __init__(self, refid=None, kindref=None, external=None, valueOf_='', mixedclass_=None, content_=None):
supermod.refTextType.__init__(self, mixedclass_, content_)
supermod.refTextType.subclass = refTextTypeSub
# end class refTextTypeSub
class sectiondefTypeSub(supermod.sectiondefType):
def __init__(self, kind=None, header='', description=None, memberdef=None):
supermod.sectiondefType.__init__(self, kind, header, description, memberdef)
supermod.sectiondefType.__init__(
self, kind, header, description, memberdef)
def find(self, details):
@ -118,7 +132,10 @@ supermod.sectiondefType.subclass = sectiondefTypeSub
class memberdefTypeSub(supermod.memberdefType):
def __init__(self, initonly=None, kind=None, volatile=None, const=None, raise_=None, virt=None, readable=None, prot=None, explicit=None, new=None, final=None, writable=None, add=None, static=None, remove=None, sealed=None, mutable=None, gettable=None, inline=None, settable=None, id=None, templateparamlist=None, type_=None, definition='', argsstring='', name='', read='', write='', bitfield='', reimplements=None, reimplementedby=None, param=None, enumvalue=None, initializer=None, exceptions=None, briefdescription=None, detaileddescription=None, inbodydescription=None, location=None, references=None, referencedby=None):
supermod.memberdefType.__init__(self, initonly, kind, volatile, const, raise_, virt, readable, prot, explicit, new, final, writable, add, static, remove, sealed, mutable, gettable, inline, settable, id, templateparamlist, type_, definition, argsstring, name, read, write, bitfield, reimplements, reimplementedby, param, enumvalue, initializer, exceptions, briefdescription, detaileddescription, inbodydescription, location, references, referencedby)
supermod.memberdefType.__init__(self, initonly, kind, volatile, const, raise_, virt, readable, prot, explicit, new, final, writable, add, static, remove, sealed, mutable, gettable, inline, settable, id, templateparamlist, type_,
definition, argsstring, name, read, write, bitfield, reimplements, reimplementedby, param, enumvalue, initializer, exceptions, briefdescription, detaileddescription, inbodydescription, location, references, referencedby)
supermod.memberdefType.subclass = memberdefTypeSub
# end class memberdefTypeSub
@ -126,6 +143,8 @@ supermod.memberdefType.subclass = memberdefTypeSub
class descriptionTypeSub(supermod.descriptionType):
def __init__(self, title='', para=None, sect1=None, internal=None, mixedclass_=None, content_=None):
supermod.descriptionType.__init__(self, mixedclass_, content_)
supermod.descriptionType.subclass = descriptionTypeSub
# end class descriptionTypeSub
@ -133,6 +152,8 @@ supermod.descriptionType.subclass = descriptionTypeSub
class enumvalueTypeSub(supermod.enumvalueType):
def __init__(self, prot=None, id=None, name='', initializer=None, briefdescription=None, detaileddescription=None, mixedclass_=None, content_=None):
supermod.enumvalueType.__init__(self, mixedclass_, content_)
supermod.enumvalueType.subclass = enumvalueTypeSub
# end class enumvalueTypeSub
@ -140,13 +161,18 @@ supermod.enumvalueType.subclass = enumvalueTypeSub
class templateparamlistTypeSub(supermod.templateparamlistType):
def __init__(self, param=None):
supermod.templateparamlistType.__init__(self, param)
supermod.templateparamlistType.subclass = templateparamlistTypeSub
# end class templateparamlistTypeSub
class paramTypeSub(supermod.paramType):
def __init__(self, type_=None, declname='', defname='', array='', defval=None, briefdescription=None):
supermod.paramType.__init__(self, type_, declname, defname, array, defval, briefdescription)
supermod.paramType.__init__(
self, type_, declname, defname, array, defval, briefdescription)
supermod.paramType.subclass = paramTypeSub
# end class paramTypeSub
@ -154,6 +180,8 @@ supermod.paramType.subclass = paramTypeSub
class linkedTextTypeSub(supermod.linkedTextType):
def __init__(self, ref=None, mixedclass_=None, content_=None):
supermod.linkedTextType.__init__(self, mixedclass_, content_)
supermod.linkedTextType.subclass = linkedTextTypeSub
# end class linkedTextTypeSub
@ -161,6 +189,8 @@ supermod.linkedTextType.subclass = linkedTextTypeSub
class graphTypeSub(supermod.graphType):
def __init__(self, node=None):
supermod.graphType.__init__(self, node)
supermod.graphType.subclass = graphTypeSub
# end class graphTypeSub
@ -168,6 +198,8 @@ supermod.graphType.subclass = graphTypeSub
class nodeTypeSub(supermod.nodeType):
def __init__(self, id=None, label='', link=None, childnode=None):
supermod.nodeType.__init__(self, id, label, link, childnode)
supermod.nodeType.subclass = nodeTypeSub
# end class nodeTypeSub
@ -175,6 +207,8 @@ supermod.nodeType.subclass = nodeTypeSub
class childnodeTypeSub(supermod.childnodeType):
def __init__(self, relation=None, refid=None, edgelabel=None):
supermod.childnodeType.__init__(self, relation, refid, edgelabel)
supermod.childnodeType.subclass = childnodeTypeSub
# end class childnodeTypeSub
@ -182,6 +216,8 @@ supermod.childnodeType.subclass = childnodeTypeSub
class linkTypeSub(supermod.linkType):
def __init__(self, refid=None, external=None, valueOf_=''):
supermod.linkType.__init__(self, refid, external)
supermod.linkType.subclass = linkTypeSub
# end class linkTypeSub
@ -189,13 +225,18 @@ supermod.linkType.subclass = linkTypeSub
class listingTypeSub(supermod.listingType):
def __init__(self, codeline=None):
supermod.listingType.__init__(self, codeline)
supermod.listingType.subclass = listingTypeSub
# end class listingTypeSub
class codelineTypeSub(supermod.codelineType):
def __init__(self, external=None, lineno=None, refkind=None, refid=None, highlight=None):
supermod.codelineType.__init__(self, external, lineno, refkind, refid, highlight)
supermod.codelineType.__init__(
self, external, lineno, refkind, refid, highlight)
supermod.codelineType.subclass = codelineTypeSub
# end class codelineTypeSub
@ -203,6 +244,8 @@ supermod.codelineType.subclass = codelineTypeSub
class highlightTypeSub(supermod.highlightType):
def __init__(self, class_=None, sp=None, ref=None, mixedclass_=None, content_=None):
supermod.highlightType.__init__(self, mixedclass_, content_)
supermod.highlightType.subclass = highlightTypeSub
# end class highlightTypeSub
@ -210,13 +253,18 @@ supermod.highlightType.subclass = highlightTypeSub
class referenceTypeSub(supermod.referenceType):
def __init__(self, endline=None, startline=None, refid=None, compoundref=None, valueOf_='', mixedclass_=None, content_=None):
supermod.referenceType.__init__(self, mixedclass_, content_)
supermod.referenceType.subclass = referenceTypeSub
# end class referenceTypeSub
class locationTypeSub(supermod.locationType):
def __init__(self, bodystart=None, line=None, bodyend=None, bodyfile=None, file=None, valueOf_=''):
supermod.locationType.__init__(self, bodystart, line, bodyend, bodyfile, file)
supermod.locationType.__init__(
self, bodystart, line, bodyend, bodyfile, file)
supermod.locationType.subclass = locationTypeSub
# end class locationTypeSub
@ -224,6 +272,8 @@ supermod.locationType.subclass = locationTypeSub
class docSect1TypeSub(supermod.docSect1Type):
def __init__(self, id=None, title='', para=None, sect2=None, internal=None, mixedclass_=None, content_=None):
supermod.docSect1Type.__init__(self, mixedclass_, content_)
supermod.docSect1Type.subclass = docSect1TypeSub
# end class docSect1TypeSub
@ -231,6 +281,8 @@ supermod.docSect1Type.subclass = docSect1TypeSub
class docSect2TypeSub(supermod.docSect2Type):
def __init__(self, id=None, title='', para=None, sect3=None, internal=None, mixedclass_=None, content_=None):
supermod.docSect2Type.__init__(self, mixedclass_, content_)
supermod.docSect2Type.subclass = docSect2TypeSub
# end class docSect2TypeSub
@ -238,6 +290,8 @@ supermod.docSect2Type.subclass = docSect2TypeSub
class docSect3TypeSub(supermod.docSect3Type):
def __init__(self, id=None, title='', para=None, sect4=None, internal=None, mixedclass_=None, content_=None):
supermod.docSect3Type.__init__(self, mixedclass_, content_)
supermod.docSect3Type.subclass = docSect3TypeSub
# end class docSect3TypeSub
@ -245,6 +299,8 @@ supermod.docSect3Type.subclass = docSect3TypeSub
class docSect4TypeSub(supermod.docSect4Type):
def __init__(self, id=None, title='', para=None, internal=None, mixedclass_=None, content_=None):
supermod.docSect4Type.__init__(self, mixedclass_, content_)
supermod.docSect4Type.subclass = docSect4TypeSub
# end class docSect4TypeSub
@ -252,6 +308,8 @@ supermod.docSect4Type.subclass = docSect4TypeSub
class docInternalTypeSub(supermod.docInternalType):
def __init__(self, para=None, sect1=None, mixedclass_=None, content_=None):
supermod.docInternalType.__init__(self, mixedclass_, content_)
supermod.docInternalType.subclass = docInternalTypeSub
# end class docInternalTypeSub
@ -259,6 +317,8 @@ supermod.docInternalType.subclass = docInternalTypeSub
class docInternalS1TypeSub(supermod.docInternalS1Type):
def __init__(self, para=None, sect2=None, mixedclass_=None, content_=None):
supermod.docInternalS1Type.__init__(self, mixedclass_, content_)
supermod.docInternalS1Type.subclass = docInternalS1TypeSub
# end class docInternalS1TypeSub
@ -266,6 +326,8 @@ supermod.docInternalS1Type.subclass = docInternalS1TypeSub
class docInternalS2TypeSub(supermod.docInternalS2Type):
def __init__(self, para=None, sect3=None, mixedclass_=None, content_=None):
supermod.docInternalS2Type.__init__(self, mixedclass_, content_)
supermod.docInternalS2Type.subclass = docInternalS2TypeSub
# end class docInternalS2TypeSub
@ -273,6 +335,8 @@ supermod.docInternalS2Type.subclass = docInternalS2TypeSub
class docInternalS3TypeSub(supermod.docInternalS3Type):
def __init__(self, para=None, sect3=None, mixedclass_=None, content_=None):
supermod.docInternalS3Type.__init__(self, mixedclass_, content_)
supermod.docInternalS3Type.subclass = docInternalS3TypeSub
# end class docInternalS3TypeSub
@ -280,6 +344,8 @@ supermod.docInternalS3Type.subclass = docInternalS3TypeSub
class docInternalS4TypeSub(supermod.docInternalS4Type):
def __init__(self, para=None, mixedclass_=None, content_=None):
supermod.docInternalS4Type.__init__(self, mixedclass_, content_)
supermod.docInternalS4Type.subclass = docInternalS4TypeSub
# end class docInternalS4TypeSub
@ -287,6 +353,8 @@ supermod.docInternalS4Type.subclass = docInternalS4TypeSub
class docURLLinkSub(supermod.docURLLink):
def __init__(self, url=None, valueOf_='', mixedclass_=None, content_=None):
supermod.docURLLink.__init__(self, mixedclass_, content_)
supermod.docURLLink.subclass = docURLLinkSub
# end class docURLLinkSub
@ -294,6 +362,8 @@ supermod.docURLLink.subclass = docURLLinkSub
class docAnchorTypeSub(supermod.docAnchorType):
def __init__(self, id=None, valueOf_='', mixedclass_=None, content_=None):
supermod.docAnchorType.__init__(self, mixedclass_, content_)
supermod.docAnchorType.subclass = docAnchorTypeSub
# end class docAnchorTypeSub
@ -301,6 +371,8 @@ supermod.docAnchorType.subclass = docAnchorTypeSub
class docFormulaTypeSub(supermod.docFormulaType):
def __init__(self, id=None, valueOf_='', mixedclass_=None, content_=None):
supermod.docFormulaType.__init__(self, mixedclass_, content_)
supermod.docFormulaType.subclass = docFormulaTypeSub
# end class docFormulaTypeSub
@ -308,6 +380,8 @@ supermod.docFormulaType.subclass = docFormulaTypeSub
class docIndexEntryTypeSub(supermod.docIndexEntryType):
def __init__(self, primaryie='', secondaryie=''):
supermod.docIndexEntryType.__init__(self, primaryie, secondaryie)
supermod.docIndexEntryType.subclass = docIndexEntryTypeSub
# end class docIndexEntryTypeSub
@ -315,6 +389,8 @@ supermod.docIndexEntryType.subclass = docIndexEntryTypeSub
class docListTypeSub(supermod.docListType):
def __init__(self, listitem=None):
supermod.docListType.__init__(self, listitem)
supermod.docListType.subclass = docListTypeSub
# end class docListTypeSub
@ -322,6 +398,8 @@ supermod.docListType.subclass = docListTypeSub
class docListItemTypeSub(supermod.docListItemType):
def __init__(self, para=None):
supermod.docListItemType.__init__(self, para)
supermod.docListItemType.subclass = docListItemTypeSub
# end class docListItemTypeSub
@ -329,6 +407,8 @@ supermod.docListItemType.subclass = docListItemTypeSub
class docSimpleSectTypeSub(supermod.docSimpleSectType):
def __init__(self, kind=None, title=None, para=None):
supermod.docSimpleSectType.__init__(self, kind, title, para)
supermod.docSimpleSectType.subclass = docSimpleSectTypeSub
# end class docSimpleSectTypeSub
@ -336,6 +416,8 @@ supermod.docSimpleSectType.subclass = docSimpleSectTypeSub
class docVarListEntryTypeSub(supermod.docVarListEntryType):
def __init__(self, term=None):
supermod.docVarListEntryType.__init__(self, term)
supermod.docVarListEntryType.subclass = docVarListEntryTypeSub
# end class docVarListEntryTypeSub
@ -343,6 +425,8 @@ supermod.docVarListEntryType.subclass = docVarListEntryTypeSub
class docRefTextTypeSub(supermod.docRefTextType):
def __init__(self, refid=None, kindref=None, external=None, valueOf_='', mixedclass_=None, content_=None):
supermod.docRefTextType.__init__(self, mixedclass_, content_)
supermod.docRefTextType.subclass = docRefTextTypeSub
# end class docRefTextTypeSub
@ -350,6 +434,8 @@ supermod.docRefTextType.subclass = docRefTextTypeSub
class docTableTypeSub(supermod.docTableType):
def __init__(self, rows=None, cols=None, row=None, caption=None):
supermod.docTableType.__init__(self, rows, cols, row, caption)
supermod.docTableType.subclass = docTableTypeSub
# end class docTableTypeSub
@ -357,6 +443,8 @@ supermod.docTableType.subclass = docTableTypeSub
class docRowTypeSub(supermod.docRowType):
def __init__(self, entry=None):
supermod.docRowType.__init__(self, entry)
supermod.docRowType.subclass = docRowTypeSub
# end class docRowTypeSub
@ -364,6 +452,8 @@ supermod.docRowType.subclass = docRowTypeSub
class docEntryTypeSub(supermod.docEntryType):
def __init__(self, thead=None, para=None):
supermod.docEntryType.__init__(self, thead, para)
supermod.docEntryType.subclass = docEntryTypeSub
# end class docEntryTypeSub
@ -371,6 +461,8 @@ supermod.docEntryType.subclass = docEntryTypeSub
class docHeadingTypeSub(supermod.docHeadingType):
def __init__(self, level=None, valueOf_='', mixedclass_=None, content_=None):
supermod.docHeadingType.__init__(self, mixedclass_, content_)
supermod.docHeadingType.subclass = docHeadingTypeSub
# end class docHeadingTypeSub
@ -378,6 +470,8 @@ supermod.docHeadingType.subclass = docHeadingTypeSub
class docImageTypeSub(supermod.docImageType):
def __init__(self, width=None, type_=None, name=None, height=None, valueOf_='', mixedclass_=None, content_=None):
supermod.docImageType.__init__(self, mixedclass_, content_)
supermod.docImageType.subclass = docImageTypeSub
# end class docImageTypeSub
@ -385,6 +479,8 @@ supermod.docImageType.subclass = docImageTypeSub
class docDotFileTypeSub(supermod.docDotFileType):
def __init__(self, name=None, valueOf_='', mixedclass_=None, content_=None):
supermod.docDotFileType.__init__(self, mixedclass_, content_)
supermod.docDotFileType.subclass = docDotFileTypeSub
# end class docDotFileTypeSub
@ -392,6 +488,8 @@ supermod.docDotFileType.subclass = docDotFileTypeSub
class docTocItemTypeSub(supermod.docTocItemType):
def __init__(self, id=None, valueOf_='', mixedclass_=None, content_=None):
supermod.docTocItemType.__init__(self, mixedclass_, content_)
supermod.docTocItemType.subclass = docTocItemTypeSub
# end class docTocItemTypeSub
@ -399,6 +497,8 @@ supermod.docTocItemType.subclass = docTocItemTypeSub
class docTocListTypeSub(supermod.docTocListType):
def __init__(self, tocitem=None):
supermod.docTocListType.__init__(self, tocitem)
supermod.docTocListType.subclass = docTocListTypeSub
# end class docTocListTypeSub
@ -406,6 +506,8 @@ supermod.docTocListType.subclass = docTocListTypeSub
class docLanguageTypeSub(supermod.docLanguageType):
def __init__(self, langid=None, para=None):
supermod.docLanguageType.__init__(self, langid, para)
supermod.docLanguageType.subclass = docLanguageTypeSub
# end class docLanguageTypeSub
@ -413,13 +515,18 @@ supermod.docLanguageType.subclass = docLanguageTypeSub
class docParamListTypeSub(supermod.docParamListType):
def __init__(self, kind=None, parameteritem=None):
supermod.docParamListType.__init__(self, kind, parameteritem)
supermod.docParamListType.subclass = docParamListTypeSub
# end class docParamListTypeSub
class docParamListItemSub(supermod.docParamListItem):
def __init__(self, parameternamelist=None, parameterdescription=None):
supermod.docParamListItem.__init__(self, parameternamelist, parameterdescription)
supermod.docParamListItem.__init__(
self, parameternamelist, parameterdescription)
supermod.docParamListItem.subclass = docParamListItemSub
# end class docParamListItemSub
@ -427,6 +534,8 @@ supermod.docParamListItem.subclass = docParamListItemSub
class docParamNameListSub(supermod.docParamNameList):
def __init__(self, parametername=None):
supermod.docParamNameList.__init__(self, parametername)
supermod.docParamNameList.subclass = docParamNameListSub
# end class docParamNameListSub
@ -434,6 +543,8 @@ supermod.docParamNameList.subclass = docParamNameListSub
class docParamNameSub(supermod.docParamName):
def __init__(self, direction=None, ref=None, mixedclass_=None, content_=None):
supermod.docParamName.__init__(self, mixedclass_, content_)
supermod.docParamName.subclass = docParamNameSub
# end class docParamNameSub
@ -441,6 +552,8 @@ supermod.docParamName.subclass = docParamNameSub
class docXRefSectTypeSub(supermod.docXRefSectType):
def __init__(self, id=None, xreftitle=None, xrefdescription=None):
supermod.docXRefSectType.__init__(self, id, xreftitle, xrefdescription)
supermod.docXRefSectType.subclass = docXRefSectTypeSub
# end class docXRefSectTypeSub
@ -448,6 +561,8 @@ supermod.docXRefSectType.subclass = docXRefSectTypeSub
class docCopyTypeSub(supermod.docCopyType):
def __init__(self, link=None, para=None, sect1=None, internal=None):
supermod.docCopyType.__init__(self, link, para, sect1, internal)
supermod.docCopyType.subclass = docCopyTypeSub
# end class docCopyTypeSub
@ -455,9 +570,12 @@ supermod.docCopyType.subclass = docCopyTypeSub
class docCharTypeSub(supermod.docCharType):
def __init__(self, char=None, valueOf_=''):
supermod.docCharType.__init__(self, char)
supermod.docCharType.subclass = docCharTypeSub
# end class docCharTypeSub
class docParaTypeSub(supermod.docParaType):
def __init__(self, char=None, valueOf_=''):
supermod.docParaType.__init__(self, char)
@ -471,7 +589,7 @@ class docParaTypeSub(supermod.docParaType):
if child_.nodeType == Node.TEXT_NODE:
obj_ = self.mixedclass_(MixedContainer.CategoryText,
MixedContainer.TypeNone, '', child_.nodeValue)
MixedContainer.TypeNone, '', child_.nodeValue)
self.content.append(obj_)
elif child_.nodeType == Node.ELEMENT_NODE and \
nodeName_ == "ref":
@ -494,12 +612,9 @@ supermod.docParaType.subclass = docParaTypeSub
# end class docParaTypeSub
def parse(inFilename):
doc = minidom.parse(inFilename)
rootNode = doc.documentElement
rootObj = supermod.DoxygenType.factory()
rootObj.build(rootNode)
return rootObj

Wyświetl plik

@ -3,8 +3,6 @@
"""
Generated Mon Feb 9 19:08:05 2009 by generateDS.py.
"""
from __future__ import absolute_import
from __future__ import unicode_literals
from xml.dom import minidom
@ -14,6 +12,7 @@ from . import compound
from . import indexsuper as supermod
class DoxygenTypeSub(supermod.DoxygenType):
def __init__(self, version=None, compound=None):
supermod.DoxygenType.__init__(self, version, compound)
@ -34,6 +33,7 @@ class DoxygenTypeSub(supermod.DoxygenType):
return results
supermod.DoxygenType.subclass = DoxygenTypeSub
# end class DoxygenTypeSub
@ -55,6 +55,7 @@ class CompoundTypeSub(supermod.CompoundType):
return results
supermod.CompoundType.subclass = CompoundTypeSub
# end class CompoundTypeSub
@ -64,6 +65,7 @@ class MemberTypeSub(supermod.MemberType):
def __init__(self, kind=None, refid=None, name=''):
supermod.MemberType.__init__(self, kind, refid, name)
supermod.MemberType.subclass = MemberTypeSub
# end class MemberTypeSub
@ -76,4 +78,3 @@ def parse(inFilename):
rootObj.build(rootNode)
return rootObj

Wyświetl plik

@ -4,16 +4,12 @@
# Generated Thu Jun 11 18:43:54 2009 by generateDS.py.
#
from __future__ import print_function
from __future__ import unicode_literals
import sys
from xml.dom import minidom
from xml.dom import Node
import six
#
# User methods
#
@ -28,12 +24,16 @@ except ImportError as exp:
class GeneratedsSuper(object):
def format_string(self, input_data, input_name=''):
return input_data
def format_integer(self, input_data, input_name=''):
return '%d' % input_data
def format_float(self, input_data, input_name=''):
return '%f' % input_data
def format_double(self, input_data, input_name=''):
return '%e' % input_data
def format_boolean(self, input_data, input_name=''):
return '%s' % input_data
@ -45,9 +45,9 @@ except ImportError as exp:
## from IPython.Shell import IPShellEmbed
## args = ''
## ipshell = IPShellEmbed(args,
# ipshell = IPShellEmbed(args,
## banner = 'Dropping into IPython',
## exit_msg = 'Leaving Interpreter, back to program.')
# exit_msg = 'Leaving Interpreter, back to program.')
# Then use the following line where and when you want to drop into the
# IPython shell:
@ -63,20 +63,23 @@ ExternalEncoding = 'ascii'
# Support/utility functions.
#
def showIndent(outfile, level):
for idx in range(level):
outfile.write(' ')
def quote_xml(inStr):
s1 = (isinstance(inStr, six.string_types) and inStr or
s1 = (isinstance(inStr, str) and inStr or
'%s' % inStr)
s1 = s1.replace('&', '&')
s1 = s1.replace('<', '&lt;')
s1 = s1.replace('>', '&gt;')
return s1
def quote_attrib(inStr):
s1 = (isinstance(inStr, six.string_types) and inStr or
s1 = (isinstance(inStr, str) and inStr or
'%s' % inStr)
s1 = s1.replace('&', '&amp;')
s1 = s1.replace('<', '&lt;')
@ -90,6 +93,7 @@ def quote_attrib(inStr):
s1 = '"%s"' % s1
return s1
def quote_python(inStr):
s1 = inStr
if s1.find("'") == -1:
@ -121,26 +125,33 @@ class MixedContainer(object):
TypeDecimal = 5
TypeDouble = 6
TypeBoolean = 7
def __init__(self, category, content_type, name, value):
self.category = category
self.content_type = content_type
self.name = name
self.value = value
def getCategory(self):
return self.category
def getContenttype(self, content_type):
return self.content_type
def getValue(self):
return self.value
def getName(self):
return self.name
def export(self, outfile, level, name, namespace):
if self.category == MixedContainer.CategoryText:
outfile.write(self.value)
elif self.category == MixedContainer.CategorySimple:
self.exportSimple(outfile, level, name)
else: # category == MixedContainer.CategoryComplex
self.value.export(outfile, level, namespace,name)
self.value.export(outfile, level, namespace, name)
def exportSimple(self, outfile, level, name):
if self.content_type == MixedContainer.TypeString:
outfile.write('<%s>%s</%s>' % (self.name, self.value, self.name))
@ -152,19 +163,20 @@ class MixedContainer(object):
outfile.write('<%s>%f</%s>' % (self.name, self.value, self.name))
elif self.content_type == MixedContainer.TypeDouble:
outfile.write('<%s>%g</%s>' % (self.name, self.value, self.name))
def exportLiteral(self, outfile, level, name):
if self.category == MixedContainer.CategoryText:
showIndent(outfile, level)
outfile.write('MixedContainer(%d, %d, "%s", "%s"),\n' % \
(self.category, self.content_type, self.name, self.value))
outfile.write('MixedContainer(%d, %d, "%s", "%s"),\n' %
(self.category, self.content_type, self.name, self.value))
elif self.category == MixedContainer.CategorySimple:
showIndent(outfile, level)
outfile.write('MixedContainer(%d, %d, "%s", "%s"),\n' % \
(self.category, self.content_type, self.name, self.value))
outfile.write('MixedContainer(%d, %d, "%s", "%s"),\n' %
(self.category, self.content_type, self.name, self.value))
else: # category == MixedContainer.CategoryComplex
showIndent(outfile, level)
outfile.write('MixedContainer(%d, %d, "%s",\n' % \
(self.category, self.content_type, self.name,))
outfile.write('MixedContainer(%d, %d, "%s",\n' %
(self.category, self.content_type, self.name,))
self.value.exportLiteral(outfile, level + 1)
showIndent(outfile, level)
outfile.write(')\n')
@ -175,6 +187,7 @@ class _MemberSpec(object):
self.name = name
self.data_type = data_type
self.container = container
def set_name(self, name): self.name = name
def get_name(self): return self.name
def set_data_type(self, data_type): self.data_type = data_type
@ -190,12 +203,14 @@ class _MemberSpec(object):
class DoxygenType(GeneratedsSuper):
subclass = None
superclass = None
def __init__(self, version=None, compound=None):
self.version = version
if compound is None:
self.compound = []
else:
self.compound = compound
def factory(*args_, **kwargs_):
if DoxygenType.subclass:
return DoxygenType.subclass(*args_, **kwargs_)
@ -208,6 +223,7 @@ class DoxygenType(GeneratedsSuper):
def insert_compound(self, index, value): self.compound[index] = value
def get_version(self): return self.version
def set_version(self, version): self.version = version
def export(self, outfile, level, namespace_='', name_='DoxygenType', namespacedef_=''):
showIndent(outfile, level)
outfile.write('<%s%s %s' % (namespace_, name_, namespacedef_, ))
@ -219,27 +235,34 @@ class DoxygenType(GeneratedsSuper):
outfile.write('</%s%s>\n' % (namespace_, name_))
else:
outfile.write(' />\n')
def exportAttributes(self, outfile, level, namespace_='', name_='DoxygenType'):
outfile.write(' version=%s' % (self.format_string(quote_attrib(self.version).encode(ExternalEncoding), input_name='version'), ))
outfile.write(' version=%s' % (self.format_string(quote_attrib(
self.version).encode(ExternalEncoding), input_name='version'), ))
def exportChildren(self, outfile, level, namespace_='', name_='DoxygenType'):
for compound_ in self.compound:
compound_.export(outfile, level, namespace_, name_='compound')
def hasContent_(self):
if (
self.compound is not None
):
):
return True
else:
return False
def exportLiteral(self, outfile, level, name_='DoxygenType'):
level += 1
self.exportLiteralAttributes(outfile, level, name_)
if self.hasContent_():
self.exportLiteralChildren(outfile, level, name_)
def exportLiteralAttributes(self, outfile, level, name_):
if self.version is not None:
showIndent(outfile, level)
outfile.write('version = %s,\n' % (self.version,))
def exportLiteralChildren(self, outfile, level, name_):
showIndent(outfile, level)
outfile.write('compound=[\n')
@ -253,18 +276,21 @@ class DoxygenType(GeneratedsSuper):
level -= 1
showIndent(outfile, level)
outfile.write('],\n')
def build(self, node_):
attrs = node_.attributes
self.buildAttributes(attrs)
for child_ in node_.childNodes:
nodeName_ = child_.nodeName.split(':')[-1]
self.buildChildren(child_, nodeName_)
def buildAttributes(self, attrs):
if attrs.get('version'):
self.version = attrs.get('version').value
def buildChildren(self, child_, nodeName_):
if child_.nodeType == Node.ELEMENT_NODE and \
nodeName_ == 'compound':
nodeName_ == 'compound':
obj_ = CompoundType.factory()
obj_.build(child_)
self.compound.append(obj_)
@ -274,6 +300,7 @@ class DoxygenType(GeneratedsSuper):
class CompoundType(GeneratedsSuper):
subclass = None
superclass = None
def __init__(self, kind=None, refid=None, name=None, member=None):
self.kind = kind
self.refid = refid
@ -282,6 +309,7 @@ class CompoundType(GeneratedsSuper):
self.member = []
else:
self.member = member
def factory(*args_, **kwargs_):
if CompoundType.subclass:
return CompoundType.subclass(*args_, **kwargs_)
@ -298,6 +326,7 @@ class CompoundType(GeneratedsSuper):
def set_kind(self, kind): self.kind = kind
def get_refid(self): return self.refid
def set_refid(self, refid): self.refid = refid
def export(self, outfile, level, namespace_='', name_='CompoundType', namespacedef_=''):
showIndent(outfile, level)
outfile.write('<%s%s %s' % (namespace_, name_, namespacedef_, ))
@ -309,28 +338,35 @@ class CompoundType(GeneratedsSuper):
outfile.write('</%s%s>\n' % (namespace_, name_))
else:
outfile.write(' />\n')
def exportAttributes(self, outfile, level, namespace_='', name_='CompoundType'):
outfile.write(' kind=%s' % (quote_attrib(self.kind), ))
outfile.write(' refid=%s' % (self.format_string(quote_attrib(self.refid).encode(ExternalEncoding), input_name='refid'), ))
outfile.write(' refid=%s' % (self.format_string(quote_attrib(
self.refid).encode(ExternalEncoding), input_name='refid'), ))
def exportChildren(self, outfile, level, namespace_='', name_='CompoundType'):
if self.name is not None:
showIndent(outfile, level)
outfile.write('<%sname>%s</%sname>\n' % (namespace_, self.format_string(quote_xml(self.name).encode(ExternalEncoding), input_name='name'), namespace_))
outfile.write('<%sname>%s</%sname>\n' % (namespace_, self.format_string(
quote_xml(self.name).encode(ExternalEncoding), input_name='name'), namespace_))
for member_ in self.member:
member_.export(outfile, level, namespace_, name_='member')
def hasContent_(self):
if (
self.name is not None or
self.member is not None
):
):
return True
else:
return False
def exportLiteral(self, outfile, level, name_='CompoundType'):
level += 1
self.exportLiteralAttributes(outfile, level, name_)
if self.hasContent_():
self.exportLiteralChildren(outfile, level, name_)
def exportLiteralAttributes(self, outfile, level, name_):
if self.kind is not None:
showIndent(outfile, level)
@ -338,9 +374,11 @@ class CompoundType(GeneratedsSuper):
if self.refid is not None:
showIndent(outfile, level)
outfile.write('refid = %s,\n' % (self.refid,))
def exportLiteralChildren(self, outfile, level, name_):
showIndent(outfile, level)
outfile.write('name=%s,\n' % quote_python(self.name).encode(ExternalEncoding))
outfile.write('name=%s,\n' % quote_python(
self.name).encode(ExternalEncoding))
showIndent(outfile, level)
outfile.write('member=[\n')
level += 1
@ -353,26 +391,29 @@ class CompoundType(GeneratedsSuper):
level -= 1
showIndent(outfile, level)
outfile.write('],\n')
def build(self, node_):
attrs = node_.attributes
self.buildAttributes(attrs)
for child_ in node_.childNodes:
nodeName_ = child_.nodeName.split(':')[-1]
self.buildChildren(child_, nodeName_)
def buildAttributes(self, attrs):
if attrs.get('kind'):
self.kind = attrs.get('kind').value
if attrs.get('refid'):
self.refid = attrs.get('refid').value
def buildChildren(self, child_, nodeName_):
if child_.nodeType == Node.ELEMENT_NODE and \
nodeName_ == 'name':
nodeName_ == 'name':
name_ = ''
for text__content_ in child_.childNodes:
name_ += text__content_.nodeValue
self.name = name_
elif child_.nodeType == Node.ELEMENT_NODE and \
nodeName_ == 'member':
nodeName_ == 'member':
obj_ = MemberType.factory()
obj_.build(child_)
self.member.append(obj_)
@ -382,10 +423,12 @@ class CompoundType(GeneratedsSuper):
class MemberType(GeneratedsSuper):
subclass = None
superclass = None
def __init__(self, kind=None, refid=None, name=None):
self.kind = kind
self.refid = refid
self.name = name
def factory(*args_, **kwargs_):
if MemberType.subclass:
return MemberType.subclass(*args_, **kwargs_)
@ -398,6 +441,7 @@ class MemberType(GeneratedsSuper):
def set_kind(self, kind): self.kind = kind
def get_refid(self): return self.refid
def set_refid(self, refid): self.refid = refid
def export(self, outfile, level, namespace_='', name_='MemberType', namespacedef_=''):
showIndent(outfile, level)
outfile.write('<%s%s %s' % (namespace_, name_, namespacedef_, ))
@ -409,25 +453,32 @@ class MemberType(GeneratedsSuper):
outfile.write('</%s%s>\n' % (namespace_, name_))
else:
outfile.write(' />\n')
def exportAttributes(self, outfile, level, namespace_='', name_='MemberType'):
outfile.write(' kind=%s' % (quote_attrib(self.kind), ))
outfile.write(' refid=%s' % (self.format_string(quote_attrib(self.refid).encode(ExternalEncoding), input_name='refid'), ))
outfile.write(' refid=%s' % (self.format_string(quote_attrib(
self.refid).encode(ExternalEncoding), input_name='refid'), ))
def exportChildren(self, outfile, level, namespace_='', name_='MemberType'):
if self.name is not None:
showIndent(outfile, level)
outfile.write('<%sname>%s</%sname>\n' % (namespace_, self.format_string(quote_xml(self.name).encode(ExternalEncoding), input_name='name'), namespace_))
outfile.write('<%sname>%s</%sname>\n' % (namespace_, self.format_string(
quote_xml(self.name).encode(ExternalEncoding), input_name='name'), namespace_))
def hasContent_(self):
if (
self.name is not None
):
):
return True
else:
return False
def exportLiteral(self, outfile, level, name_='MemberType'):
level += 1
self.exportLiteralAttributes(outfile, level, name_)
if self.hasContent_():
self.exportLiteralChildren(outfile, level, name_)
def exportLiteralAttributes(self, outfile, level, name_):
if self.kind is not None:
showIndent(outfile, level)
@ -435,23 +486,28 @@ class MemberType(GeneratedsSuper):
if self.refid is not None:
showIndent(outfile, level)
outfile.write('refid = %s,\n' % (self.refid,))
def exportLiteralChildren(self, outfile, level, name_):
showIndent(outfile, level)
outfile.write('name=%s,\n' % quote_python(self.name).encode(ExternalEncoding))
outfile.write('name=%s,\n' % quote_python(
self.name).encode(ExternalEncoding))
def build(self, node_):
attrs = node_.attributes
self.buildAttributes(attrs)
for child_ in node_.childNodes:
nodeName_ = child_.nodeName.split(':')[-1]
self.buildChildren(child_, nodeName_)
def buildAttributes(self, attrs):
if attrs.get('kind'):
self.kind = attrs.get('kind').value
if attrs.get('refid'):
self.refid = attrs.get('refid').value
def buildChildren(self, child_, nodeName_):
if child_.nodeType == Node.ELEMENT_NODE and \
nodeName_ == 'name':
nodeName_ == 'name':
name_ = ''
for text__content_ in child_.childNodes:
name_ += text__content_.nodeValue
@ -465,6 +521,7 @@ Options:
-s Use the SAX parser, not the minidom parser.
"""
def usage():
print(USAGE_TEXT)
sys.exit(1)
@ -479,7 +536,7 @@ def parse(inFileName):
doc = None
sys.stdout.write('<?xml version="1.0" ?>\n')
rootObj.export(sys.stdout, 0, name_="doxygenindex",
namespacedef_='')
namespacedef_='')
return rootObj
@ -492,7 +549,7 @@ def parseString(inString):
doc = None
sys.stdout.write('<?xml version="1.0" ?>\n')
rootObj.export(sys.stdout, 0, name_="doxygenindex",
namespacedef_='')
namespacedef_='')
return rootObj
@ -518,9 +575,7 @@ def main():
usage()
if __name__ == '__main__':
main()
#import pdb
#pdb.run('main()')
# pdb.run('main()')

Wyświetl plik

@ -4,25 +4,13 @@
# This file was generated by gr_modtool, a tool from the GNU Radio framework
# This file is a part of gr-droneid
#
# 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
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
# SPDX-License-Identifier: GPL-3.0-or-later
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
"""
Utilities for extracting text from generated classes.
"""
from __future__ import unicode_literals
def is_string(txt):
if isinstance(txt, str):
@ -34,11 +22,13 @@ def is_string(txt):
pass
return False
def description(obj):
if obj is None:
return None
return description_bit(obj).strip()
def description_bit(obj):
if hasattr(obj, 'content'):
contents = [description_bit(item) for item in obj.content]
@ -51,7 +41,8 @@ def description_bit(obj):
elif is_string(obj):
return obj
else:
raise Exception('Expecting a string or something with content, content_ or value attribute')
raise Exception(
'Expecting a string or something with content, content_ or value attribute')
# If this bit is a paragraph then add one some line breaks.
if hasattr(obj, 'name') and obj.name == 'para':
result += "\n\n"

Wyświetl plik

@ -0,0 +1,446 @@
#!/usr/bin/env python
__applicationName__ = "doxypy"
__blurb__ = """
doxypy is an input filter for Doxygen. It preprocesses python
files so that docstrings of classes and functions are reformatted
into Doxygen-conform documentation blocks.
"""
__doc__ = __blurb__ + \
"""
In order to make Doxygen preprocess files through doxypy, simply
add the following lines to your Doxyfile:
FILTER_SOURCE_FILES = YES
INPUT_FILTER = "python /path/to/doxypy.py"
"""
__version__ = "0.4.2"
__date__ = "5th December 2008"
__website__ = "http://code.foosel.org/doxypy"
__author__ = (
"Philippe 'demod' Neumann (doxypy at demod dot org)",
"Gina 'foosel' Haeussge (gina at foosel dot net)"
)
__licenseName__ = "GPL v2"
__license__ = """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, see <http://www.gnu.org/licenses/>.
"""
import sys
import re
from argparse import ArgumentParser
class FSM(object):
"""Implements a finite state machine.
Transitions are given as 4-tuples, consisting of an origin state, a target
state, a condition for the transition (given as a reference to a function
which gets called with a given piece of input) and a pointer to a function
to be called upon the execution of the given transition.
"""
"""
@var transitions holds the transitions
@var current_state holds the current state
@var current_input holds the current input
@var current_transition hold the currently active transition
"""
def __init__(self, start_state=None, transitions=[]):
self.transitions = transitions
self.current_state = start_state
self.current_input = None
self.current_transition = None
def setStartState(self, state):
self.current_state = state
def addTransition(self, from_state, to_state, condition, callback):
self.transitions.append([from_state, to_state, condition, callback])
def makeTransition(self, input):
""" Makes a transition based on the given input.
@param input input to parse by the FSM
"""
for transition in self.transitions:
[from_state, to_state, condition, callback] = transition
if from_state == self.current_state:
match = condition(input)
if match:
self.current_state = to_state
self.current_input = input
self.current_transition = transition
if args.debug:
print("# FSM: executing (%s -> %s) for line '%s'" %
(from_state, to_state, input), file=sys.stderr)
callback(match)
return
class Doxypy(object):
def __init__(self):
string_prefixes = "[uU]?[rR]?"
self.start_single_comment_re = re.compile(
r"^\s*%s(''')" % string_prefixes)
self.end_single_comment_re = re.compile(r"(''')\s*$")
self.start_double_comment_re = re.compile(
r'^\s*%s(""")' % string_prefixes)
self.end_double_comment_re = re.compile(r'(""")\s*$')
self.single_comment_re = re.compile(
r"^\s*%s(''').*(''')\s*$" % string_prefixes)
self.double_comment_re = re.compile(
r'^\s*%s(""").*(""")\s*$' % string_prefixes)
self.defclass_re = re.compile(r"^(\s*)(def .+:|class .+:)")
self.empty_re = re.compile(r"^\s*$")
self.hashline_re = re.compile(r"^\s*#.*$")
self.importline_re = re.compile(r"^\s*(import |from .+ import)")
self.multiline_defclass_start_re = re.compile(
r"^(\s*)(def|class)(\s.*)?$")
self.multiline_defclass_end_re = re.compile(r":\s*$")
# Transition list format
# ["FROM", "TO", condition, action]
transitions = [
# FILEHEAD
# single line comments
["FILEHEAD", "FILEHEAD", self.single_comment_re.search,
self.appendCommentLine],
["FILEHEAD", "FILEHEAD", self.double_comment_re.search,
self.appendCommentLine],
# multiline comments
["FILEHEAD", "FILEHEAD_COMMENT_SINGLE",
self.start_single_comment_re.search, self.appendCommentLine],
["FILEHEAD_COMMENT_SINGLE", "FILEHEAD",
self.end_single_comment_re.search, self.appendCommentLine],
["FILEHEAD_COMMENT_SINGLE", "FILEHEAD_COMMENT_SINGLE",
self.catchall, self.appendCommentLine],
["FILEHEAD", "FILEHEAD_COMMENT_DOUBLE",
self.start_double_comment_re.search, self.appendCommentLine],
["FILEHEAD_COMMENT_DOUBLE", "FILEHEAD",
self.end_double_comment_re.search, self.appendCommentLine],
["FILEHEAD_COMMENT_DOUBLE", "FILEHEAD_COMMENT_DOUBLE",
self.catchall, self.appendCommentLine],
# other lines
["FILEHEAD", "FILEHEAD", self.empty_re.search, self.appendFileheadLine],
["FILEHEAD", "FILEHEAD", self.hashline_re.search, self.appendFileheadLine],
["FILEHEAD", "FILEHEAD", self.importline_re.search,
self.appendFileheadLine],
["FILEHEAD", "DEFCLASS", self.defclass_re.search, self.resetCommentSearch],
["FILEHEAD", "DEFCLASS_MULTI",
self.multiline_defclass_start_re.search, self.resetCommentSearch],
["FILEHEAD", "DEFCLASS_BODY", self.catchall, self.appendFileheadLine],
# DEFCLASS
# single line comments
["DEFCLASS", "DEFCLASS_BODY",
self.single_comment_re.search, self.appendCommentLine],
["DEFCLASS", "DEFCLASS_BODY",
self.double_comment_re.search, self.appendCommentLine],
# multiline comments
["DEFCLASS", "COMMENT_SINGLE",
self.start_single_comment_re.search, self.appendCommentLine],
["COMMENT_SINGLE", "DEFCLASS_BODY",
self.end_single_comment_re.search, self.appendCommentLine],
["COMMENT_SINGLE", "COMMENT_SINGLE",
self.catchall, self.appendCommentLine],
["DEFCLASS", "COMMENT_DOUBLE",
self.start_double_comment_re.search, self.appendCommentLine],
["COMMENT_DOUBLE", "DEFCLASS_BODY",
self.end_double_comment_re.search, self.appendCommentLine],
["COMMENT_DOUBLE", "COMMENT_DOUBLE",
self.catchall, self.appendCommentLine],
# other lines
["DEFCLASS", "DEFCLASS", self.empty_re.search, self.appendDefclassLine],
["DEFCLASS", "DEFCLASS", self.defclass_re.search, self.resetCommentSearch],
["DEFCLASS", "DEFCLASS_MULTI",
self.multiline_defclass_start_re.search, self.resetCommentSearch],
["DEFCLASS", "DEFCLASS_BODY", self.catchall, self.stopCommentSearch],
# DEFCLASS_BODY
["DEFCLASS_BODY", "DEFCLASS",
self.defclass_re.search, self.startCommentSearch],
["DEFCLASS_BODY", "DEFCLASS_MULTI",
self.multiline_defclass_start_re.search, self.startCommentSearch],
["DEFCLASS_BODY", "DEFCLASS_BODY", self.catchall, self.appendNormalLine],
# DEFCLASS_MULTI
["DEFCLASS_MULTI", "DEFCLASS",
self.multiline_defclass_end_re.search, self.appendDefclassLine],
["DEFCLASS_MULTI", "DEFCLASS_MULTI",
self.catchall, self.appendDefclassLine],
]
self.fsm = FSM("FILEHEAD", transitions)
self.outstream = sys.stdout
self.output = []
self.comment = []
self.filehead = []
self.defclass = []
self.indent = ""
def __closeComment(self):
"""Appends any open comment block and triggering block to the output."""
if args.autobrief:
if len(self.comment) == 1 \
or (len(self.comment) > 2 and self.comment[1].strip() == ''):
self.comment[0] = self.__docstringSummaryToBrief(
self.comment[0])
if self.comment:
block = self.makeCommentBlock()
self.output.extend(block)
if self.defclass:
self.output.extend(self.defclass)
def __docstringSummaryToBrief(self, line):
"""Adds \\brief to the docstrings summary line.
A \\brief is prepended, provided no other doxygen command is at the
start of the line.
"""
stripped = line.strip()
if stripped and not stripped[0] in ('@', '\\'):
return "\\brief " + line
else:
return line
def __flushBuffer(self):
"""Flushes the current outputbuffer to the outstream."""
if self.output:
try:
if args.debug:
print("# OUTPUT: ", self.output, file=sys.stderr)
print("\n".join(self.output), file=self.outstream)
self.outstream.flush()
except IOError:
# Fix for FS#33. Catches "broken pipe" when doxygen closes
# stdout prematurely upon usage of INPUT_FILTER, INLINE_SOURCES
# and FILTER_SOURCE_FILES.
pass
self.output = []
def catchall(self, input):
"""The catchall-condition, always returns true."""
return True
def resetCommentSearch(self, match):
"""Restarts a new comment search for a different triggering line.
Closes the current commentblock and starts a new comment search.
"""
if args.debug:
print("# CALLBACK: resetCommentSearch", file=sys.stderr)
self.__closeComment()
self.startCommentSearch(match)
def startCommentSearch(self, match):
"""Starts a new comment search.
Saves the triggering line, resets the current comment and saves
the current indentation.
"""
if args.debug:
print("# CALLBACK: startCommentSearch", file=sys.stderr)
self.defclass = [self.fsm.current_input]
self.comment = []
self.indent = match.group(1)
def stopCommentSearch(self, match):
"""Stops a comment search.
Closes the current commentblock, resets the triggering line and
appends the current line to the output.
"""
if args.debug:
print("# CALLBACK: stopCommentSearch", file=sys.stderr)
self.__closeComment()
self.defclass = []
self.output.append(self.fsm.current_input)
def appendFileheadLine(self, match):
"""Appends a line in the FILEHEAD state.
Closes the open comment block, resets it and appends the current line.
"""
if args.debug:
print("# CALLBACK: appendFileheadLine", file=sys.stderr)
self.__closeComment()
self.comment = []
self.output.append(self.fsm.current_input)
def appendCommentLine(self, match):
"""Appends a comment line.
The comment delimiter is removed from multiline start and ends as
well as singleline comments.
"""
if args.debug:
print("# CALLBACK: appendCommentLine", file=sys.stderr)
(from_state, to_state, condition, callback) = self.fsm.current_transition
# single line comment
if (from_state == "DEFCLASS" and to_state == "DEFCLASS_BODY") \
or (from_state == "FILEHEAD" and to_state == "FILEHEAD"):
# remove comment delimiter from begin and end of the line
activeCommentDelim = match.group(1)
line = self.fsm.current_input
self.comment.append(line[line.find(
activeCommentDelim) + len(activeCommentDelim):line.rfind(activeCommentDelim)])
if (to_state == "DEFCLASS_BODY"):
self.__closeComment()
self.defclass = []
# multiline start
elif from_state == "DEFCLASS" or from_state == "FILEHEAD":
# remove comment delimiter from begin of the line
activeCommentDelim = match.group(1)
line = self.fsm.current_input
self.comment.append(
line[line.find(activeCommentDelim) + len(activeCommentDelim):])
# multiline end
elif to_state == "DEFCLASS_BODY" or to_state == "FILEHEAD":
# remove comment delimiter from end of the line
activeCommentDelim = match.group(1)
line = self.fsm.current_input
self.comment.append(line[0:line.rfind(activeCommentDelim)])
if (to_state == "DEFCLASS_BODY"):
self.__closeComment()
self.defclass = []
# in multiline comment
else:
# just append the comment line
self.comment.append(self.fsm.current_input)
def appendNormalLine(self, match):
"""Appends a line to the output."""
if args.debug:
print("# CALLBACK: appendNormalLine", file=sys.stderr)
self.output.append(self.fsm.current_input)
def appendDefclassLine(self, match):
"""Appends a line to the triggering block."""
if args.debug:
print("# CALLBACK: appendDefclassLine", file=sys.stderr)
self.defclass.append(self.fsm.current_input)
def makeCommentBlock(self):
"""Indents the current comment block with respect to the current
indentation level.
@returns a list of indented comment lines
"""
doxyStart = "##"
commentLines = self.comment
commentLines = ["%s# %s" % (self.indent, x) for x in commentLines]
l = [self.indent + doxyStart]
l.extend(commentLines)
return l
def parse(self, input):
"""Parses a python file given as input string and returns the doxygen-
compatible representation.
@param input the python code to parse
@returns the modified python code
"""
lines = input.split("\n")
for line in lines:
self.fsm.makeTransition(line)
if self.fsm.current_state == "DEFCLASS":
self.__closeComment()
return "\n".join(self.output)
def parseFile(self, filename):
"""Parses a python file given as input string and returns the doxygen-
compatible representation.
@param input the python code to parse
@returns the modified python code
"""
f = open(filename, 'r')
for line in f:
self.parseLine(line.rstrip('\r\n'))
if self.fsm.current_state == "DEFCLASS":
self.__closeComment()
self.__flushBuffer()
f.close()
def parseLine(self, line):
"""Parse one line of python and flush the resulting output to the
outstream.
@param line the python code line to parse
"""
self.fsm.makeTransition(line)
self.__flushBuffer()
def argParse():
"""Parses commandline args."""
parser = ArgumentParser(prog=__applicationName__)
parser.add_argument("--version", action="version",
version="%(prog)s " + __version__
)
parser.add_argument("--autobrief", action="store_true",
help="use the docstring summary line as \\brief description"
)
parser.add_argument("--debug", action="store_true",
help="enable debug output on stderr"
)
parser.add_argument("filename", metavar="FILENAME")
return parser.parse_args()
def main():
"""Starts the parser on the file given by the filename as the first
argument on the commandline.
"""
global args
args = argParse()
fsm = Doxypy()
fsm.parseFile(args.filename)
if __name__ == "__main__":
main()

Wyświetl plik

@ -4,4 +4,3 @@
* module are listed here or in the subcategories below.
*
*/

Wyświetl plik

@ -0,0 +1,19 @@
#ifndef PYDOC_MACROS_H
#define PYDOC_MACROS_H
#define __EXPAND(x) x
#define __COUNT(_1, _2, _3, _4, _5, _6, _7, COUNT, ...) COUNT
#define __VA_SIZE(...) __EXPAND(__COUNT(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1))
#define __CAT1(a, b) a##b
#define __CAT2(a, b) __CAT1(a, b)
#define __DOC1(n1) __doc_##n1
#define __DOC2(n1, n2) __doc_##n1##_##n2
#define __DOC3(n1, n2, n3) __doc_##n1##_##n2##_##n3
#define __DOC4(n1, n2, n3, n4) __doc_##n1##_##n2##_##n3##_##n4
#define __DOC5(n1, n2, n3, n4, n5) __doc_##n1##_##n2##_##n3##_##n4##_##n5
#define __DOC6(n1, n2, n3, n4, n5, n6) __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6
#define __DOC7(n1, n2, n3, n4, n5, n6, n7) \
__doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6##_##n7
#define DOC(...) __EXPAND(__EXPAND(__CAT2(__DOC, __VA_SIZE(__VA_ARGS__)))(__VA_ARGS__))
#endif // PYDOC_MACROS_H

Wyświetl plik

@ -2,42 +2,37 @@
# Copyright 2010-2012 Free Software Foundation, Inc.
#
# This file was generated by gr_modtool, a tool from the GNU Radio framework
# This file is a part of gr-droneid
# This file is a part of gnuradio
#
# 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
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
# SPDX-License-Identifier: GPL-3.0-or-later
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
"""
Creates the swig_doc.i SWIG interface file.
Execute using: python swig_doc.py xml_path outputfilename
Updates the *pydoc_h files for a module
Execute using: python update_pydoc.py xml_path outputfilename
The file instructs SWIG to transfer the doxygen comments into the
The file instructs Pybind11 to transfer the doxygen comments into the
python docstrings.
"""
from __future__ import unicode_literals
import sys, time
import os
import sys
import time
import glob
import re
import json
from argparse import ArgumentParser
from doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile
from doxyxml import DoxyOther, base
def py_name(name):
bits = name.split('_')
return '_'.join(bits[1:])
def make_name(name):
bits = name.split('_')
return bits[0] + '_make_' + '_'.join(bits[1:])
@ -62,6 +57,7 @@ class Block(object):
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
@ -75,7 +71,8 @@ class Block2(object):
# Check for a parsing error.
if item.error():
return False
is_a_block2 = item.has_member('make', DoxyFunction) and item.has_member('sptr', DoxyOther)
is_a_block2 = item.has_member(
'make', DoxyFunction) and item.has_member('sptr', DoxyOther)
return is_a_block2
@ -87,6 +84,7 @@ def utoascii(text):
return ''
out = text.encode('ascii', 'replace')
# swig will require us to replace blackslash with 4 backslashes
# TODO: evaluate what this should be for pybind11
out = out.replace(b'\\', b'\\\\\\\\')
out = out.replace(b'"', b'\\"').decode('ascii')
return str(out)
@ -105,6 +103,7 @@ def combine_descriptions(obj):
description.append(dd)
return utoascii('\n\n'.join(description)).strip()
def format_params(parameteritems):
output = ['Args:']
template = ' {0} : {1}'
@ -112,10 +111,13 @@ def format_params(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, params=[]):
"""
Create a docstring entry for a swig interface file.
Create a docstring key/value pair, where the key is the object name.
obj - a doxyxml object from which documentation will be extracted.
name - the name of the C object (defaults to obj.name())
@ -125,7 +127,9 @@ def make_entry(obj, name=None, templ="{description}", description=None, params=[
used as the description instead of extracting it from obj.
"""
if name is None:
name=obj.name()
name = obj.name()
if hasattr(obj, '_parse_data') and hasattr(obj._parse_data, 'definition'):
name = obj._parse_data.definition.split(' ')[-1]
if "operator " in name:
return ''
if description is None:
@ -134,56 +138,28 @@ def make_entry(obj, name=None, templ="{description}", description=None, params=[
description += '\n\n'
description += utoascii(format_params(params))
docstring = templ.format(description=description)
if not docstring:
return ''
return entry_templ.format(
name=name,
docstring=docstring,
)
def make_func_entry(func, name=None, description=None, params=None):
"""
Create a function docstring entry for a swig interface file.
func - a doxyxml object from which documentation will be extracted.
name - the name of the C object (defaults to func.name())
description - if this optional variable is set then it's value is
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)
return make_entry(func, name=name, description=description, params=params)
return {name: docstring}
def make_class_entry(klass, description=None, ignored_methods=[], params=None):
"""
Create a class docstring for a swig interface file.
Create a class docstring key/value pair.
"""
if params is None:
params = klass.params
output = []
output.append(make_entry(klass, description=description, params=params))
output = {}
output.update(make_entry(klass, description=description, params=params))
for func in klass.in_category(DoxyFunction):
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)
output.update(make_entry(func, name=name))
return output
def make_block_entry(di, block):
"""
Create class and function docstrings of a gnuradio block for a
swig interface file.
Create class and function docstrings of a gnuradio block
"""
descriptions = []
# Get the documentation associated with the class.
@ -208,48 +184,42 @@ def make_block_entry(di, block):
super_description = "\n\n".join(descriptions)
# Associate the combined description with the class and
# the make function.
output = []
output.append(make_class_entry(block, description=super_description))
output.append(make_func_entry(make_func, description=super_description,
params=block.params))
return "\n\n".join(output)
output = {}
output.update(make_class_entry(block, description=super_description))
output.update(make_entry(make_func, description=super_description,
params=block.params))
return output
def make_block2_entry(di, block):
"""
Create class and function docstrings of a new style gnuradio block for a
swig interface file.
Create class and function docstrings of a new style gnuradio block
"""
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
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))
output = {}
output.update(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)
output.update(make_entry(
make_func, name=makename, description=description,
params=make_func.params))
return output
def make_swig_interface_file(di, swigdocfilename, custom_output=None):
output = ["""
/*
* This file was automatically generated using swig_doc.py.
*
* Any changes to it will be lost next time it is regenerated.
*/
"""]
def get_docstrings_dict(di, custom_output=None):
if custom_output is not None:
output.append(custom_output)
output = {}
if custom_output:
output.update(custom_output)
# Create docstrings for the blocks.
blocks = di.in_category(Block)
@ -262,21 +232,23 @@ def make_swig_interface_file(di, swigdocfilename, custom_output=None):
# 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))
output.update(make_block_entry(di, block))
except block.ParsingError:
sys.stderr.write('Parsing error for block {0}\n'.format(block.name()))
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'
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))
output.update(make_block2_entry(di, block))
except block.ParsingError:
sys.stderr.write('Parsing error for block {0}\n'.format(block.name()))
sys.stderr.write(
'Parsing error for block {0}\n'.format(block.name()))
raise
# Create docstrings for functions
@ -285,9 +257,10 @@ def make_swig_interface_file(di, swigdocfilename, custom_output=None):
if f.name() not in make_funcs and not f.name().startswith('std::')]
for f in funcs:
try:
output.append(make_func_entry(f))
output.update(make_entry(f))
except f.ParsingError:
sys.stderr.write('Parsing error for function {0}\n'.format(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]
@ -296,37 +269,104 @@ def make_swig_interface_file(di, swigdocfilename, custom_output=None):
if k.name() not in block_names and not k.name().startswith('std::')]
for k in klasses:
try:
output.append(make_class_entry(k))
output.update(make_class_entry(k))
except k.ParsingError:
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)
return output
def sub_docstring_in_pydoc_h(pydoc_files, docstrings_dict, output_dir, filter_str=None):
if filter_str:
docstrings_dict = {
k: v for k, v in docstrings_dict.items() if k.startswith(filter_str)}
with open(os.path.join(output_dir, 'docstring_status'), 'w') as status_file:
for pydoc_file in pydoc_files:
if filter_str:
filter_str2 = "::".join((filter_str, os.path.split(
pydoc_file)[-1].split('_pydoc_template.h')[0]))
docstrings_dict2 = {
k: v for k, v in docstrings_dict.items() if k.startswith(filter_str2)}
else:
docstrings_dict2 = docstrings_dict
file_in = open(pydoc_file, 'r').read()
for key, value in docstrings_dict2.items():
file_in_tmp = file_in
try:
doc_key = key.split("::")
# if 'gr' in doc_key:
# doc_key.remove('gr')
doc_key = '_'.join(doc_key)
regexp = r'(__doc_{} =\sR\"doc\()[^)]*(\)doc\")'.format(
doc_key)
regexp = re.compile(regexp, re.MULTILINE)
(file_in, nsubs) = regexp.subn(
r'\1' + value + r'\2', file_in, count=1)
if nsubs == 1:
status_file.write("PASS: " + pydoc_file + "\n")
except KeyboardInterrupt:
raise KeyboardInterrupt
except: # be permissive, TODO log, but just leave the docstring blank
status_file.write("FAIL: " + pydoc_file + "\n")
file_in = file_in_tmp
output_pathname = os.path.join(output_dir, os.path.basename(
pydoc_file).replace('_template.h', '.h'))
with open(output_pathname, 'w') as file_out:
file_out.write(file_in)
def copy_docstring_templates(pydoc_files, output_dir):
with open(os.path.join(output_dir, 'docstring_status'), 'w') as status_file:
for pydoc_file in pydoc_files:
file_in = open(pydoc_file, 'r').read()
output_pathname = os.path.join(output_dir, os.path.basename(
pydoc_file).replace('_template.h', '.h'))
with open(output_pathname, 'w') as file_out:
file_out.write(file_in)
status_file.write("DONE")
def argParse():
"""Parses commandline args."""
desc = 'Scrape the doxygen generated xml for docstrings to insert into python bindings'
parser = ArgumentParser(description=desc)
parser.add_argument("function", help="Operation to perform on docstrings", choices=[
"scrape", "sub", "copy"])
parser.add_argument("--xml_path")
parser.add_argument("--bindings_dir")
parser.add_argument("--output_dir")
parser.add_argument("--json_path")
parser.add_argument("--filter", default=None)
return parser.parse_args()
swig_doc = open(swigdocfilename, 'w')
swig_doc.write(output)
swig_doc.close()
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 Exception(err_msg)
xml_path = sys.argv[1]
swigdocfilename = sys.argv[2]
di = DoxyIndex(xml_path)
# gnuradio.gr.msq_queue.insert_tail and delete_head create errors unless docstrings are defined!
# This is presumably a bug in SWIG.
#msg_q = di.get_member(u'gr_msg_queue', DoxyClass)
#insert_tail = msg_q.get_member(u'insert_tail', DoxyFunction)
#delete_head = msg_q.get_member(u'delete_head', DoxyFunction)
output = []
#output.append(make_func_entry(insert_tail, name='gr_py_msg_queue__insert_tail'))
#output.append(make_func_entry(delete_head, name='gr_py_msg_queue__delete_head'))
custom_output = "\n\n".join(output)
# Generate the docstrings interface file.
make_swig_interface_file(di, swigdocfilename, custom_output=custom_output)
args = argParse()
if args.function.lower() == 'scrape':
di = DoxyIndex(args.xml_path)
docstrings_dict = get_docstrings_dict(di)
with open(args.json_path, 'w') as fp:
json.dump(docstrings_dict, fp)
elif args.function.lower() == 'sub':
with open(args.json_path, 'r') as fp:
docstrings_dict = json.load(fp)
pydoc_files = glob.glob(os.path.join(
args.bindings_dir, '*_pydoc_template.h'))
sub_docstring_in_pydoc_h(
pydoc_files, docstrings_dict, args.output_dir, args.filter)
elif args.function.lower() == 'copy':
pydoc_files = glob.glob(os.path.join(
args.bindings_dir, '*_pydoc_template.h'))
copy_docstring_templates(pydoc_files, args.output_dir)

Wyświetl plik

@ -0,0 +1,47 @@
id: droneid_utils
label: utils
category: '[droneid]'
templates:
imports: from gnuradio import droneid
make: droneid.utils()
# Make one 'parameters' list entry for every parameter you want settable from the GUI.
# Keys include:
# * id (makes the value accessible as keyname, e.g. in the make entry)
# * label (label shown in the GUI)
# * dtype (e.g. int, float, complex, byte, short, xxx_vector, ...)
# * default
parameters:
- id: parametername_replace_me
label: FIX ME:
dtype: string
default: You need to fill in your grc/droneid_utils.block.yaml
#- id: ...
# label: ...
# dtype: ...
# Make one 'inputs' list entry per input and one 'outputs' list entry per output.
# Keys include:
# * label (an identifier for the GUI)
# * domain (optional - stream or message. Default is stream)
# * dtype (e.g. int, float, complex, byte, short, xxx_vector, ...)
# * vlen (optional - data stream vector length. Default is 1)
# * optional (optional - set to 1 for optional inputs. Default is 0)
inputs:
#- label: ...
# domain: ...
# dtype: ...
# vlen: ...
# optional: ...
outputs:
#- label: ...
# domain: ...
# dtype: ...
# vlen: ...
# optional: ...
# 'file_format' specifies the version of the GRC yml format used in the file
# and should usually not be changed.
file_format: 1

Wyświetl plik

@ -0,0 +1,18 @@
# Copyright 2011,2012 Free Software Foundation, Inc.
#
# This file was generated by gr_modtool, a tool from the GNU Radio framework
# This file is a part of gr-droneid
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
########################################################################
# Install public header files
########################################################################
install(FILES
api.h
demodulation.h
extractor.h
time_sync.h
utils.h DESTINATION include/gnuradio/droneid
)

Wyświetl plik

@ -0,0 +1,22 @@
/*
* Copyright 2011 Free Software Foundation, Inc.
*
* This file was generated by gr_modtool, a tool from the GNU Radio framework
* This file is a part of gr-droneid
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#ifndef INCLUDED_DRONEID_API_H
#define INCLUDED_DRONEID_API_H
#include <gnuradio/attributes.h>
#ifdef gnuradio_droneid_EXPORTS
#define DRONEID_API __GR_ATTR_EXPORT
#else
#define DRONEID_API __GR_ATTR_IMPORT
#endif
#endif /* INCLUDED_DRONEID_API_H */

Wyświetl plik

@ -0,0 +1,41 @@
/* -*- c++ -*- */
/*
* Copyright 2022 gr-droneid author.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#ifndef INCLUDED_DRONEID_DEMODULATION_H
#define INCLUDED_DRONEID_DEMODULATION_H
#include <gnuradio/droneid/api.h>
#include <gnuradio/sync_block.h>
namespace gr {
namespace droneid {
/*!
* \brief <+description of block+>
* \ingroup droneid
*
*/
class DRONEID_API demodulation : virtual public gr::sync_block
{
public:
typedef std::shared_ptr<demodulation> sptr;
/*!
* \brief Return a shared_ptr to a new instance of droneid::demodulation.
*
* To avoid accidental use of raw pointers, droneid::demodulation's
* constructor is in a private implementation
* class. droneid::demodulation::make is the public interface for
* creating new instances.
*/
static sptr make(double sample_rate);
};
} // namespace droneid
} // namespace gr
#endif /* INCLUDED_DRONEID_DEMODULATION_H */

Wyświetl plik

@ -0,0 +1,41 @@
/* -*- c++ -*- */
/*
* Copyright 2022 gr-droneid author.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#ifndef INCLUDED_DRONEID_EXTRACTOR_H
#define INCLUDED_DRONEID_EXTRACTOR_H
#include <gnuradio/droneid/api.h>
#include <gnuradio/sync_block.h>
namespace gr {
namespace droneid {
/*!
* \brief <+description of block+>
* \ingroup droneid
*
*/
class DRONEID_API extractor : virtual public gr::sync_block
{
public:
typedef std::shared_ptr<extractor> sptr;
/*!
* \brief Return a shared_ptr to a new instance of droneid::extractor.
*
* To avoid accidental use of raw pointers, droneid::extractor's
* constructor is in a private implementation
* class. droneid::extractor::make is the public interface for
* creating new instances.
*/
static sptr make(double sample_rate);
};
} // namespace droneid
} // namespace gr
#endif /* INCLUDED_DRONEID_EXTRACTOR_H */

Wyświetl plik

@ -0,0 +1,41 @@
/* -*- c++ -*- */
/*
* Copyright 2022 gr-droneid author.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#ifndef INCLUDED_DRONEID_TIME_SYNC_H
#define INCLUDED_DRONEID_TIME_SYNC_H
#include <gnuradio/droneid/api.h>
#include <gnuradio/sync_block.h>
namespace gr {
namespace droneid {
/*!
* \brief <+description of block+>
* \ingroup droneid
*
*/
class DRONEID_API time_sync : virtual public gr::sync_block
{
public:
typedef std::shared_ptr<time_sync> sptr;
/*!
* \brief Return a shared_ptr to a new instance of droneid::time_sync.
*
* To avoid accidental use of raw pointers, droneid::time_sync's
* constructor is in a private implementation
* class. droneid::time_sync::make is the public interface for
* creating new instances.
*/
static sptr make(double sample_rate);
};
} // namespace droneid
} // namespace gr
#endif /* INCLUDED_DRONEID_TIME_SYNC_H */

Wyświetl plik

@ -0,0 +1,48 @@
/* -*- c++ -*- */
/*
* Copyright 2022 gr-droneid author.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#ifndef INCLUDED_DRONEID_UTILS_H
#define INCLUDED_DRONEID_UTILS_H
#include <gnuradio/droneid/api.h>
#include <cstdint>
#include <vector>
#include <complex>
namespace gr {
namespace droneid {
/*!
* \brief <+description+>
*
*/
class DRONEID_API utils
{
public:
utils();
~utils();
static constexpr double CARRIER_SPACING = 15e3;
static constexpr unsigned int OCCUPIED_CARRIERS_EXC_DC = 600;
static constexpr unsigned int OCCUPIED_CARRIERS_INC_DC = 601;
static unsigned int get_long_cp_len(double sample_rate);
static unsigned int get_short_cp_len(double sample_rate);
static unsigned int get_fft_size(double sample_rate);
static std::vector<std::complex<float>> create_zc_sequence(double sample_rate, uint32_t root);
private:
};
} // namespace droneid
} // namespace gr
#endif /* INCLUDED_DRONEID_UTILS_H */

Wyświetl plik

@ -0,0 +1,21 @@
/* -*- c++ -*- */
/*
* Copyright 2022 gr-droneid author.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include <gnuradio/attributes.h>
#include <gnuradio/droneid/utils.h>
#include <boost/test/unit_test.hpp>
namespace gr {
namespace droneid {
BOOST_AUTO_TEST_CASE(test_utils_replace_with_specific_test_name)
{
// Put test here
}
} /* namespace droneid */
} /* namespace gr */

Wyświetl plik

@ -0,0 +1,66 @@
/* -*- c++ -*- */
/*
* Copyright 2022 gr-droneid author.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include <gnuradio/droneid/utils.h>
#include <gnuradio/io_signature.h>
#include <gnuradio/fft/fft.h>
namespace gr {
namespace droneid {
uint32_t utils::get_long_cp_len(double sample_rate) {
return static_cast<uint32_t>(std::round(sample_rate / 192000));
}
uint32_t utils::get_short_cp_len(double sample_rate) {
return static_cast<uint32_t>(round(0.0000046875 * sample_rate));
}
uint32_t utils::get_fft_size(double sample_rate) {
return static_cast<uint32_t>(round(sample_rate / CARRIER_SPACING));
}
std::vector<std::complex<float>> utils::create_zc_sequence(const double sample_rate, const uint32_t root) {
const auto fft_size = get_fft_size(sample_rate);
std::vector<std::complex<float>> sequence(fft_size, {0, 0});
const uint32_t guard_carriers = fft_size - OCCUPIED_CARRIERS_EXC_DC;
const auto left_guards = guard_carriers / 2;
std::vector<std::complex<float>> g (OCCUPIED_CARRIERS_INC_DC);
const auto I = std::complex<double>(0, 1);
for (int idx = 0; idx < OCCUPIED_CARRIERS_INC_DC; idx++) {
// Doing the arith below in double precision and then casting down to a float. Using floats the whole
// way will result in an output that's very far off from the MATLAB implementation. The errors will accumulate
// down the vector
sequence[left_guards + idx] = std::exp(-I * (M_PIf64 * (double)root * (double)idx * (double)(idx + 1) / 601.0));
}
// Null out the DC carrier
sequence[(fft_size / 2) - 1] = 0;
// Create an FFT object that is configured to run an inverse FFT
gr::fft::fft_complex_rev ifft(static_cast<int>(fft_size), false);
// FFT-shift the inputs (swap the left and right halves) and store in the IFFT input buffer
std::copy(sequence.begin() + (fft_size/2), sequence.begin() + fft_size, ifft.get_inbuf());
std::copy(sequence.begin(), sequence.begin() + (fft_size/2), ifft.get_inbuf() + (fft_size/2));
// Run the IFFT
ifft.execute();
// Copy the IFFT'd samples out
std::copy(ifft.get_outbuf(), ifft.get_outbuf() + fft_size, sequence.begin());
// The samples need to be scaled by the FFT size to get the power back down
std::for_each(sequence.begin(), sequence.end(), [fft_size](std::complex<float> & sample){sample /= static_cast<float>(fft_size);});
return sequence;
}
}
}

Wyświetl plik

@ -0,0 +1,5 @@
*~
*.pyc
*.pyo
build*/
examples/grc/*.py

Wyświetl plik

@ -0,0 +1,44 @@
# Copyright 2011 Free Software Foundation, Inc.
#
# This file was generated by gr_modtool, a tool from the GNU Radio framework
# This file is a part of gr-droneid
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
########################################################################
# Include python install macros
########################################################################
include(GrPython)
if(NOT PYTHONINTERP_FOUND)
return()
endif()
add_subdirectory(bindings)
########################################################################
# Install python sources
########################################################################
GR_PYTHON_INSTALL(
FILES
__init__.py
DESTINATION ${GR_PYTHON_DIR}/gnuradio/droneid
)
########################################################################
# Handle the unit tests
########################################################################
include(GrTest)
set(GR_TEST_TARGET_DEPS gnuradio-droneid)
# Create a package directory that tests can import. It includes everything
# from `python/`.
add_custom_target(
copy_module_for_tests ALL
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}
${PROJECT_BINARY_DIR}/test_modules/gnuradio/droneid/
)
GR_ADD_TEST(qa_demodulation ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_demodulation.py)
GR_ADD_TEST(qa_extractor ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_extractor.py)
GR_ADD_TEST(qa_time_sync ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_time_sync.py)

Wyświetl plik

@ -0,0 +1,23 @@
#
# Copyright 2008,2009 Free Software Foundation, Inc.
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# The presence of this file turns this directory into a Python package
'''
This is the GNU Radio DRONEID module. Place your Python package
description here (python/__init__.py).
'''
import os
# import pybind11 generated symbols into the droneid namespace
try:
# this might fail if the module is python-only
from .droneid_python import *
except ModuleNotFoundError:
pass
# import any pure python here
#

Wyświetl plik

@ -0,0 +1,48 @@
# Copyright 2020 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
########################################################################
# Check if there is C++ code at all
########################################################################
if(NOT droneid_sources)
MESSAGE(STATUS "No C++ sources... skipping python bindings")
return()
endif(NOT droneid_sources)
########################################################################
# Check for pygccxml
########################################################################
GR_PYTHON_CHECK_MODULE_RAW(
"pygccxml"
"import pygccxml"
PYGCCXML_FOUND
)
include(GrPybind)
########################################################################
# Python Bindings
########################################################################
list(APPEND droneid_python_files
demodulation_python.cc
extractor_python.cc
time_sync_python.cc
utils_python.cc python_bindings.cc)
GR_PYBIND_MAKE_OOT(droneid
../../..
gr::droneid
"${droneid_python_files}")
# copy bindings extension for use in QA test module
add_custom_command(TARGET droneid_python POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:droneid_python>
${PROJECT_BINARY_DIR}/test_modules/gnuradio/droneid/
)
install(TARGETS droneid_python DESTINATION ${GR_PYTHON_DIR}/gnuradio/droneid COMPONENT pythonapi)

Wyświetl plik

@ -0,0 +1,54 @@
import warnings
import argparse
from gnuradio.bindtool import BindingGenerator
import sys
import tempfile
parser = argparse.ArgumentParser(description='Bind a GR Out of Tree Block')
parser.add_argument('--module', type=str,
help='Name of gr module containing file to bind (e.g. fft digital analog)')
parser.add_argument('--output_dir', default=tempfile.gettempdir(),
help='Output directory of generated bindings')
parser.add_argument('--prefix', help='Prefix of Installed GNU Radio')
parser.add_argument(
'--filename', help="File to be parsed")
parser.add_argument(
'--defines', help='Set additional defines for precompiler', default=(), nargs='*')
parser.add_argument(
'--include', help='Additional Include Dirs, separated', default=(), nargs='*')
parser.add_argument(
'--status', help='Location of output file for general status (used during cmake)', default=None
)
parser.add_argument(
'--flag_automatic', default='0'
)
parser.add_argument(
'--flag_pygccxml', default='0'
)
args = parser.parse_args()
prefix = args.prefix
output_dir = args.output_dir
defines = tuple(','.join(args.defines).split(','))
includes = ','.join(args.include)
name = args.module
namespace = ['gr', name]
prefix_include_root = name
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=DeprecationWarning)
bg = BindingGenerator(prefix, namespace,
prefix_include_root, output_dir, define_symbols=defines, addl_includes=includes,
catch_exceptions=False, write_json_output=False, status_output=args.status,
flag_automatic=True if args.flag_automatic.lower() in [
'1', 'true'] else False,
flag_pygccxml=True if args.flag_pygccxml.lower() in ['1', 'true'] else False)
bg.gen_file_binding(args.filename)

Wyświetl plik

@ -0,0 +1,46 @@
/*
* Copyright 2022 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
/***********************************************************************************/
/* This file is automatically generated using bindtool and can be manually edited */
/* The following lines can be configured to regenerate this file during cmake */
/* If manual edits are made, the following tags should be modified accordingly. */
/* BINDTOOL_GEN_AUTOMATIC(0) */
/* BINDTOOL_USE_PYGCCXML(0) */
/* BINDTOOL_HEADER_FILE(demodulation.h) */
/* BINDTOOL_HEADER_FILE_HASH(5c2868f6605215573194c2a8cd533a01) */
/***********************************************************************************/
#include <pybind11/complex.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
namespace py = pybind11;
#include <gnuradio/droneid/demodulation.h>
// pydoc.h is automatically generated in the build directory
#include <demodulation_pydoc.h>
void bind_demodulation(py::module& m)
{
using demodulation = ::gr::droneid::demodulation;
py::class_<demodulation,
gr::sync_block,
gr::block,
gr::basic_block,
std::shared_ptr<demodulation>>(m, "demodulation", D(demodulation))
.def(py::init(&demodulation::make), py::arg("sample_rate"), D(demodulation, make))
;
}

Wyświetl plik

@ -0,0 +1 @@
This directory stores templates for docstrings that are scraped from the include header files for each block

Wyświetl plik

@ -0,0 +1,24 @@
/*
* Copyright 2022 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "pydoc_macros.h"
#define D(...) DOC(gr, droneid, __VA_ARGS__)
/*
This file contains placeholders for docstrings for the Python bindings.
Do not edit! These were automatically extracted during the binding process
and will be overwritten during the build process
*/
static const char* __doc_gr_droneid_demodulation = R"doc()doc";
static const char* __doc_gr_droneid_demodulation_demodulation = R"doc()doc";
static const char* __doc_gr_droneid_demodulation_make = R"doc()doc";

Wyświetl plik

@ -0,0 +1,24 @@
/*
* Copyright 2022 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "pydoc_macros.h"
#define D(...) DOC(gr, droneid, __VA_ARGS__)
/*
This file contains placeholders for docstrings for the Python bindings.
Do not edit! These were automatically extracted during the binding process
and will be overwritten during the build process
*/
static const char* __doc_gr_droneid_extractor = R"doc()doc";
static const char* __doc_gr_droneid_extractor_extractor = R"doc()doc";
static const char* __doc_gr_droneid_extractor_make = R"doc()doc";

Wyświetl plik

@ -0,0 +1,24 @@
/*
* Copyright 2022 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "pydoc_macros.h"
#define D(...) DOC(gr, droneid, __VA_ARGS__)
/*
This file contains placeholders for docstrings for the Python bindings.
Do not edit! These were automatically extracted during the binding process
and will be overwritten during the build process
*/
static const char* __doc_gr_droneid_time_sync = R"doc()doc";
static const char* __doc_gr_droneid_time_sync_time_sync = R"doc()doc";
static const char* __doc_gr_droneid_time_sync_make = R"doc()doc";

Wyświetl plik

@ -0,0 +1,36 @@
/*
* Copyright 2022 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "pydoc_macros.h"
#define D(...) DOC(gr, droneid, __VA_ARGS__)
/*
This file contains placeholders for docstrings for the Python bindings.
Do not edit! These were automatically extracted during the binding process
and will be overwritten during the build process
*/
static const char* __doc_gr_droneid_utils = R"doc()doc";
static const char* __doc_gr_droneid_utils_utils_0 = R"doc()doc";
static const char* __doc_gr_droneid_utils_utils_1 = R"doc()doc";
static const char* __doc_gr_droneid_utils_get_long_cp_len = R"doc()doc";
static const char* __doc_gr_droneid_utils_get_short_cp_len = R"doc()doc";
static const char* __doc_gr_droneid_utils_get_fft_size = R"doc()doc";
static const char* __doc_gr_droneid_utils_create_zc_sequence = R"doc()doc";

Wyświetl plik

@ -0,0 +1,46 @@
/*
* Copyright 2022 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
/***********************************************************************************/
/* This file is automatically generated using bindtool and can be manually edited */
/* The following lines can be configured to regenerate this file during cmake */
/* If manual edits are made, the following tags should be modified accordingly. */
/* BINDTOOL_GEN_AUTOMATIC(0) */
/* BINDTOOL_USE_PYGCCXML(0) */
/* BINDTOOL_HEADER_FILE(extractor.h) */
/* BINDTOOL_HEADER_FILE_HASH(66664a7627c5dee6914aba6335671c77) */
/***********************************************************************************/
#include <pybind11/complex.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
namespace py = pybind11;
#include <gnuradio/droneid/extractor.h>
// pydoc.h is automatically generated in the build directory
#include <extractor_pydoc.h>
void bind_extractor(py::module& m)
{
using extractor = ::gr::droneid::extractor;
py::class_<extractor,
gr::sync_block,
gr::block,
gr::basic_block,
std::shared_ptr<extractor>>(m, "extractor", D(extractor))
.def(py::init(&extractor::make), py::arg("sample_rate"), D(extractor, make))
;
}

Wyświetl plik

@ -0,0 +1,2 @@
./include/gnuradio/droneid/extractor.hError occurred while running CASTXML xml file does not exist
./include/gnuradio/droneid/utils.hError occurred while running CASTXML xml file does not exist

Wyświetl plik

@ -0,0 +1,80 @@
# Utilities for reading values in header files
from argparse import ArgumentParser
import re
class PybindHeaderParser:
def __init__(self, pathname):
with open(pathname, 'r') as f:
self.file_txt = f.read()
def get_flag_automatic(self):
# p = re.compile(r'BINDTOOL_GEN_AUTOMATIC\(([^\s])\)')
# m = p.search(self.file_txt)
m = re.search(r'BINDTOOL_GEN_AUTOMATIC\(([^\s])\)', self.file_txt)
if (m and m.group(1) == '1'):
return True
else:
return False
def get_flag_pygccxml(self):
# p = re.compile(r'BINDTOOL_USE_PYGCCXML\(([^\s])\)')
# m = p.search(self.file_txt)
m = re.search(r'BINDTOOL_USE_PYGCCXML\(([^\s])\)', self.file_txt)
if (m and m.group(1) == '1'):
return True
else:
return False
def get_header_filename(self):
# p = re.compile(r'BINDTOOL_HEADER_FILE\(([^\s]*)\)')
# m = p.search(self.file_txt)
m = re.search(r'BINDTOOL_HEADER_FILE\(([^\s]*)\)', self.file_txt)
if (m):
return m.group(1)
else:
return None
def get_header_file_hash(self):
# p = re.compile(r'BINDTOOL_HEADER_FILE_HASH\(([^\s]*)\)')
# m = p.search(self.file_txt)
m = re.search(r'BINDTOOL_HEADER_FILE_HASH\(([^\s]*)\)', self.file_txt)
if (m):
return m.group(1)
else:
return None
def get_flags(self):
return f'{self.get_flag_automatic()};{self.get_flag_pygccxml()};{self.get_header_filename()};{self.get_header_file_hash()};'
def argParse():
"""Parses commandline args."""
desc = 'Reads the parameters from the comment block in the pybind files'
parser = ArgumentParser(description=desc)
parser.add_argument("function", help="Operation to perform on comment block of pybind file", choices=[
"flag_auto", "flag_pygccxml", "header_filename", "header_file_hash", "all"])
parser.add_argument(
"pathname", help="Pathname of pybind c++ file to read, e.g. blockname_python.cc")
return parser.parse_args()
if __name__ == "__main__":
# Parse command line options and set up doxyxml.
args = argParse()
pbhp = PybindHeaderParser(args.pathname)
if args.function == "flag_auto":
print(pbhp.get_flag_automatic())
elif args.function == "flag_pygccxml":
print(pbhp.get_flag_pygccxml())
elif args.function == "header_filename":
print(pbhp.get_header_filename())
elif args.function == "header_file_hash":
print(pbhp.get_header_file_hash())
elif args.function == "all":
print(pbhp.get_flags())

Wyświetl plik

@ -0,0 +1,61 @@
/*
* Copyright 2020 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include <pybind11/pybind11.h>
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <numpy/arrayobject.h>
namespace py = pybind11;
// Headers for binding functions
/**************************************/
// The following comment block is used for
// gr_modtool to insert function prototypes
// Please do not delete
/**************************************/
// BINDING_FUNCTION_PROTOTYPES(
void bind_demodulation(py::module& m);
void bind_extractor(py::module& m);
void bind_time_sync(py::module& m);
void bind_utils(py::module& m);
// ) END BINDING_FUNCTION_PROTOTYPES
// We need this hack because import_array() returns NULL
// for newer Python versions.
// This function is also necessary because it ensures access to the C API
// and removes a warning.
void* init_numpy()
{
import_array();
return NULL;
}
PYBIND11_MODULE(droneid_python, m)
{
// Initialize the numpy C API
// (otherwise we will see segmentation faults)
init_numpy();
// Allow access to base block methods
py::module::import("gnuradio.gr");
/**************************************/
// The following comment block is used for
// gr_modtool to insert binding function calls
// Please do not delete
/**************************************/
// BINDING_FUNCTION_CALLS(
bind_demodulation(m);
bind_extractor(m);
bind_time_sync(m);
bind_utils(m);
// ) END BINDING_FUNCTION_CALLS
}

Wyświetl plik

@ -0,0 +1,46 @@
/*
* Copyright 2022 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
/***********************************************************************************/
/* This file is automatically generated using bindtool and can be manually edited */
/* The following lines can be configured to regenerate this file during cmake */
/* If manual edits are made, the following tags should be modified accordingly. */
/* BINDTOOL_GEN_AUTOMATIC(0) */
/* BINDTOOL_USE_PYGCCXML(0) */
/* BINDTOOL_HEADER_FILE(time_sync.h) */
/* BINDTOOL_HEADER_FILE_HASH(a826484d77978013b16512bd464ca13a) */
/***********************************************************************************/
#include <pybind11/complex.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
namespace py = pybind11;
#include <gnuradio/droneid/time_sync.h>
// pydoc.h is automatically generated in the build directory
#include <time_sync_pydoc.h>
void bind_time_sync(py::module& m)
{
using time_sync = ::gr::droneid::time_sync;
py::class_<time_sync,
gr::sync_block,
gr::block,
gr::basic_block,
std::shared_ptr<time_sync>>(m, "time_sync", D(time_sync))
.def(py::init(&time_sync::make), py::arg("sample_rate"), D(time_sync, make))
;
}

Wyświetl plik

@ -0,0 +1,67 @@
/*
* Copyright 2022 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
/***********************************************************************************/
/* This file is automatically generated using bindtool and can be manually edited */
/* The following lines can be configured to regenerate this file during cmake */
/* If manual edits are made, the following tags should be modified accordingly. */
/* BINDTOOL_GEN_AUTOMATIC(0) */
/* BINDTOOL_USE_PYGCCXML(0) */
/* BINDTOOL_HEADER_FILE(utils.h) */
/* BINDTOOL_HEADER_FILE_HASH(016d4ede7bb4151a0742f95f1a071c17) */
/***********************************************************************************/
#include <pybind11/complex.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
namespace py = pybind11;
#include <gnuradio/droneid/utils.h>
// pydoc.h is automatically generated in the build directory
#include <utils_pydoc.h>
void bind_utils(py::module& m)
{
using utils = ::gr::droneid::utils;
py::class_<utils, std::shared_ptr<utils>>(m, "utils", D(utils))
.def(py::init<>(), D(utils, utils, 0))
.def(py::init<gr::droneid::utils const&>(), py::arg("arg0"), D(utils, utils, 1))
.def_static("get_long_cp_len",
&utils::get_long_cp_len,
py::arg("sample_rate"),
D(utils, get_long_cp_len))
.def_static("get_short_cp_len",
&utils::get_short_cp_len,
py::arg("sample_rate"),
D(utils, get_short_cp_len))
.def_static("get_fft_size",
&utils::get_fft_size,
py::arg("sample_rate"),
D(utils, get_fft_size))
.def_static("create_zc_sequence",
&utils::create_zc_sequence,
py::arg("sample_rate"),
py::arg("root"),
D(utils, create_zc_sequence))
;
}

Wyświetl plik

@ -0,0 +1,39 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2022 gr-droneid author.
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
from gnuradio import gr, gr_unittest
# from gnuradio import blocks
try:
from gnuradio.droneid import demodulation
except ImportError:
import os
import sys
dirname, filename = os.path.split(os.path.abspath(__file__))
sys.path.append(os.path.join(dirname, "bindings"))
from gnuradio.droneid import demodulation
class qa_demodulation(gr_unittest.TestCase):
def setUp(self):
self.tb = gr.top_block()
def tearDown(self):
self.tb = None
def test_instance(self):
# FIXME: Test will fail until you pass sensible arguments to the constructor
instance = demodulation()
def test_001_descriptive_test_name(self):
# set up fg
self.tb.run()
# check data
if __name__ == '__main__':
gr_unittest.run(qa_demodulation)

Wyświetl plik

@ -0,0 +1,39 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2022 gr-droneid author.
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
from gnuradio import gr, gr_unittest
# from gnuradio import blocks
try:
from gnuradio.droneid import extractor
except ImportError:
import os
import sys
dirname, filename = os.path.split(os.path.abspath(__file__))
sys.path.append(os.path.join(dirname, "bindings"))
from gnuradio.droneid import extractor
class qa_extractor(gr_unittest.TestCase):
def setUp(self):
self.tb = gr.top_block()
def tearDown(self):
self.tb = None
def test_instance(self):
# FIXME: Test will fail until you pass sensible arguments to the constructor
instance = extractor()
def test_001_descriptive_test_name(self):
# set up fg
self.tb.run()
# check data
if __name__ == '__main__':
gr_unittest.run(qa_extractor)

Wyświetl plik

@ -0,0 +1,39 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2022 gr-droneid author.
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
from gnuradio import gr, gr_unittest
# from gnuradio import blocks
try:
from gnuradio.droneid import time_sync
except ImportError:
import os
import sys
dirname, filename = os.path.split(os.path.abspath(__file__))
sys.path.append(os.path.join(dirname, "bindings"))
from gnuradio.droneid import time_sync
class qa_time_sync(gr_unittest.TestCase):
def setUp(self):
self.tb = gr.top_block()
def tearDown(self):
self.tb = None
def test_instance(self):
# FIXME: Test will fail until you pass sensible arguments to the constructor
instance = time_sync()
def test_001_descriptive_test_name(self):
# set up fg
self.tb.run()
# check data
if __name__ == '__main__':
gr_unittest.run(qa_time_sync)