GNU Radio 3.8 support

https://wiki.gnuradio.org/index.php/GNU_Radio_3.8_OOT_Module_Porting_Guide

Change-Id: I23dd638c8c48ed0a4b50559ce33fbd5e60b7dcbc
diff --git a/docs/doxygen/doxyxml/__init__.py b/docs/doxygen/doxyxml/__init__.py
index 5cd0b3c..3b0a580 100644
--- a/docs/doxygen/doxyxml/__init__.py
+++ b/docs/doxygen/doxyxml/__init__.py
@@ -1,7 +1,8 @@
 #
 # Copyright 2010 Free Software Foundation, Inc.
 #
-# This file is part of GNU Radio
+# This file was generated by gr_modtool, a tool from the GNU Radio framework
+# This file is a part of gr-gsm
 #
 # GNU Radio is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -63,8 +64,9 @@
 u'Outputs the vital aadvark statistics.'
 
 """
+from __future__ import unicode_literals
 
-from doxyindex import DoxyIndex, DoxyFunction, DoxyParam, DoxyClass, DoxyFile, DoxyNamespace, DoxyGroup, DoxyFriend, DoxyOther
+from .doxyindex import DoxyIndex, DoxyFunction, DoxyParam, DoxyClass, DoxyFile, DoxyNamespace, DoxyGroup, DoxyFriend, DoxyOther
 
 def _test():
     import os
diff --git a/docs/doxygen/doxyxml/base.py b/docs/doxygen/doxyxml/base.py
index e8f026a..071d8f1 100644
--- a/docs/doxygen/doxyxml/base.py
+++ b/docs/doxygen/doxyxml/base.py
@@ -1,7 +1,8 @@
 #
 # Copyright 2010 Free Software Foundation, Inc.
 #
-# This file is part of GNU Radio
+# This file was generated by gr_modtool, a tool from the GNU Radio framework
+# This file is a part of gr-gsm
 #
 # GNU Radio is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -24,24 +25,26 @@
 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
 
 from xml.parsers.expat import ExpatError
 
-from generated import compound
+from .generated import compound
 
 
 class Base(object):
 
-    class Duplicate(StandardError):
+    class Duplicate(Exception):
         pass
 
-    class NoSuchMember(StandardError):
+    class NoSuchMember(Exception):
         pass
 
-    class ParsingError(StandardError):
+    class ParsingError(Exception):
         pass
 
     def __init__(self, parse_data, top=None):
@@ -94,7 +97,7 @@
         for cls in self.mem_classes:
             if cls.can_parse(mem):
                 return cls
-        raise StandardError(("Did not find a class for object '%s'." \
+        raise Exception(("Did not find a class for object '%s'." \
                                  % (mem.get_name())))
 
     def convert_mem(self, mem):
@@ -102,11 +105,11 @@
             cls = self.get_cls(mem)
             converted = cls.from_parse_data(mem, self.top)
             if converted is None:
-                raise StandardError('No class matched this object.')
+                raise Exception('No class matched this object.')
             self.add_ref(converted)
             return converted
-        except StandardError, e:
-            print e
+        except Exception as e:
+            print(e)
 
     @classmethod
     def includes(cls, inst):
diff --git a/docs/doxygen/doxyxml/doxyindex.py b/docs/doxygen/doxyxml/doxyindex.py
index 0132ab8..e00729e 100644
--- a/docs/doxygen/doxyxml/doxyindex.py
+++ b/docs/doxygen/doxyxml/doxyindex.py
@@ -1,7 +1,8 @@
 #
 # Copyright 2010 Free Software Foundation, Inc.
 #
-# This file is part of GNU Radio
+# This file was generated by gr_modtool, a tool from the GNU Radio framework
+# This file is a part of gr-gsm
 #
 # GNU Radio is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -22,12 +23,14 @@
 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
 
-from generated import index
-from base import Base
-from text import description
+from .generated import index
+from .base import Base
+from .text import description
 
 class DoxyIndex(Base):
     """
@@ -43,13 +46,16 @@
         self._root = index.parse(os.path.join(self._xml_path, 'index.xml'))
         for mem in self._root.compound:
             converted = self.convert_mem(mem)
-            # For files we want the contents to be accessible directly
-            # from the parent rather than having to go through the file
-            # object.
+            # For files and namespaces we want the contents to be
+            # accessible directly from the parent rather than having
+            # to go through the file object.
             if self.get_cls(mem) == DoxyFile:
                 if mem.name.endswith('.h'):
                     self._members += converted.members()
                     self._members.append(converted)
+            elif self.get_cls(mem) == DoxyNamespace:
+                self._members += converted.members()
+                self._members.append(converted)
             else:
                 self._members.append(converted)
 
@@ -80,13 +86,29 @@
         self._data['brief_description'] = bd
         self._data['detailed_description'] = dd
 
+    def set_parameters(self, data):
+        vs = [ddc.value for ddc in data.detaileddescription.content_]
+        pls = []
+        for v in vs:
+            if hasattr(v, 'parameterlist'):
+                pls += v.parameterlist
+        pis = []
+        for pl in pls:
+            pis += pl.parameteritem
+        dpis = []
+        for pi in pis:
+            dpi = DoxyParameterItem(pi)
+            dpi._parse()
+            dpis.append(dpi)
+        self._data['params'] = dpis
+
+
 class DoxyCompound(DoxyCompMem):
     pass
 
 class DoxyMember(DoxyCompMem):
     pass
 
-
 class DoxyFunction(DoxyMember):
 
     __module__ = "gnuradio.utils.doxyxml"
@@ -98,10 +120,13 @@
             return
         super(DoxyFunction, self)._parse()
         self.set_descriptions(self._parse_data)
-        self._data['params'] = []
-        prms = self._parse_data.param
-        for prm in prms:
-            self._data['params'].append(DoxyParam(prm))
+        self.set_parameters(self._parse_data)
+        if not self._data['params']:
+            # If the params weren't set by a comment then just grab the names.
+            self._data['params'] = []
+            prms = self._parse_data.param
+            for prm in prms:
+                self._data['params'].append(DoxyParam(prm))
 
     brief_description = property(lambda self: self.data()['brief_description'])
     detailed_description = property(lambda self: self.data()['detailed_description'])
@@ -121,9 +146,39 @@
         self.set_descriptions(self._parse_data)
         self._data['declname'] = self._parse_data.declname
 
+    @property
+    def description(self):
+        descriptions = []
+        if self.brief_description:
+            descriptions.append(self.brief_description)
+        if self.detailed_description:
+            descriptions.append(self.detailed_description)
+        return '\n\n'.join(descriptions)
+
     brief_description = property(lambda self: self.data()['brief_description'])
     detailed_description = property(lambda self: self.data()['detailed_description'])
-    declname = property(lambda self: self.data()['declname'])
+    name = property(lambda self: self.data()['declname'])
+
+class DoxyParameterItem(DoxyMember):
+    """A different representation of a parameter in Doxygen."""
+
+    def _parse(self):
+        if self._parsed:
+            return
+        super(DoxyParameterItem, self)._parse()
+        names = []
+        for nl in self._parse_data.parameternamelist:
+            for pn in nl.parametername:
+                names.append(description(pn))
+        # Just take first name
+        self._data['name'] = names[0]
+        # Get description
+        pd = description(self._parse_data.get_parameterdescription())
+        self._data['description'] = pd
+
+    description = property(lambda self: self.data()['description'])
+    name = property(lambda self: self.data()['name'])
+
 
 class DoxyClass(DoxyCompound):
 
@@ -139,12 +194,14 @@
         if self._error:
             return
         self.set_descriptions(self._retrieved_data.compounddef)
+        self.set_parameters(self._retrieved_data.compounddef)
         # Sectiondef.kind tells about whether private or public.
         # We just ignore this for now.
         self.process_memberdefs()
 
     brief_description = property(lambda self: self.data()['brief_description'])
     detailed_description = property(lambda self: self.data()['detailed_description'])
+    params = property(lambda self: self.data()['params'])
 
 Base.mem_classes.append(DoxyClass)
 
@@ -177,6 +234,16 @@
 
     kind = 'namespace'
 
+    def _parse(self):
+        if self._parsed:
+            return
+        super(DoxyNamespace, self)._parse()
+        self.retrieve_data()
+        self.set_descriptions(self._retrieved_data.compounddef)
+        if self._error:
+            return
+        self.process_memberdefs()
+
 Base.mem_classes.append(DoxyNamespace)
 
 
@@ -227,11 +294,11 @@
 
     __module__ = "gnuradio.utils.doxyxml"
 
-    kinds = set(['variable', 'struct', 'union', 'define', 'typedef', 'enum', 'dir', 'page'])
+    kinds = set(['variable', 'struct', 'union', 'define', 'typedef', 'enum',
+                 'dir', 'page', 'signal', 'slot', 'property'])
 
     @classmethod
     def can_parse(cls, obj):
         return obj.kind in cls.kinds
 
 Base.mem_classes.append(DoxyOther)
-
diff --git a/docs/doxygen/doxyxml/generated/__init__.py b/docs/doxygen/doxyxml/generated/__init__.py
index 3982397..23095c1 100644
--- a/docs/doxygen/doxyxml/generated/__init__.py
+++ b/docs/doxygen/doxyxml/generated/__init__.py
@@ -5,3 +5,4 @@
 resultant classes are not very friendly to navigate so the rest of the
 doxyxml module processes them further.
 """
+from __future__ import unicode_literals
diff --git a/docs/doxygen/doxyxml/generated/compound.py b/docs/doxygen/doxyxml/generated/compound.py
index 1522ac2..de4f506 100644
--- a/docs/doxygen/doxyxml/generated/compound.py
+++ b/docs/doxygen/doxyxml/generated/compound.py
@@ -1,17 +1,19 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 """
 Generated Mon Feb  9 19:08:05 2009 by generateDS.py.
 """
+from __future__ import absolute_import
+from __future__ import unicode_literals
 
-from string import lower as str_lower
+
 from xml.dom import minidom
 from xml.dom import Node
 
 import sys
 
-import compoundsuper as supermod
-from compoundsuper import MixedContainer
+from . import compoundsuper as supermod
+from .compoundsuper import MixedContainer
 
 
 class DoxygenTypeSub(supermod.DoxygenType):
diff --git a/docs/doxygen/doxyxml/generated/compoundsuper.py b/docs/doxygen/doxyxml/generated/compoundsuper.py
index 6255dda..b68978f 100644
--- a/docs/doxygen/doxyxml/generated/compoundsuper.py
+++ b/docs/doxygen/doxyxml/generated/compoundsuper.py
@@ -1,15 +1,20 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 #
 # Generated Thu Jun 11 18:44:25 2009 by generateDS.py.
 #
 
+from __future__ import print_function
+from __future__ import unicode_literals
+
 import sys
-import getopt
-from string import lower as str_lower
+
 from xml.dom import minidom
 from xml.dom import Node
 
+import six
+
+
 #
 # User methods
 #
@@ -19,9 +24,9 @@
 
 try:
     from generatedssuper import GeneratedsSuper
-except ImportError, exp:
+except ImportError as exp:
 
-    class GeneratedsSuper:
+    class GeneratedsSuper(object):
         def format_string(self, input_data, input_name=''):
             return input_data
         def format_integer(self, input_data, input_name=''):
@@ -64,7 +69,7 @@
         outfile.write('    ')
 
 def quote_xml(inStr):
-    s1 = (isinstance(inStr, basestring) and inStr or
+    s1 = (isinstance(inStr, six.string_types) and inStr or
           '%s' % inStr)
     s1 = s1.replace('&', '&')
     s1 = s1.replace('<', '&lt;')
@@ -72,7 +77,7 @@
     return s1
 
 def quote_attrib(inStr):
-    s1 = (isinstance(inStr, basestring) and inStr or
+    s1 = (isinstance(inStr, six.string_types) and inStr or
           '%s' % inStr)
     s1 = s1.replace('&', '&amp;')
     s1 = s1.replace('<', '&lt;')
@@ -102,7 +107,7 @@
             return '"""%s"""' % s1
 
 
-class MixedContainer:
+class MixedContainer(object):
     # Constants for category:
     CategoryNone = 0
     CategoryText = 1
@@ -4221,7 +4226,7 @@
         if attrs.get('lineno'):
             try:
                 self.lineno = int(attrs.get('lineno').value)
-            except ValueError, exp:
+            except ValueError as exp:
                 raise ValueError('Bad integer attribute (lineno): %s' % exp)
         if attrs.get('refkind'):
             self.refkind = attrs.get('refkind').value
@@ -4504,12 +4509,12 @@
         if attrs.get('endline'):
             try:
                 self.endline = int(attrs.get('endline').value)
-            except ValueError, exp:
+            except ValueError as exp:
                 raise ValueError('Bad integer attribute (endline): %s' % exp)
         if attrs.get('startline'):
             try:
                 self.startline = int(attrs.get('startline').value)
-            except ValueError, exp:
+            except ValueError as exp:
                 raise ValueError('Bad integer attribute (startline): %s' % exp)
         if attrs.get('refid'):
             self.refid = attrs.get('refid').value
@@ -4627,17 +4632,17 @@
         if attrs.get('bodystart'):
             try:
                 self.bodystart = int(attrs.get('bodystart').value)
-            except ValueError, exp:
+            except ValueError as exp:
                 raise ValueError('Bad integer attribute (bodystart): %s' % exp)
         if attrs.get('line'):
             try:
                 self.line = int(attrs.get('line').value)
-            except ValueError, exp:
+            except ValueError as exp:
                 raise ValueError('Bad integer attribute (line): %s' % exp)
         if attrs.get('bodyend'):
             try:
                 self.bodyend = int(attrs.get('bodyend').value)
-            except ValueError, exp:
+            except ValueError as exp:
                 raise ValueError('Bad integer attribute (bodyend): %s' % exp)
         if attrs.get('bodyfile'):
             self.bodyfile = attrs.get('bodyfile').value
@@ -6778,12 +6783,12 @@
         if attrs.get('rows'):
             try:
                 self.rows = int(attrs.get('rows').value)
-            except ValueError, exp:
+            except ValueError as exp:
                 raise ValueError('Bad integer attribute (rows): %s' % exp)
         if attrs.get('cols'):
             try:
                 self.cols = int(attrs.get('cols').value)
-            except ValueError, exp:
+            except ValueError as exp:
                 raise ValueError('Bad integer attribute (cols): %s' % exp)
     def buildChildren(self, child_, nodeName_):
         if child_.nodeType == Node.ELEMENT_NODE and \
@@ -7108,7 +7113,7 @@
         if attrs.get('level'):
             try:
                 self.level = int(attrs.get('level').value)
-            except ValueError, exp:
+            except ValueError as exp:
                 raise ValueError('Bad integer attribute (level): %s' % exp)
     def buildChildren(self, child_, nodeName_):
         if child_.nodeType == Node.TEXT_NODE:
@@ -8283,7 +8288,7 @@
 """
 
 def usage():
-    print USAGE_TEXT
+    print(USAGE_TEXT)
     sys.exit(1)
 
 
@@ -8339,4 +8344,3 @@
     main()
     #import pdb
     #pdb.run('main()')
-
diff --git a/docs/doxygen/doxyxml/generated/index.py b/docs/doxygen/doxyxml/generated/index.py
index 7a70e14..5b54c66 100644
--- a/docs/doxygen/doxyxml/generated/index.py
+++ b/docs/doxygen/doxyxml/generated/index.py
@@ -1,16 +1,18 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 """
 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
 
 import os
 import sys
-import compound
+from . import compound
 
-import indexsuper as supermod
+from . import indexsuper as supermod
 
 class DoxygenTypeSub(supermod.DoxygenType):
     def __init__(self, version=None, compound=None):
diff --git a/docs/doxygen/doxyxml/generated/indexsuper.py b/docs/doxygen/doxyxml/generated/indexsuper.py
index a991530..2400d81 100644
--- a/docs/doxygen/doxyxml/generated/indexsuper.py
+++ b/docs/doxygen/doxyxml/generated/indexsuper.py
@@ -1,15 +1,19 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 #
 # Generated Thu Jun 11 18:43:54 2009 by generateDS.py.
 #
 
+from __future__ import print_function
+from __future__ import unicode_literals
+
 import sys
-import getopt
-from string import lower as str_lower
+
 from xml.dom import minidom
 from xml.dom import Node
 
+import six
+
 #
 # User methods
 #
@@ -19,9 +23,9 @@
 
 try:
     from generatedssuper import GeneratedsSuper
-except ImportError, exp:
+except ImportError as exp:
 
-    class GeneratedsSuper:
+    class GeneratedsSuper(object):
         def format_string(self, input_data, input_name=''):
             return input_data
         def format_integer(self, input_data, input_name=''):
@@ -64,7 +68,7 @@
         outfile.write('    ')
 
 def quote_xml(inStr):
-    s1 = (isinstance(inStr, basestring) and inStr or
+    s1 = (isinstance(inStr, six.string_types) and inStr or
           '%s' % inStr)
     s1 = s1.replace('&', '&amp;')
     s1 = s1.replace('<', '&lt;')
@@ -72,7 +76,7 @@
     return s1
 
 def quote_attrib(inStr):
-    s1 = (isinstance(inStr, basestring) and inStr or
+    s1 = (isinstance(inStr, six.string_types) and inStr or
           '%s' % inStr)
     s1 = s1.replace('&', '&amp;')
     s1 = s1.replace('<', '&lt;')
@@ -102,7 +106,7 @@
             return '"""%s"""' % s1
 
 
-class MixedContainer:
+class MixedContainer(object):
     # Constants for category:
     CategoryNone = 0
     CategoryText = 1
@@ -462,7 +466,7 @@
 """
 
 def usage():
-    print USAGE_TEXT
+    print(USAGE_TEXT)
     sys.exit(1)
 
 
@@ -520,4 +524,3 @@
     main()
     #import pdb
     #pdb.run('main()')
-
diff --git a/docs/doxygen/doxyxml/text.py b/docs/doxygen/doxyxml/text.py
index 629edd1..9cb7b4d 100644
--- a/docs/doxygen/doxyxml/text.py
+++ b/docs/doxygen/doxyxml/text.py
@@ -1,7 +1,8 @@
 #
 # Copyright 2010 Free Software Foundation, Inc.
 #
-# This file is part of GNU Radio
+# This file was generated by gr_modtool, a tool from the GNU Radio framework
+# This file is a part of gr-gsm
 #
 # GNU Radio is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -21,12 +22,13 @@
 """
 Utilities for extracting text from generated classes.
 """
+from __future__ import unicode_literals
 
 def is_string(txt):
     if isinstance(txt, str):
         return True
     try:
-        if isinstance(txt, unicode):
+        if isinstance(txt, str):
             return True
     except NameError:
         pass
@@ -49,7 +51,7 @@
     elif is_string(obj):
         return obj
     else:
-        raise StandardError('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"