aports/testing/gr-osmosdr/gnuradio-3.9-compat.patch
psykose afbfbf2300 testing/gr-osmosdr: rebuild against py3.10/gnuradio
use patches for early gnuradio 3.9 support
2021-12-25 13:42:39 +00:00

2299 lines
70 KiB
Diff

From 0d727b3ef8ea56132fd538c9aa54b671950e1297 Mon Sep 17 00:00:00 2001
From: Matt Mills <mmills@2bn.net>
Date: Thu, 29 Oct 2020 18:28:13 -0600
Subject: Replace swig with pybind11 for gr3.9 master compat
Signed-off-by: Eric Wild <ewild@sysmocom.de>
---
CMakeLists.txt | 16 +-
docs/doxygen/pydoc_macros.h | 19 ++
docs/doxygen/swig_doc.py | 332 --------------------
docs/doxygen/update_pydoc.py | 346 +++++++++++++++++++++
python/CMakeLists.txt | 20 +-
python/__init__.py | 29 +-
python/bindings/CMakeLists.txt | 30 ++
python/bindings/README.md | 0
python/bindings/bind_oot_file.py | 53 ++++
python/bindings/docstrings/README.md | 1 +
python/bindings/docstrings/sink_pydoc_template.h | 153 +++++++++
python/bindings/docstrings/source_pydoc_template.h | 162 ++++++++++
python/bindings/header_utils.py | 78 +++++
python/bindings/python_bindings.cc | 57 ++++
python/bindings/sink_python.cc | 320 +++++++++++++++++++
python/bindings/source_python.cc | 342 ++++++++++++++++++++
swig/CMakeLists.txt | 57 ----
swig/osmosdr_swig.i | 82 -----
18 files changed, 1583 insertions(+), 514 deletions(-)
create mode 100644 docs/doxygen/pydoc_macros.h
delete mode 100644 docs/doxygen/swig_doc.py
create mode 100644 docs/doxygen/update_pydoc.py
create mode 100644 python/bindings/CMakeLists.txt
create mode 100644 python/bindings/README.md
create mode 100644 python/bindings/bind_oot_file.py
create mode 100644 python/bindings/docstrings/README.md
create mode 100644 python/bindings/docstrings/sink_pydoc_template.h
create mode 100644 python/bindings/docstrings/source_pydoc_template.h
create mode 100644 python/bindings/header_utils.py
create mode 100644 python/bindings/python_bindings.cc
create mode 100644 python/bindings/sink_python.cc
create mode 100644 python/bindings/source_python.cc
delete mode 100644 swig/CMakeLists.txt
delete mode 100644 swig/osmosdr_swig.i
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 74c54f5..b4bb535 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -41,7 +41,7 @@ set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules)
# Find GNURadio (pmt and runtime are core, always included)
-find_package(Gnuradio "3.8" REQUIRED COMPONENTS blocks fft filter)
+find_package(Gnuradio "3.9" REQUIRED COMPONENTS blocks fft filter)
# Set the version information here
set(VERSION_MAJOR 0)
@@ -188,20 +188,11 @@ find_package(Doxygen)
##########
find_package(PythonLibs 3)
-find_package(SWIG)
-
-if(SWIG_FOUND)
- message(STATUS "Minimum SWIG version required is 1.3.31")
- set(SWIG_VERSION_CHECK FALSE)
- if("${SWIG_VERSION}" VERSION_GREATER "1.3.30")
- set(SWIG_VERSION_CHECK TRUE)
- endif()
-endif(SWIG_FOUND)
+find_package(pybind11)
GR_REGISTER_COMPONENT("Python support" ENABLE_PYTHON
PYTHONLIBS_FOUND
- SWIG_FOUND
- SWIG_VERSION_CHECK
+ pybind11_FOUND
)
########################################################################
@@ -269,7 +260,6 @@ add_custom_target(uninstall
add_subdirectory(include/osmosdr)
add_subdirectory(lib)
if(ENABLE_PYTHON)
- add_subdirectory(swig)
add_subdirectory(python)
add_subdirectory(grc)
add_subdirectory(apps)
diff --git a/docs/doxygen/pydoc_macros.h b/docs/doxygen/pydoc_macros.h
new file mode 100644
index 0000000..98bf7cd
--- /dev/null
+++ b/docs/doxygen/pydoc_macros.h
@@ -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
\ No newline at end of file
diff --git a/docs/doxygen/swig_doc.py b/docs/doxygen/swig_doc.py
deleted file mode 100644
index e3b308e..0000000
--- a/docs/doxygen/swig_doc.py
+++ /dev/null
@@ -1,332 +0,0 @@
-#
-# 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-osmosdr
-#
-# 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.
-#
-# 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
-
-The file instructs SWIG to transfer the doxygen comments into the
-python docstrings.
-
-"""
-from __future__ import unicode_literals
-
-import sys, time
-
-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:])
-
-
-class Block(object):
- """
- Checks if doxyxml produced objects correspond to a gnuradio block.
- """
-
- @classmethod
- def includes(cls, item):
- if not isinstance(item, DoxyClass):
- return False
- # Check for a parsing error.
- if item.error():
- return False
- friendname = make_name(item.name())
- is_a_block = item.has_member(friendname, DoxyFriend)
- # But now sometimes the make function isn't a friend so check again.
- if not is_a_block:
- is_a_block = di.has_member(friendname, DoxyFunction)
- return is_a_block
-
-class Block2(object):
- """
- Checks if doxyxml produced objects correspond to a new style
- gnuradio block.
- """
-
- @classmethod
- def includes(cls, item):
- if not isinstance(item, DoxyClass):
- return False
- # Check for a parsing error.
- if item.error():
- return False
- is_a_block2 = item.has_member('make', DoxyFunction) and item.has_member('sptr', DoxyOther)
- return is_a_block2
-
-
-def utoascii(text):
- """
- Convert unicode text into ascii and escape quotes and backslashes.
- """
- if text is None:
- return ''
- out = text.encode('ascii', 'replace')
- # swig will require us to replace blackslash with 4 backslashes
- out = out.replace(b'\\', b'\\\\\\\\')
- out = out.replace(b'"', b'\\"').decode('ascii')
- return str(out)
-
-
-def combine_descriptions(obj):
- """
- Combines the brief and detailed descriptions of an object together.
- """
- description = []
- bd = obj.brief_description.strip()
- dd = obj.detailed_description.strip()
- if bd:
- description.append(bd)
- if dd:
- description.append(dd)
- return utoascii('\n\n'.join(description)).strip()
-
-def format_params(parameteritems):
- output = ['Args:']
- template = ' {0} : {1}'
- for pi in parameteritems:
- output.append(template.format(pi.name, pi.description))
- return '\n'.join(output)
-
-entry_templ = '%feature("docstring") {name} "{docstring}"'
-def make_entry(obj, name=None, templ="{description}", description=None, params=[]):
- """
- Create a docstring entry for a swig interface file.
-
- obj - a doxyxml object from which documentation will be extracted.
- name - the name of the C object (defaults to obj.name())
- templ - an optional template for the docstring containing only one
- variable named 'description'.
- description - if this optional variable is set then it's value is
- used as the description instead of extracting it from obj.
- """
- if name is None:
- name=obj.name()
- if "operator " in name:
- return ''
- if description is None:
- description = combine_descriptions(obj)
- if params:
- description += '\n\n'
- description += utoascii(format_params(params))
- docstring = templ.format(description=description)
- if not docstring:
- return ''
- 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)
-
-
-def make_class_entry(klass, description=None, ignored_methods=[], params=None):
- """
- Create a class docstring for a swig interface file.
- """
- if params is None:
- params = klass.params
- output = []
- output.append(make_entry(klass, description=description, 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)
-
-
-def make_block_entry(di, block):
- """
- Create class and function docstrings of a gnuradio block for a
- swig interface file.
- """
- descriptions = []
- # Get the documentation associated with the class.
- class_desc = combine_descriptions(block)
- if class_desc:
- descriptions.append(class_desc)
- # Get the documentation associated with the make function
- make_func = di.get_member(make_name(block.name()), DoxyFunction)
- make_func_desc = combine_descriptions(make_func)
- if make_func_desc:
- descriptions.append(make_func_desc)
- # Get the documentation associated with the file
- try:
- block_file = di.get_member(block.name() + ".h", DoxyFile)
- file_desc = combine_descriptions(block_file)
- if file_desc:
- descriptions.append(file_desc)
- except base.Base.NoSuchMember:
- # Don't worry if we can't find a matching file.
- pass
- # And join them all together to make a super duper description.
- 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)
-
-def make_block2_entry(di, block):
- """
- Create class and function docstrings of a new style gnuradio block for a
- swig interface file.
- """
- descriptions = []
- # For new style blocks all the relevant documentation should be
- # associated with the 'make' method.
- class_description = combine_descriptions(block)
- make_func = block.get_member('make', DoxyFunction)
- make_description = combine_descriptions(make_func)
- description = class_description + "\n\nConstructor Specific Documentation:\n\n" + make_description
- # Associate the combined description with the class and
- # the make function.
- output = []
- output.append(make_class_entry(
- block, description=description,
- ignored_methods=['make'], params=make_func.params))
- makename = block.name() + '::make'
- output.append(make_func_entry(
- make_func, name=makename, description=description,
- params=make_func.params))
- return "\n\n".join(output)
-
-def make_swig_interface_file(di, swigdocfilename, custom_output=None):
-
- output = ["""
-/*
- * This file was automatically generated using swig_doc.py.
- *
- * Any changes to it will be lost next time it is regenerated.
- */
-"""]
-
- if custom_output is not None:
- output.append(custom_output)
-
- # Create docstrings for the blocks.
- blocks = di.in_category(Block)
- blocks2 = di.in_category(Block2)
-
- make_funcs = set([])
- for block in blocks:
- try:
- make_func = di.get_member(make_name(block.name()), DoxyFunction)
- # Don't want to risk writing to output twice.
- if make_func.name() not in make_funcs:
- make_funcs.add(make_func.name())
- output.append(make_block_entry(di, block))
- except block.ParsingError:
- sys.stderr.write('Parsing error for block {0}\n'.format(block.name()))
- raise
-
- for block in blocks2:
- try:
- make_func = block.get_member('make', DoxyFunction)
- make_func_name = block.name() +'::make'
- # Don't want to risk writing to output twice.
- if make_func_name not in make_funcs:
- make_funcs.add(make_func_name)
- output.append(make_block2_entry(di, block))
- except block.ParsingError:
- sys.stderr.write('Parsing error for block {0}\n'.format(block.name()))
- raise
-
- # Create docstrings for functions
- # Don't include the make functions since they have already been dealt with.
- funcs = [f for f in di.in_category(DoxyFunction)
- if f.name() not in make_funcs and not f.name().startswith('std::')]
- for f in funcs:
- try:
- output.append(make_func_entry(f))
- except f.ParsingError:
- sys.stderr.write('Parsing error for function {0}\n'.format(f.name()))
-
- # Create docstrings for classes
- block_names = [block.name() for block in blocks]
- block_names += [block.name() for block in blocks2]
- klasses = [k for k in di.in_category(DoxyClass)
- if k.name() not in block_names and not k.name().startswith('std::')]
- for k in klasses:
- try:
- output.append(make_class_entry(k))
- except k.ParsingError:
- sys.stderr.write('Parsing error for class {0}\n'.format(k.name()))
-
- # Docstrings are not created for anything that is not a function or a class.
- # If this excludes anything important please add it here.
-
- output = "\n\n".join(output)
-
- swig_doc = 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)
diff --git a/docs/doxygen/update_pydoc.py b/docs/doxygen/update_pydoc.py
new file mode 100644
index 0000000..e6b4544
--- /dev/null
+++ b/docs/doxygen/update_pydoc.py
@@ -0,0 +1,346 @@
+#
+# 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 gnuradio
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+#
+"""
+Updates the *pydoc_h files for a module
+Execute using: python update_pydoc.py xml_path outputfilename
+
+The file instructs Pybind11 to transfer the doxygen comments into the
+python docstrings.
+
+"""
+
+import os, sys, time, glob, re, 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:])
+
+
+class Block(object):
+ """
+ Checks if doxyxml produced objects correspond to a gnuradio block.
+ """
+
+ @classmethod
+ def includes(cls, item):
+ if not isinstance(item, DoxyClass):
+ return False
+ # Check for a parsing error.
+ if item.error():
+ return False
+ friendname = make_name(item.name())
+ is_a_block = item.has_member(friendname, DoxyFriend)
+ # But now sometimes the make function isn't a friend so check again.
+ if not is_a_block:
+ is_a_block = di.has_member(friendname, DoxyFunction)
+ return is_a_block
+
+class Block2(object):
+ """
+ Checks if doxyxml produced objects correspond to a new style
+ gnuradio block.
+ """
+
+ @classmethod
+ def includes(cls, item):
+ if not isinstance(item, DoxyClass):
+ return False
+ # Check for a parsing error.
+ if item.error():
+ return False
+ is_a_block2 = item.has_member('make', DoxyFunction) and item.has_member('sptr', DoxyOther)
+ return is_a_block2
+
+
+def utoascii(text):
+ """
+ Convert unicode text into ascii and escape quotes and backslashes.
+ """
+ if text is None:
+ 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)
+
+
+def combine_descriptions(obj):
+ """
+ Combines the brief and detailed descriptions of an object together.
+ """
+ description = []
+ bd = obj.brief_description.strip()
+ dd = obj.detailed_description.strip()
+ if bd:
+ description.append(bd)
+ if dd:
+ description.append(dd)
+ return utoascii('\n\n'.join(description)).strip()
+
+def format_params(parameteritems):
+ output = ['Args:']
+ template = ' {0} : {1}'
+ for pi in parameteritems:
+ output.append(template.format(pi.name, pi.description))
+ return '\n'.join(output)
+
+entry_templ = '%feature("docstring") {name} "{docstring}"'
+def make_entry(obj, name=None, templ="{description}", description=None, params=[]):
+ """
+ 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())
+ templ - an optional template for the docstring containing only one
+ variable named 'description'.
+ description - if this optional variable is set then it's value is
+ used as the description instead of extracting it from obj.
+ """
+ if name is None:
+ 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:
+ description = combine_descriptions(obj)
+ if params:
+ description += '\n\n'
+ description += utoascii(format_params(params))
+ docstring = templ.format(description=description)
+
+ return {name: docstring}
+
+
+def make_class_entry(klass, description=None, ignored_methods=[], params=None):
+ """
+ Create a class docstring key/value pair.
+ """
+ if params is None:
+ params = klass.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.update(make_entry(func, name=name))
+ return output
+
+
+def make_block_entry(di, block):
+ """
+ Create class and function docstrings of a gnuradio block
+ """
+ descriptions = []
+ # Get the documentation associated with the class.
+ class_desc = combine_descriptions(block)
+ if class_desc:
+ descriptions.append(class_desc)
+ # Get the documentation associated with the make function
+ make_func = di.get_member(make_name(block.name()), DoxyFunction)
+ make_func_desc = combine_descriptions(make_func)
+ if make_func_desc:
+ descriptions.append(make_func_desc)
+ # Get the documentation associated with the file
+ try:
+ block_file = di.get_member(block.name() + ".h", DoxyFile)
+ file_desc = combine_descriptions(block_file)
+ if file_desc:
+ descriptions.append(file_desc)
+ except base.Base.NoSuchMember:
+ # Don't worry if we can't find a matching file.
+ pass
+ # And join them all together to make a super duper description.
+ super_description = "\n\n".join(descriptions)
+ # Associate the combined description with the class and
+ # the make function.
+ 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 new style blocks all the relevant documentation should be
+ # associated with the 'make' method.
+ class_description = combine_descriptions(block)
+ make_func = block.get_member('make', DoxyFunction)
+ make_description = combine_descriptions(make_func)
+ description = class_description + "\n\nConstructor Specific Documentation:\n\n" + make_description
+ # Associate the combined description with the class and
+ # the make function.
+ output = {}
+ output.update(make_class_entry(
+ block, description=description,
+ ignored_methods=['make'], params=make_func.params))
+ makename = block.name() + '::make'
+ output.update(make_entry(
+ make_func, name=makename, description=description,
+ params=make_func.params))
+ return output
+
+def get_docstrings_dict(di, custom_output=None):
+
+ output = {}
+ if custom_output:
+ output.update(custom_output)
+
+ # Create docstrings for the blocks.
+ blocks = di.in_category(Block)
+ blocks2 = di.in_category(Block2)
+
+ make_funcs = set([])
+ for block in blocks:
+ try:
+ make_func = di.get_member(make_name(block.name()), DoxyFunction)
+ # Don't want to risk writing to output twice.
+ if make_func.name() not in make_funcs:
+ make_funcs.add(make_func.name())
+ output.update(make_block_entry(di, block))
+ except block.ParsingError:
+ sys.stderr.write('Parsing error for block {0}\n'.format(block.name()))
+ raise
+
+ for block in blocks2:
+ try:
+ make_func = block.get_member('make', DoxyFunction)
+ make_func_name = block.name() +'::make'
+ # Don't want to risk writing to output twice.
+ if make_func_name not in make_funcs:
+ make_funcs.add(make_func_name)
+ output.update(make_block2_entry(di, block))
+ except block.ParsingError:
+ sys.stderr.write('Parsing error for block {0}\n'.format(block.name()))
+ raise
+
+ # Create docstrings for functions
+ # Don't include the make functions since they have already been dealt with.
+ funcs = [f for f in di.in_category(DoxyFunction)
+ if f.name() not in make_funcs and not f.name().startswith('std::')]
+ for f in funcs:
+ try:
+ output.update(make_entry(f))
+ except f.ParsingError:
+ sys.stderr.write('Parsing error for function {0}\n'.format(f.name()))
+
+ # Create docstrings for classes
+ block_names = [block.name() for block in blocks]
+ block_names += [block.name() for block in blocks2]
+ klasses = [k for k in di.in_category(DoxyClass)
+ if k.name() not in block_names and not k.name().startswith('std::')]
+ for k in klasses:
+ try:
+ output.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.
+
+ 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'))
+ # FIXME: Remove this debug print
+ print('output docstrings to {}'.format(output_pathname))
+ 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'))
+ # FIXME: Remove this debug print
+ print('copy docstrings to {}'.format(output_pathname))
+ 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()
+
+if __name__ == "__main__":
+ # Parse command line options and set up doxyxml.
+ 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)
+
+
diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt
index 53cb61e..dcae02a 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -1,21 +1,10 @@
# Copyright 2011 Free Software Foundation, Inc.
#
-# This file is part of gr-osmosdr
+# This file was generated by gr_modtool, a tool from the GNU Radio framework
+# This file is a part of gr-osmosdr
#
-# gr-osmosdr 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
#
-# gr-osmosdr 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 gr-osmosdr; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
########################################################################
# Include python install macros
@@ -25,6 +14,8 @@ if(NOT PYTHONINTERP_FOUND)
return()
endif()
+add_subdirectory(bindings)
+
########################################################################
# Install python sources
########################################################################
@@ -40,4 +31,3 @@ GR_PYTHON_INSTALL(
include(GrTest)
set(GR_TEST_TARGET_DEPS gnuradio-osmosdr)
-set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig)
diff --git a/python/__init__.py b/python/__init__.py
index 1cb090f..e619f4f 100644
--- a/python/__init__.py
+++ b/python/__init__.py
@@ -1,25 +1,24 @@
#
# Copyright 2008,2009 Free Software Foundation, Inc.
#
-# This application 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.
-#
-# This application is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+# 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 OsmoSDR module.
+This is the GNU Radio OSMOSDR module. Place your Python package
+description here (python/__init__.py).
'''
+import os
-from .osmosdr_swig import *
+# import pybind11 generated symbols into the osmosdr namespace
+try:
+ from .osmosdr_python import *
+except ImportError:
+ dirname, filename = os.path.split(os.path.abspath(__file__))
+ __path__.append(os.path.join(dirname, "bindings"))
+ from .osmosdr_python import *
+
+# import any pure python here
+#
diff --git a/python/bindings/CMakeLists.txt b/python/bindings/CMakeLists.txt
new file mode 100644
index 0000000..ed50d7e
--- /dev/null
+++ b/python/bindings/CMakeLists.txt
@@ -0,0 +1,30 @@
+# Copyright 2020 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+GR_PYTHON_CHECK_MODULE_RAW(
+ "pygccxml"
+ "import pygccxml"
+ PYGCCXML_FOUND
+ )
+
+include(GrPybind)
+
+########################################################################
+# Python Bindings
+########################################################################
+
+list(APPEND osmosdr_python_files
+ sink_python.cc
+ source_python.cc
+ python_bindings.cc)
+
+GR_PYBIND_MAKE_OOT(osmosdr
+ ../..
+ gr::osmosdr
+ "${osmosdr_python_files}")
+
+install(TARGETS osmosdr_python DESTINATION ${GR_PYTHON_DIR}/osmosdr COMPONENT pythonapi)
diff --git a/python/bindings/README.md b/python/bindings/README.md
new file mode 100644
index 0000000..e69de29
diff --git a/python/bindings/bind_oot_file.py b/python/bindings/bind_oot_file.py
new file mode 100644
index 0000000..55de795
--- /dev/null
+++ b/python/bindings/bind_oot_file.py
@@ -0,0 +1,53 @@
+import warnings
+import argparse
+import os
+from gnuradio.bindtool import BindingGenerator
+import pathlib
+import sys
+
+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='/tmp',
+ help='Output directory of generated bindings')
+parser.add_argument('--prefix', help='Prefix of Installed GNU Radio')
+parser.add_argument('--src', help='Directory of gnuradio source tree',
+ default=os.path.dirname(os.path.abspath(__file__))+'/../../..')
+
+parser.add_argument(
+ '--filename', help="File to be parsed")
+
+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
+includes = args.include
+name = args.module
+
+namespace = [name]
+prefix_include_root = name
+
+
+with warnings.catch_warnings():
+ warnings.filterwarnings("ignore", category=DeprecationWarning)
+
+ bg = BindingGenerator(prefix, namespace,
+ prefix_include_root, output_dir, addl_includes=','.join(args.include), 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)
diff --git a/python/bindings/docstrings/README.md b/python/bindings/docstrings/README.md
new file mode 100644
index 0000000..295455a
--- /dev/null
+++ b/python/bindings/docstrings/README.md
@@ -0,0 +1 @@
+This directory stores templates for docstrings that are scraped from the include header files for each block
\ No newline at end of file
diff --git a/python/bindings/docstrings/sink_pydoc_template.h b/python/bindings/docstrings/sink_pydoc_template.h
new file mode 100644
index 0000000..dad47cf
--- /dev/null
+++ b/python/bindings/docstrings/sink_pydoc_template.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2020 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,osmosdr, __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_osmosdr_sink = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_sink_0 = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_sink_1 = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_make = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_num_channels = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_sample_rates = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_set_sample_rate = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_sample_rate = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_freq_range = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_set_center_freq = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_center_freq = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_set_freq_corr = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_freq_corr = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_gain_names = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_gain_range_0 = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_gain_range_1 = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_set_gain_mode = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_gain_mode = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_set_gain_0 = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_set_gain_1 = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_gain_0 = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_gain_1 = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_set_if_gain = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_set_bb_gain = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_antennas = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_set_antenna = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_antenna = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_set_dc_offset = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_set_iq_balance = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_set_bandwidth = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_bandwidth = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_bandwidth_range = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_set_time_source = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_time_source = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_time_sources = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_set_clock_source = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_clock_source = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_clock_sources = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_clock_rate = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_set_clock_rate = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_time_now = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_get_time_last_pps = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_set_time_now = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_set_time_next_pps = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_sink_set_time_unknown_pps = R"doc()doc";
+
+
diff --git a/python/bindings/docstrings/source_pydoc_template.h b/python/bindings/docstrings/source_pydoc_template.h
new file mode 100644
index 0000000..f2c3ca4
--- /dev/null
+++ b/python/bindings/docstrings/source_pydoc_template.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2020 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,osmosdr, __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_osmosdr_source = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_source_0 = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_source_1 = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_make = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_num_channels = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_seek = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_sample_rates = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_set_sample_rate = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_sample_rate = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_freq_range = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_set_center_freq = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_center_freq = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_set_freq_corr = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_freq_corr = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_gain_names = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_gain_range_0 = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_gain_range_1 = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_set_gain_mode = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_gain_mode = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_set_gain_0 = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_set_gain_1 = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_gain_0 = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_gain_1 = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_set_if_gain = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_set_bb_gain = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_antennas = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_set_antenna = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_antenna = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_set_dc_offset_mode = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_set_dc_offset = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_set_iq_balance_mode = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_set_iq_balance = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_set_bandwidth = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_bandwidth = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_bandwidth_range = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_set_time_source = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_time_source = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_time_sources = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_set_clock_source = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_clock_source = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_clock_sources = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_clock_rate = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_set_clock_rate = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_time_now = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_get_time_last_pps = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_set_time_now = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_set_time_next_pps = R"doc()doc";
+
+
+ static const char *__doc_osmosdr_source_set_time_unknown_pps = R"doc()doc";
+
+
diff --git a/python/bindings/header_utils.py b/python/bindings/header_utils.py
new file mode 100644
index 0000000..165124e
--- /dev/null
+++ b/python/bindings/header_utils.py
@@ -0,0 +1,78 @@
+# 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())
\ No newline at end of file
diff --git a/python/bindings/python_bindings.cc b/python/bindings/python_bindings.cc
new file mode 100644
index 0000000..fc11ee0
--- /dev/null
+++ b/python/bindings/python_bindings.cc
@@ -0,0 +1,57 @@
+/*
+ * 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_sink(py::module& m);
+ void bind_source(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(osmosdr_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_sink(m);
+ bind_source(m);
+ // ) END BINDING_FUNCTION_CALLS
+}
diff --git a/python/bindings/sink_python.cc b/python/bindings/sink_python.cc
new file mode 100644
index 0000000..1c6711d
--- /dev/null
+++ b/python/bindings/sink_python.cc
@@ -0,0 +1,320 @@
+/*
+ * Copyright 2020 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(1) */
+/* BINDTOOL_USE_PYGCCXML(0) */
+/* BINDTOOL_HEADER_FILE(sink.h) */
+/* BINDTOOL_HEADER_FILE_HASH(d4331eb8a19b7a2aa4ed0100039f7a0e) */
+/***********************************************************************************/
+
+#include <pybind11/complex.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <osmosdr/sink.h>
+// pydoc.h is automatically generated in the build directory
+#include <sink_pydoc.h>
+
+void bind_sink(py::module& m)
+{
+
+ using sink = ::osmosdr::sink;
+
+
+ py::class_<sink, gr::hier_block2,
+ std::shared_ptr<sink>>(m, "sink", D(sink))
+
+ .def(py::init(&sink::make),
+ py::arg("args") = "",
+ D(sink,make)
+ )
+
+
+
+
+
+ .def("get_num_channels",&sink::get_num_channels,
+ D(sink,get_num_channels)
+ )
+
+
+ .def("get_sample_rates",&sink::get_sample_rates,
+ D(sink,get_sample_rates)
+ )
+
+
+ .def("set_sample_rate",&sink::set_sample_rate,
+ py::arg("rate"),
+ D(sink,set_sample_rate)
+ )
+
+
+ .def("get_sample_rate",&sink::get_sample_rate,
+ D(sink,get_sample_rate)
+ )
+
+
+ .def("get_freq_range",&sink::get_freq_range,
+ py::arg("chan") = 0,
+ D(sink,get_freq_range)
+ )
+
+
+ .def("set_center_freq",&sink::set_center_freq,
+ py::arg("freq"),
+ py::arg("chan") = 0,
+ D(sink,set_center_freq)
+ )
+
+
+ .def("get_center_freq",&sink::get_center_freq,
+ py::arg("chan") = 0,
+ D(sink,get_center_freq)
+ )
+
+
+ .def("set_freq_corr",&sink::set_freq_corr,
+ py::arg("ppm"),
+ py::arg("chan") = 0,
+ D(sink,set_freq_corr)
+ )
+
+
+ .def("get_freq_corr",&sink::get_freq_corr,
+ py::arg("chan") = 0,
+ D(sink,get_freq_corr)
+ )
+
+
+ .def("get_gain_names",&sink::get_gain_names,
+ py::arg("chan") = 0,
+ D(sink,get_gain_names)
+ )
+
+
+ .def("get_gain_range",(osmosdr::gain_range_t (sink::*)(size_t))&sink::get_gain_range,
+ py::arg("chan") = 0,
+ D(sink,get_gain_range,0)
+ )
+
+
+ .def("get_gain_range",(osmosdr::gain_range_t (sink::*)(std::string const &, size_t))&sink::get_gain_range,
+ py::arg("name"),
+ py::arg("chan") = 0,
+ D(sink,get_gain_range,1)
+ )
+
+
+ .def("set_gain_mode",&sink::set_gain_mode,
+ py::arg("automatic"),
+ py::arg("chan") = 0,
+ D(sink,set_gain_mode)
+ )
+
+
+ .def("get_gain_mode",&sink::get_gain_mode,
+ py::arg("chan") = 0,
+ D(sink,get_gain_mode)
+ )
+
+
+ .def("set_gain",(double (sink::*)(double, size_t))&sink::set_gain,
+ py::arg("gain"),
+ py::arg("chan") = 0,
+ D(sink,set_gain,0)
+ )
+
+
+ .def("set_gain",(double (sink::*)(double, std::string const &, size_t))&sink::set_gain,
+ py::arg("gain"),
+ py::arg("name"),
+ py::arg("chan") = 0,
+ D(sink,set_gain,1)
+ )
+
+
+ .def("get_gain",(double (sink::*)(size_t))&sink::get_gain,
+ py::arg("chan") = 0,
+ D(sink,get_gain,0)
+ )
+
+
+ .def("get_gain",(double (sink::*)(std::string const &, size_t))&sink::get_gain,
+ py::arg("name"),
+ py::arg("chan") = 0,
+ D(sink,get_gain,1)
+ )
+
+
+ .def("set_if_gain",&sink::set_if_gain,
+ py::arg("gain"),
+ py::arg("chan") = 0,
+ D(sink,set_if_gain)
+ )
+
+
+ .def("set_bb_gain",&sink::set_bb_gain,
+ py::arg("gain"),
+ py::arg("chan") = 0,
+ D(sink,set_bb_gain)
+ )
+
+
+ .def("get_antennas",&sink::get_antennas,
+ py::arg("chan") = 0,
+ D(sink,get_antennas)
+ )
+
+
+ .def("set_antenna",&sink::set_antenna,
+ py::arg("antenna"),
+ py::arg("chan") = 0,
+ D(sink,set_antenna)
+ )
+
+
+ .def("get_antenna",&sink::get_antenna,
+ py::arg("chan") = 0,
+ D(sink,get_antenna)
+ )
+
+
+ .def("set_dc_offset",&sink::set_dc_offset,
+ py::arg("offset"),
+ py::arg("chan") = 0,
+ D(sink,set_dc_offset)
+ )
+
+
+ .def("set_iq_balance",&sink::set_iq_balance,
+ py::arg("balance"),
+ py::arg("chan") = 0,
+ D(sink,set_iq_balance)
+ )
+
+
+ .def("set_bandwidth",&sink::set_bandwidth,
+ py::arg("bandwidth"),
+ py::arg("chan") = 0,
+ D(sink,set_bandwidth)
+ )
+
+
+ .def("get_bandwidth",&sink::get_bandwidth,
+ py::arg("chan") = 0,
+ D(sink,get_bandwidth)
+ )
+
+
+ .def("get_bandwidth_range",&sink::get_bandwidth_range,
+ py::arg("chan") = 0,
+ D(sink,get_bandwidth_range)
+ )
+
+
+ .def("set_time_source",&sink::set_time_source,
+ py::arg("source"),
+ py::arg("mboard") = 0,
+ D(sink,set_time_source)
+ )
+
+
+ .def("get_time_source",&sink::get_time_source,
+ py::arg("mboard"),
+ D(sink,get_time_source)
+ )
+
+
+ .def("get_time_sources",&sink::get_time_sources,
+ py::arg("mboard"),
+ D(sink,get_time_sources)
+ )
+
+
+ .def("set_clock_source",&sink::set_clock_source,
+ py::arg("source"),
+ py::arg("mboard") = 0,
+ D(sink,set_clock_source)
+ )
+
+
+ .def("get_clock_source",&sink::get_clock_source,
+ py::arg("mboard"),
+ D(sink,get_clock_source)
+ )
+
+
+ .def("get_clock_sources",&sink::get_clock_sources,
+ py::arg("mboard"),
+ D(sink,get_clock_sources)
+ )
+
+
+ .def("get_clock_rate",&sink::get_clock_rate,
+ py::arg("mboard") = 0,
+ D(sink,get_clock_rate)
+ )
+
+
+ .def("set_clock_rate",&sink::set_clock_rate,
+ py::arg("rate"),
+ py::arg("mboard") = 0,
+ D(sink,set_clock_rate)
+ )
+
+
+ .def("get_time_now",&sink::get_time_now,
+ py::arg("mboard") = 0,
+ D(sink,get_time_now)
+ )
+
+
+ .def("get_time_last_pps",&sink::get_time_last_pps,
+ py::arg("mboard") = 0,
+ D(sink,get_time_last_pps)
+ )
+
+
+ .def("set_time_now",&sink::set_time_now,
+ py::arg("time_spec"),
+ py::arg("mboard") = 0,
+ D(sink,set_time_now)
+ )
+
+
+ .def("set_time_next_pps",&sink::set_time_next_pps,
+ py::arg("time_spec"),
+ D(sink,set_time_next_pps)
+ )
+
+
+ .def("set_time_unknown_pps",&sink::set_time_unknown_pps,
+ py::arg("time_spec"),
+ D(sink,set_time_unknown_pps)
+ )
+
+ ;
+
+
+
+
+}
+
+
+
+
+
+
+
diff --git a/python/bindings/source_python.cc b/python/bindings/source_python.cc
new file mode 100644
index 0000000..48bf10c
--- /dev/null
+++ b/python/bindings/source_python.cc
@@ -0,0 +1,342 @@
+/*
+ * Copyright 2020 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(1) */
+/* BINDTOOL_USE_PYGCCXML(0) */
+/* BINDTOOL_HEADER_FILE(source.h) */
+/* BINDTOOL_HEADER_FILE_HASH(574373c3c7682569b0fd7eea577739da) */
+/***********************************************************************************/
+
+#include <pybind11/complex.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <osmosdr/source.h>
+// pydoc.h is automatically generated in the build directory
+#include <source_pydoc.h>
+
+void bind_source(py::module& m)
+{
+
+ using source = ::osmosdr::source;
+
+
+ py::class_<source, gr::hier_block2,
+ std::shared_ptr<source>>(m, "source", D(source))
+
+ .def(py::init(&source::make),
+ py::arg("args") = "",
+ D(source,make)
+ )
+
+
+
+
+
+ .def("get_num_channels",&source::get_num_channels,
+ D(source,get_num_channels)
+ )
+
+
+ .def("seek",&source::seek,
+ py::arg("seek_point"),
+ py::arg("whence"),
+ py::arg("chan") = 0,
+ D(source,seek)
+ )
+
+
+ .def("get_sample_rates",&source::get_sample_rates,
+ D(source,get_sample_rates)
+ )
+
+
+ .def("set_sample_rate",&source::set_sample_rate,
+ py::arg("rate"),
+ D(source,set_sample_rate)
+ )
+
+
+ .def("get_sample_rate",&source::get_sample_rate,
+ D(source,get_sample_rate)
+ )
+
+
+ .def("get_freq_range",&source::get_freq_range,
+ py::arg("chan") = 0,
+ D(source,get_freq_range)
+ )
+
+
+ .def("set_center_freq",&source::set_center_freq,
+ py::arg("freq"),
+ py::arg("chan") = 0,
+ D(source,set_center_freq)
+ )
+
+
+ .def("get_center_freq",&source::get_center_freq,
+ py::arg("chan") = 0,
+ D(source,get_center_freq)
+ )
+
+
+ .def("set_freq_corr",&source::set_freq_corr,
+ py::arg("ppm"),
+ py::arg("chan") = 0,
+ D(source,set_freq_corr)
+ )
+
+
+ .def("get_freq_corr",&source::get_freq_corr,
+ py::arg("chan") = 0,
+ D(source,get_freq_corr)
+ )
+
+
+ .def("get_gain_names",&source::get_gain_names,
+ py::arg("chan") = 0,
+ D(source,get_gain_names)
+ )
+
+
+ .def("get_gain_range",(osmosdr::gain_range_t (source::*)(size_t))&source::get_gain_range,
+ py::arg("chan") = 0,
+ D(source,get_gain_range,0)
+ )
+
+
+ .def("get_gain_range",(osmosdr::gain_range_t (source::*)(std::string const &, size_t))&source::get_gain_range,
+ py::arg("name"),
+ py::arg("chan") = 0,
+ D(source,get_gain_range,1)
+ )
+
+
+ .def("set_gain_mode",&source::set_gain_mode,
+ py::arg("automatic"),
+ py::arg("chan") = 0,
+ D(source,set_gain_mode)
+ )
+
+
+ .def("get_gain_mode",&source::get_gain_mode,
+ py::arg("chan") = 0,
+ D(source,get_gain_mode)
+ )
+
+
+ .def("set_gain",(double (source::*)(double, size_t))&source::set_gain,
+ py::arg("gain"),
+ py::arg("chan") = 0,
+ D(source,set_gain,0)
+ )
+
+
+ .def("set_gain",(double (source::*)(double, std::string const &, size_t))&source::set_gain,
+ py::arg("gain"),
+ py::arg("name"),
+ py::arg("chan") = 0,
+ D(source,set_gain,1)
+ )
+
+
+ .def("get_gain",(double (source::*)(size_t))&source::get_gain,
+ py::arg("chan") = 0,
+ D(source,get_gain,0)
+ )
+
+
+ .def("get_gain",(double (source::*)(std::string const &, size_t))&source::get_gain,
+ py::arg("name"),
+ py::arg("chan") = 0,
+ D(source,get_gain,1)
+ )
+
+
+ .def("set_if_gain",&source::set_if_gain,
+ py::arg("gain"),
+ py::arg("chan") = 0,
+ D(source,set_if_gain)
+ )
+
+
+ .def("set_bb_gain",&source::set_bb_gain,
+ py::arg("gain"),
+ py::arg("chan") = 0,
+ D(source,set_bb_gain)
+ )
+
+
+ .def("get_antennas",&source::get_antennas,
+ py::arg("chan") = 0,
+ D(source,get_antennas)
+ )
+
+
+ .def("set_antenna",&source::set_antenna,
+ py::arg("antenna"),
+ py::arg("chan") = 0,
+ D(source,set_antenna)
+ )
+
+
+ .def("get_antenna",&source::get_antenna,
+ py::arg("chan") = 0,
+ D(source,get_antenna)
+ )
+
+
+ .def("set_dc_offset_mode",&source::set_dc_offset_mode,
+ py::arg("mode"),
+ py::arg("chan") = 0,
+ D(source,set_dc_offset_mode)
+ )
+
+
+ .def("set_dc_offset",&source::set_dc_offset,
+ py::arg("offset"),
+ py::arg("chan") = 0,
+ D(source,set_dc_offset)
+ )
+
+
+ .def("set_iq_balance_mode",&source::set_iq_balance_mode,
+ py::arg("mode"),
+ py::arg("chan") = 0,
+ D(source,set_iq_balance_mode)
+ )
+
+
+ .def("set_iq_balance",&source::set_iq_balance,
+ py::arg("balance"),
+ py::arg("chan") = 0,
+ D(source,set_iq_balance)
+ )
+
+
+ .def("set_bandwidth",&source::set_bandwidth,
+ py::arg("bandwidth"),
+ py::arg("chan") = 0,
+ D(source,set_bandwidth)
+ )
+
+
+ .def("get_bandwidth",&source::get_bandwidth,
+ py::arg("chan") = 0,
+ D(source,get_bandwidth)
+ )
+
+
+ .def("get_bandwidth_range",&source::get_bandwidth_range,
+ py::arg("chan") = 0,
+ D(source,get_bandwidth_range)
+ )
+
+
+ .def("set_time_source",&source::set_time_source,
+ py::arg("source"),
+ py::arg("mboard") = 0,
+ D(source,set_time_source)
+ )
+
+
+ .def("get_time_source",&source::get_time_source,
+ py::arg("mboard"),
+ D(source,get_time_source)
+ )
+
+
+ .def("get_time_sources",&source::get_time_sources,
+ py::arg("mboard"),
+ D(source,get_time_sources)
+ )
+
+
+ .def("set_clock_source",&source::set_clock_source,
+ py::arg("source"),
+ py::arg("mboard") = 0,
+ D(source,set_clock_source)
+ )
+
+
+ .def("get_clock_source",&source::get_clock_source,
+ py::arg("mboard"),
+ D(source,get_clock_source)
+ )
+
+
+ .def("get_clock_sources",&source::get_clock_sources,
+ py::arg("mboard"),
+ D(source,get_clock_sources)
+ )
+
+
+ .def("get_clock_rate",&source::get_clock_rate,
+ py::arg("mboard") = 0,
+ D(source,get_clock_rate)
+ )
+
+
+ .def("set_clock_rate",&source::set_clock_rate,
+ py::arg("rate"),
+ py::arg("mboard") = 0,
+ D(source,set_clock_rate)
+ )
+
+
+ .def("get_time_now",&source::get_time_now,
+ py::arg("mboard") = 0,
+ D(source,get_time_now)
+ )
+
+
+ .def("get_time_last_pps",&source::get_time_last_pps,
+ py::arg("mboard") = 0,
+ D(source,get_time_last_pps)
+ )
+
+
+ .def("set_time_now",&source::set_time_now,
+ py::arg("time_spec"),
+ py::arg("mboard") = 0,
+ D(source,set_time_now)
+ )
+
+
+ .def("set_time_next_pps",&source::set_time_next_pps,
+ py::arg("time_spec"),
+ D(source,set_time_next_pps)
+ )
+
+
+ .def("set_time_unknown_pps",&source::set_time_unknown_pps,
+ py::arg("time_spec"),
+ D(source,set_time_unknown_pps)
+ )
+
+ ;
+
+
+
+
+}
+
+
+
+
+
+
+
diff --git a/swig/CMakeLists.txt b/swig/CMakeLists.txt
deleted file mode 100644
index 159f212..0000000
--- a/swig/CMakeLists.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright 2011 Free Software Foundation, Inc.
-#
-# This file is part of gr-osmosdr
-#
-# gr-osmosdr 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.
-#
-# gr-osmosdr 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 gr-osmosdr; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-
-########################################################################
-# Include swig generation macros
-########################################################################
-find_package(SWIG)
-find_package(PythonLibs 3)
-if(NOT SWIG_FOUND OR NOT PYTHONLIBS_FOUND)
- return()
-endif()
-include(GrSwig)
-include(GrPython)
-
-########################################################################
-# Setup swig generation
-########################################################################
-set(GR_SWIG_INCLUDE_DIRS $<TARGET_PROPERTY:gnuradio::runtime_swig,INTERFACE_INCLUDE_DIRECTORIES>)
-set(GR_SWIG_TARGET_DEPS gnuradio::runtime_swig)
-
-set(GR_SWIG_LIBRARIES gnuradio-osmosdr)
-
-set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/osmosdr_swig_doc.i)
-set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../include/osmosdr)
-
-GR_SWIG_MAKE(osmosdr_swig osmosdr_swig.i)
-
-########################################################################
-# Install the build swig module
-########################################################################
-GR_SWIG_INSTALL(TARGETS osmosdr_swig DESTINATION ${GR_PYTHON_DIR}/osmosdr)
-
-########################################################################
-# Install swig .i files for development
-########################################################################
-install(
- FILES
- osmosdr_swig.i
- ${CMAKE_CURRENT_BINARY_DIR}/osmosdr_swig_doc.i
- DESTINATION ${GR_INCLUDE_DIR}/osmosdr/swig
-)
diff --git a/swig/osmosdr_swig.i b/swig/osmosdr_swig.i
deleted file mode 100644
index da42e6e..0000000
--- a/swig/osmosdr_swig.i
+++ /dev/null
@@ -1,82 +0,0 @@
-/* -*- c++ -*- */
-
-#define OSMOSDR_API
-
-// suppress Warning 319: No access specifier given for base class 'boost::noncopyable' (ignored).
-#pragma SWIG nowarn=319
-
-%include "gnuradio.i" // the common stuff
-
-//load generated python docstrings
-%include "osmosdr_swig_doc.i"
-
-%{
-#include "osmosdr/device.h"
-#include "osmosdr/source.h"
-#include "osmosdr/sink.h"
-%}
-
-// Workaround for a SWIG 2.0.4 bug with templates. Probably needs to be looked in to.
-%{
-#if PY_VERSION_HEX >= 0x03020000
-# define SWIGPY_SLICE_ARG(obj) ((PyObject*) (obj))
-#else
-# define SWIGPY_SLICE_ARG(obj) ((PySliceObject*) (obj))
-#endif
-%}
-
-%template(string_vector_t) std::vector<std::string>;
-
-//%template(size_vector_t) std::vector<size_t>;
-
-%include <osmosdr/pimpl.h>
-
-%ignore osmosdr::device_t::operator[]; //ignore warnings about %extend
-
-%template(string_string_dict_t) std::map<std::string, std::string>; //define before device
-%template(devices_t) std::vector<osmosdr::device_t>;
-%include <osmosdr/device.h>
-
-//%extend std::map<std::string, std::string>{
-// std::string __getitem__(std::string key) {return (*self)[key];}
-// void __setitem__(std::string key, std::string val) {(*self)[key] = val;}
-//};
-
-%template(range_vector_t) std::vector<osmosdr::range_t>; //define before range
-%include <osmosdr/ranges.h>
-
-%include <osmosdr/time_spec.h>
-
-%extend osmosdr::time_spec_t{
- osmosdr::time_spec_t __add__(const osmosdr::time_spec_t &what)
- {
- osmosdr::time_spec_t temp = *self;
- temp += what;
- return temp;
- }
- osmosdr::time_spec_t __sub__(const osmosdr::time_spec_t &what)
- {
- osmosdr::time_spec_t temp = *self;
- temp -= what;
- return temp;
- }
-};
-
-%define OSMOSDR_SWIG_BLOCK_MAGIC2(PKG, BASE_NAME)
-%template(BASE_NAME ## _sptr) std::shared_ptr<PKG ## :: ## BASE_NAME>;
-%pythoncode %{
-BASE_NAME ## _sptr.__repr__ = lambda self: "<gr_block %s (%d)>" % (self.name(), self.unique_id())
-BASE_NAME = BASE_NAME.make;
-%}
-%enddef
-
-%include "osmosdr/source.h"
-%include "osmosdr/sink.h"
-
-OSMOSDR_SWIG_BLOCK_MAGIC2(osmosdr,source);
-OSMOSDR_SWIG_BLOCK_MAGIC2(osmosdr,sink);
-
-%{
-static const size_t ALL_MBOARDS = osmosdr::ALL_MBOARDS;
-%}
-//static const size_t ALL_MBOARDS;
--
cgit v1.2.3