aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpsykose <alice@ayaya.dev>2021-12-20 09:41:54 +0000
committerKevin Daudt <kdaudt@alpinelinux.org>2021-12-25 13:42:39 +0000
commitafbfbf23001746e400e475cb8e3e8a428d411b1e (patch)
tree1583eaabdf299343769037946c72368c9f845d38
parentb57095baefd4d9d3c17bae9db7e0391e21e34101 (diff)
downloadaports-afbfbf23001746e400e475cb8e3e8a428d411b1e.tar.gz
aports-afbfbf23001746e400e475cb8e3e8a428d411b1e.tar.bz2
aports-afbfbf23001746e400e475cb8e3e8a428d411b1e.tar.xz
testing/gr-osmosdr: rebuild against py3.10/gnuradio
use patches for early gnuradio 3.9 support
-rw-r--r--testing/gr-osmosdr/APKBUILD18
-rw-r--r--testing/gr-osmosdr/add-python-bindings.patch173
-rw-r--r--testing/gr-osmosdr/fix-docstrings.patch40
-rw-r--r--testing/gr-osmosdr/gnuradio-3.9-compat.patch2298
-rw-r--r--testing/gr-osmosdr/use-std-shared-ptr.patch548
5 files changed, 3074 insertions, 3 deletions
diff --git a/testing/gr-osmosdr/APKBUILD b/testing/gr-osmosdr/APKBUILD
index 056917754f..e0388facaa 100644
--- a/testing/gr-osmosdr/APKBUILD
+++ b/testing/gr-osmosdr/APKBUILD
@@ -2,7 +2,7 @@
# Maintainer: Marian Buschsieweke <marian.buschsieweke@ovgu.de>
pkgname=gr-osmosdr
pkgver=0.2.3
-pkgrel=0
+pkgrel=1
pkgdesc="osmocom Gnu Radio Blocks"
url="https://osmocom.org/projects/gr-osmosdr/wiki"
arch="x86_64 aarch64" # limited by libvolk and gnuradio
@@ -18,14 +18,22 @@ makedepends="
graphviz
hackrf
librtlsdr-dev
+ libsndfile-dev
libvolk-dev
log4cpp-dev
mpir-dev
+ py3-numpy-dev
+ py3-pybind11-dev
python3-dev
soapy-sdr-dev
- swig
"
-source="$pkgname-$pkgver.tar.gz::https://github.com/osmocom/gr-osmosdr/archive/v$pkgver.tar.gz"
+source="
+ $pkgname-$pkgver.tar.gz::https://github.com/osmocom/gr-osmosdr/archive/v$pkgver.tar.gz
+ use-std-shared-ptr.patch
+ gnuradio-3.9-compat.patch
+ fix-docstrings.patch
+ add-python-bindings.patch
+ "
build() {
cmake -B build \
@@ -46,4 +54,8 @@ check() {
sha512sums="
3c82a39972a309aa5b023b9c5e61f1fc80b797380b7a6c6c23cd4fe278cfaba3ab3019f32d38ebc01300868bb892f6aaaa7f12c9ee9b7ab5ba3e38817a40bf3e gr-osmosdr-0.2.3.tar.gz
+c0c06b9f5907db565ddea1c6ee5ebfaaa8e6bf66950581467d8173deb8cbecadc57ff32b3683eb3affd0368b11e399ded58824490cecddbe38b5b174d69b0630 use-std-shared-ptr.patch
+617edcdc27d7a9799caef1a1e778222d7954288cb767f76f81e68def2f66b4ba7640ff08866d696109a0d6bd0473bf996c3707bedadc59e283261d42c209bfbb gnuradio-3.9-compat.patch
+d66309f99144515aeae771a6bf4f64defa35f7a9f9c4c646e807c6d6df5d817346de0a66cb9114716b32990d9837ea9107efb3b2fc0fd32de7453ec235e1f667 fix-docstrings.patch
+94730f15580c8dd46803da78fe36b7c8afefc735330918c4f58beaabb0a12b5898041dfe70167d55a55e682c8536ef441d2b9ea4e3c069a637e3fbb1950716aa add-python-bindings.patch
"
diff --git a/testing/gr-osmosdr/add-python-bindings.patch b/testing/gr-osmosdr/add-python-bindings.patch
new file mode 100644
index 0000000000..e1fea6dd15
--- /dev/null
+++ b/testing/gr-osmosdr/add-python-bindings.patch
@@ -0,0 +1,173 @@
+From 1f724162e1e0afd1636658c2e8fed60320f0809a Mon Sep 17 00:00:00 2001
+From: Clayton Smith <argilo@gmail.com>
+Date: Wed, 30 Dec 2020 10:05:36 -0500
+Subject: Add Python bindings
+
+Signed-off-by: Eric Wild <ewild@sysmocom.de>
+---
+ python/bindings/CMakeLists.txt | 3 +++
+ python/bindings/device_python.cc | 27 +++++++++++++++++++++++++++
+ python/bindings/python_bindings.cc | 8 ++++++++
+ python/bindings/ranges_python.cc | 35 +++++++++++++++++++++++++++++++++++
+ python/bindings/time_spec_python.cc | 33 +++++++++++++++++++++++++++++++++
+ 5 files changed, 106 insertions(+)
+ create mode 100644 python/bindings/device_python.cc
+ create mode 100644 python/bindings/ranges_python.cc
+ create mode 100644 python/bindings/time_spec_python.cc
+
+diff --git a/python/bindings/CMakeLists.txt b/python/bindings/CMakeLists.txt
+index ed50d7e..f2233cf 100644
+--- a/python/bindings/CMakeLists.txt
++++ b/python/bindings/CMakeLists.txt
+@@ -18,8 +18,11 @@ include(GrPybind)
+ ########################################################################
+
+ list(APPEND osmosdr_python_files
++ device_python.cc
+ sink_python.cc
+ source_python.cc
++ ranges_python.cc
++ time_spec_python.cc
+ python_bindings.cc)
+
+ GR_PYBIND_MAKE_OOT(osmosdr
+diff --git a/python/bindings/device_python.cc b/python/bindings/device_python.cc
+new file mode 100644
+index 0000000..f82a48f
+--- /dev/null
++++ b/python/bindings/device_python.cc
+@@ -0,0 +1,27 @@
++#include <pybind11/pybind11.h>
++#include <pybind11/stl.h>
++
++namespace py = pybind11;
++
++#include <osmosdr/device.h>
++
++void bind_device(py::module& m)
++{
++ using device_t = ::osmosdr::device_t;
++
++ py::class_<device_t>(m, "device_t")
++ .def(py::init<std::string&>(), py::arg("args") = "")
++ .def("to_pp_string", &device_t::to_pp_string)
++ .def("to_string", &device_t::to_string);
++
++
++ using devices_t = ::osmosdr::devices_t;
++
++ py::class_<devices_t>(m, "devices_t");
++
++
++ using device = ::osmosdr::device;
++
++ py::class_<device>(m, "device")
++ .def_static("find", &device::find, py::arg("hint") = device_t());
++}
+diff --git a/python/bindings/python_bindings.cc b/python/bindings/python_bindings.cc
+index fc11ee0..7204b2b 100644
+--- a/python/bindings/python_bindings.cc
++++ b/python/bindings/python_bindings.cc
+@@ -25,6 +25,10 @@ namespace py = pybind11;
+ void bind_source(py::module& m);
+ // ) END BINDING_FUNCTION_PROTOTYPES
+
++void bind_device(py::module& m);
++void bind_ranges(py::module& m);
++void bind_time_spec(py::module& m);
++
+
+ // We need this hack because import_array() returns NULL
+ // for newer Python versions.
+@@ -54,4 +58,8 @@ PYBIND11_MODULE(osmosdr_python, m)
+ bind_sink(m);
+ bind_source(m);
+ // ) END BINDING_FUNCTION_CALLS
++
++ bind_device(m);
++ bind_ranges(m);
++ bind_time_spec(m);
+ }
+diff --git a/python/bindings/ranges_python.cc b/python/bindings/ranges_python.cc
+new file mode 100644
+index 0000000..fce957c
+--- /dev/null
++++ b/python/bindings/ranges_python.cc
+@@ -0,0 +1,35 @@
++#include <pybind11/pybind11.h>
++
++namespace py = pybind11;
++
++#include <osmosdr/ranges.h>
++
++void bind_ranges(py::module& m)
++{
++ m.attr("ALL_MBOARDS") = ::osmosdr::ALL_MBOARDS;
++ m.attr("ALL_CHANS") = ::osmosdr::ALL_CHANS;
++
++
++ using range_t = ::osmosdr::range_t;
++
++ py::class_<range_t>(m, "range_t")
++ .def(py::init<double>(), py::arg("value") = 0)
++ .def(py::init<double, double, double>(), py::arg("start"), py::arg("stop"), py::arg("step") = 0)
++ .def("start", &range_t::start)
++ .def("stop", &range_t::stop)
++ .def("step", &range_t::step)
++ .def("to_pp_string", &range_t::to_pp_string);
++
++
++ using meta_range_t = ::osmosdr::meta_range_t;
++
++ py::class_<meta_range_t>(m, "meta_range_t")
++ .def(py::init())
++ .def(py::init<double, double, double>(), py::arg("start"), py::arg("stop"), py::arg("step") = 0)
++ .def("start", &meta_range_t::start)
++ .def("stop", &meta_range_t::stop)
++ .def("step", &meta_range_t::step)
++ .def("clip", &meta_range_t::clip, py::arg("value"), py::arg("clip_step") = false)
++ .def("values", &meta_range_t::values)
++ .def("to_pp_string", &meta_range_t::to_pp_string);
++}
+diff --git a/python/bindings/time_spec_python.cc b/python/bindings/time_spec_python.cc
+new file mode 100644
+index 0000000..d12a3c7
+--- /dev/null
++++ b/python/bindings/time_spec_python.cc
+@@ -0,0 +1,33 @@
++#include <pybind11/pybind11.h>
++#include <pybind11/operators.h>
++
++namespace py = pybind11;
++
++#include <osmosdr/time_spec.h>
++
++void bind_time_spec(py::module& m)
++{
++ using time_spec_t = ::osmosdr::time_spec_t;
++
++ py::class_<time_spec_t>(m, "time_spec_t")
++ .def_static("get_system_time", &time_spec_t::get_system_time)
++ .def(py::init<double>(), py::arg("secs") = 0)
++ .def(py::init<time_t, double>(), py::arg("full_secs"), py::arg("frac_secs") = 0)
++ .def(py::init<time_t, long, double>(), py::arg("full_secs"), py::arg("tick_count"), py::arg("tick_rate"))
++ .def_static("from_ticks", &time_spec_t::from_ticks, py::arg("ticks"), py::arg("tick_rate"))
++ .def("get_tick_count", &time_spec_t::get_tick_count, py::arg("tick_rate"))
++ .def("to_ticks", &time_spec_t::to_ticks, py::arg("tick_rate"))
++ .def("get_real_secs", &time_spec_t::get_real_secs)
++ .def("get_full_secs", &time_spec_t::get_full_secs)
++ .def("get_frac_secs", &time_spec_t::get_frac_secs)
++ .def(py::self + py::self)
++ .def(py::self += py::self)
++ .def(py::self - py::self)
++ .def(py::self -= py::self)
++ .def(py::self == py::self)
++ .def(py::self != py::self)
++ .def(py::self < py::self)
++ .def(py::self > py::self)
++ .def(py::self <= py::self)
++ .def(py::self >= py::self);
++}
+--
+cgit v1.2.3
+
diff --git a/testing/gr-osmosdr/fix-docstrings.patch b/testing/gr-osmosdr/fix-docstrings.patch
new file mode 100644
index 0000000000..e9f42941db
--- /dev/null
+++ b/testing/gr-osmosdr/fix-docstrings.patch
@@ -0,0 +1,40 @@
+From f88dc7df2f6224d1724dc8b02dfa9f2fcde9a9d1 Mon Sep 17 00:00:00 2001
+From: Matt Mills <mmills@2bn.net>
+Date: Thu, 29 Oct 2020 18:47:29 -0600
+Subject: Fix docstrings in python bindings for gr namespace
+
+Signed-off-by: Eric Wild <ewild@sysmocom.de>
+---
+ python/bindings/docstrings/sink_pydoc_template.h | 2 +-
+ python/bindings/docstrings/source_pydoc_template.h | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/python/bindings/docstrings/sink_pydoc_template.h b/python/bindings/docstrings/sink_pydoc_template.h
+index dad47cf..504105f 100644
+--- a/python/bindings/docstrings/sink_pydoc_template.h
++++ b/python/bindings/docstrings/sink_pydoc_template.h
+@@ -7,7 +7,7 @@
+ *
+ */
+ #include "pydoc_macros.h"
+-#define D(...) DOC(gr,osmosdr, __VA_ARGS__ )
++#define D(...) DOC(osmosdr, __VA_ARGS__ )
+ /*
+ This file contains placeholders for docstrings for the Python bindings.
+ Do not edit! These were automatically extracted during the binding process
+diff --git a/python/bindings/docstrings/source_pydoc_template.h b/python/bindings/docstrings/source_pydoc_template.h
+index f2c3ca4..17aae8e 100644
+--- a/python/bindings/docstrings/source_pydoc_template.h
++++ b/python/bindings/docstrings/source_pydoc_template.h
+@@ -7,7 +7,7 @@
+ *
+ */
+ #include "pydoc_macros.h"
+-#define D(...) DOC(gr,osmosdr, __VA_ARGS__ )
++#define D(...) DOC(osmosdr, __VA_ARGS__ )
+ /*
+ This file contains placeholders for docstrings for the Python bindings.
+ Do not edit! These were automatically extracted during the binding process
+--
+cgit v1.2.3
+
diff --git a/testing/gr-osmosdr/gnuradio-3.9-compat.patch b/testing/gr-osmosdr/gnuradio-3.9-compat.patch
new file mode 100644
index 0000000000..ec514fd14a
--- /dev/null
+++ b/testing/gr-osmosdr/gnuradio-3.9-compat.patch
@@ -0,0 +1,2298 @@
+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
+
diff --git a/testing/gr-osmosdr/use-std-shared-ptr.patch b/testing/gr-osmosdr/use-std-shared-ptr.patch
new file mode 100644
index 0000000000..b16fd5c163
--- /dev/null
+++ b/testing/gr-osmosdr/use-std-shared-ptr.patch
@@ -0,0 +1,548 @@
+From 159885f9e67101834c100ceb7affc122e3f98bac Mon Sep 17 00:00:00 2001
+From: Clayton Smith <argilo@gmail.com>
+Date: Mon, 28 Dec 2020 22:27:22 -0500
+Subject: Replace boost::shared_ptr with std::shared_ptr
+
+Signed-off-by: Eric Wild <ewild@sysmocom.de>
+---
+ include/osmosdr/sink.h | 2 +-
+ include/osmosdr/source.h | 2 +-
+ lib/airspy/airspy_source_c.h | 6 +++---
+ lib/airspyhf/airspyhf_source_c.h | 2 +-
+ lib/bladerf/bladerf_sink_c.h | 6 +++---
+ lib/bladerf/bladerf_source_c.h | 6 +++---
+ lib/fcd/fcd_source_c.h | 2 +-
+ lib/file/file_sink_c.h | 2 +-
+ lib/file/file_source_c.h | 2 +-
+ lib/freesrp/freesrp_sink_c.h | 6 +++---
+ lib/freesrp/freesrp_source_c.h | 6 +++---
+ lib/hackrf/hackrf_sink_c.h | 6 +++---
+ lib/hackrf/hackrf_source_c.h | 6 +++---
+ lib/redpitaya/redpitaya_sink_c.h | 2 +-
+ lib/redpitaya/redpitaya_source_c.h | 2 +-
+ lib/rfspace/rfspace_source_c.h | 6 +++---
+ lib/rtl/rtl_source_c.h | 6 +++---
+ lib/rtl_tcp/rtl_tcp_source_c.h | 2 +-
+ lib/rtl_tcp/rtl_tcp_source_f.h | 2 +-
+ lib/sdrplay/sdrplay_source_c.h | 6 +++---
+ lib/soapy/soapy_sink_c.h | 6 +++---
+ lib/soapy/soapy_source_c.h | 6 +++---
+ lib/uhd/uhd_sink_c.h | 2 +-
+ lib/uhd/uhd_source_c.h | 2 +-
+ lib/xtrx/xtrx_obj.h | 2 +-
+ lib/xtrx/xtrx_sink_c.h | 2 +-
+ lib/xtrx/xtrx_source_c.h | 2 +-
+ swig/osmosdr_swig.i | 2 +-
+ 28 files changed, 52 insertions(+), 52 deletions(-)
+
+diff --git a/include/osmosdr/sink.h b/include/osmosdr/sink.h
+index 906976e..1f72a5e 100644
+--- a/include/osmosdr/sink.h
++++ b/include/osmosdr/sink.h
+@@ -38,7 +38,7 @@ class sink;
+ class OSMOSDR_API sink : virtual public gr::hier_block2
+ {
+ public:
+- typedef boost::shared_ptr< sink > sptr;
++ typedef std::shared_ptr< sink > sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of sink.
+diff --git a/include/osmosdr/source.h b/include/osmosdr/source.h
+index 88f8385..3ea716d 100644
+--- a/include/osmosdr/source.h
++++ b/include/osmosdr/source.h
+@@ -38,7 +38,7 @@ class source;
+ class OSMOSDR_API source : virtual public gr::hier_block2
+ {
+ public:
+- typedef boost::shared_ptr< source > sptr;
++ typedef std::shared_ptr< source > sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of source.
+diff --git a/lib/airspy/airspy_source_c.h b/lib/airspy/airspy_source_c.h
+index a7d817f..81add15 100644
+--- a/lib/airspy/airspy_source_c.h
++++ b/lib/airspy/airspy_source_c.h
+@@ -36,7 +36,7 @@
+ class airspy_source_c;
+
+ /*
+- * We use boost::shared_ptr's instead of raw pointers for all access
++ * We use std::shared_ptr's instead of raw pointers for all access
+ * to gr::blocks (and many other data structures). The shared_ptr gets
+ * us transparent reference counting, which greatly simplifies storage
+ * management issues. This is especially helpful in our hybrid
+@@ -44,9 +44,9 @@ class airspy_source_c;
+ *
+ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
+ *
+- * As a convention, the _sptr suffix indicates a boost::shared_ptr
++ * As a convention, the _sptr suffix indicates a std::shared_ptr
+ */
+-typedef boost::shared_ptr<airspy_source_c> airspy_source_c_sptr;
++typedef std::shared_ptr<airspy_source_c> airspy_source_c_sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of airspy_source_c.
+diff --git a/lib/airspyhf/airspyhf_source_c.h b/lib/airspyhf/airspyhf_source_c.h
+index dbdd87a..d9dd952 100644
+--- a/lib/airspyhf/airspyhf_source_c.h
++++ b/lib/airspyhf/airspyhf_source_c.h
+@@ -35,7 +35,7 @@
+
+ class airspyhf_source_c;
+
+-typedef boost::shared_ptr<airspyhf_source_c> airspyhf_source_c_sptr;
++typedef std::shared_ptr<airspyhf_source_c> airspyhf_source_c_sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of airspyhf_source_c.
+diff --git a/lib/bladerf/bladerf_sink_c.h b/lib/bladerf/bladerf_sink_c.h
+index 9f8a496..268f8df 100644
+--- a/lib/bladerf/bladerf_sink_c.h
++++ b/lib/bladerf/bladerf_sink_c.h
+@@ -30,7 +30,7 @@
+ class bladerf_sink_c;
+
+ /*
+- * We use boost::shared_ptr's instead of raw pointers for all access
++ * We use std::shared_ptr's instead of raw pointers for all access
+ * to gr_blocks (and many other data structures). The shared_ptr gets
+ * us transparent reference counting, which greatly simplifies storage
+ * management issues. This is especially helpful in our hybrid
+@@ -38,9 +38,9 @@ class bladerf_sink_c;
+ *
+ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
+ *
+- * As a convention, the _sptr suffix indicates a boost::shared_ptr
++ * As a convention, the _sptr suffix indicates a std::shared_ptr
+ */
+-typedef boost::shared_ptr<bladerf_sink_c> bladerf_sink_c_sptr;
++typedef std::shared_ptr<bladerf_sink_c> bladerf_sink_c_sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of bladerf_sink_c.
+diff --git a/lib/bladerf/bladerf_source_c.h b/lib/bladerf/bladerf_source_c.h
+index 05f9ddf..0cc26f4 100644
+--- a/lib/bladerf/bladerf_source_c.h
++++ b/lib/bladerf/bladerf_source_c.h
+@@ -30,7 +30,7 @@
+ class bladerf_source_c;
+
+ /*
+- * We use boost::shared_ptr's instead of raw pointers for all access
++ * We use std::shared_ptr's instead of raw pointers for all access
+ * to gr_blocks (and many other data structures). The shared_ptr gets
+ * us transparent reference counting, which greatly simplifies storage
+ * management issues. This is especially helpful in our hybrid
+@@ -38,9 +38,9 @@ class bladerf_source_c;
+ *
+ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
+ *
+- * As a convention, the _sptr suffix indicates a boost::shared_ptr
++ * As a convention, the _sptr suffix indicates a std::shared_ptr
+ */
+-typedef boost::shared_ptr<bladerf_source_c> bladerf_source_c_sptr;
++typedef std::shared_ptr<bladerf_source_c> bladerf_source_c_sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of bladerf_source_c.
+diff --git a/lib/fcd/fcd_source_c.h b/lib/fcd/fcd_source_c.h
+index 2b02eb1..876e237 100644
+--- a/lib/fcd/fcd_source_c.h
++++ b/lib/fcd/fcd_source_c.h
+@@ -29,7 +29,7 @@
+
+ class fcd_source_c;
+
+-typedef boost::shared_ptr< fcd_source_c > fcd_source_c_sptr;
++typedef std::shared_ptr< fcd_source_c > fcd_source_c_sptr;
+
+ fcd_source_c_sptr make_fcd_source_c( const std::string & args = "" );
+
+diff --git a/lib/file/file_sink_c.h b/lib/file/file_sink_c.h
+index 6e59451..dac30f0 100644
+--- a/lib/file/file_sink_c.h
++++ b/lib/file/file_sink_c.h
+@@ -28,7 +28,7 @@
+
+ class file_sink_c;
+
+-typedef boost::shared_ptr< file_sink_c > file_sink_c_sptr;
++typedef std::shared_ptr< file_sink_c > file_sink_c_sptr;
+
+ file_sink_c_sptr make_file_sink_c( const std::string & args = "" );
+
+diff --git a/lib/file/file_source_c.h b/lib/file/file_source_c.h
+index 3e03037..b3d8b47 100644
+--- a/lib/file/file_source_c.h
++++ b/lib/file/file_source_c.h
+@@ -28,7 +28,7 @@
+
+ class file_source_c;
+
+-typedef boost::shared_ptr< file_source_c > file_source_c_sptr;
++typedef std::shared_ptr< file_source_c > file_source_c_sptr;
+
+ file_source_c_sptr make_file_source_c( const std::string & args = "" );
+
+diff --git a/lib/freesrp/freesrp_sink_c.h b/lib/freesrp/freesrp_sink_c.h
+index ce75785..23dd8ff 100644
+--- a/lib/freesrp/freesrp_sink_c.h
++++ b/lib/freesrp/freesrp_sink_c.h
+@@ -39,7 +39,7 @@
+ class freesrp_sink_c;
+
+ /*
+- * We use boost::shared_ptr's instead of raw pointers for all access
++ * We use std::shared_ptr's instead of raw pointers for all access
+ * to gr_blocks (and many other data structures). The shared_ptr gets
+ * us transparent reference counting, which greatly simplifies storage
+ * management issues. This is especially helpful in our hybrid
+@@ -47,9 +47,9 @@ class freesrp_sink_c;
+ *
+ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
+ *
+- * As a convention, the _sptr suffix indicates a boost::shared_ptr
++ * As a convention, the _sptr suffix indicates a std::shared_ptr
+ */
+-typedef boost::shared_ptr<freesrp_sink_c> freesrp_sink_c_sptr;
++typedef std::shared_ptr<freesrp_sink_c> freesrp_sink_c_sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of freesrp_sink_c.
+diff --git a/lib/freesrp/freesrp_source_c.h b/lib/freesrp/freesrp_source_c.h
+index 08f115c..6b1604c 100644
+--- a/lib/freesrp/freesrp_source_c.h
++++ b/lib/freesrp/freesrp_source_c.h
+@@ -40,7 +40,7 @@
+ class freesrp_source_c;
+
+ /*
+- * We use boost::shared_ptr's instead of raw pointers for all access
++ * We use std::shared_ptr's instead of raw pointers for all access
+ * to gr_blocks (and many other data structures). The shared_ptr gets
+ * us transparent reference counting, which greatly simplifies storage
+ * management issues. This is especially helpful in our hybrid
+@@ -48,9 +48,9 @@ class freesrp_source_c;
+ *
+ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
+ *
+- * As a convention, the _sptr suffix indicates a boost::shared_ptr
++ * As a convention, the _sptr suffix indicates a std::shared_ptr
+ */
+-typedef boost::shared_ptr<freesrp_source_c> freesrp_source_c_sptr;
++typedef std::shared_ptr<freesrp_source_c> freesrp_source_c_sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of freesrp_source_c.
+diff --git a/lib/hackrf/hackrf_sink_c.h b/lib/hackrf/hackrf_sink_c.h
+index 08ff2ca..ef719f3 100644
+--- a/lib/hackrf/hackrf_sink_c.h
++++ b/lib/hackrf/hackrf_sink_c.h
+@@ -45,7 +45,7 @@ typedef struct circular_buffer
+ } circular_buffer_t;
+
+ /*
+- * We use boost::shared_ptr's instead of raw pointers for all access
++ * We use std::shared_ptr's instead of raw pointers for all access
+ * to gr::blocks (and many other data structures). The shared_ptr gets
+ * us transparent reference counting, which greatly simplifies storage
+ * management issues. This is especially helpful in our hybrid
+@@ -53,9 +53,9 @@ typedef struct circular_buffer
+ *
+ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
+ *
+- * As a convention, the _sptr suffix indicates a boost::shared_ptr
++ * As a convention, the _sptr suffix indicates a std::shared_ptr
+ */
+-typedef boost::shared_ptr<hackrf_sink_c> hackrf_sink_c_sptr;
++typedef std::shared_ptr<hackrf_sink_c> hackrf_sink_c_sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of hackrf_sink_c.
+diff --git a/lib/hackrf/hackrf_source_c.h b/lib/hackrf/hackrf_source_c.h
+index 0d38ac0..55a0fbb 100644
+--- a/lib/hackrf/hackrf_source_c.h
++++ b/lib/hackrf/hackrf_source_c.h
+@@ -34,7 +34,7 @@
+ class hackrf_source_c;
+
+ /*
+- * We use boost::shared_ptr's instead of raw pointers for all access
++ * We use std::shared_ptr's instead of raw pointers for all access
+ * to gr::blocks (and many other data structures). The shared_ptr gets
+ * us transparent reference counting, which greatly simplifies storage
+ * management issues. This is especially helpful in our hybrid
+@@ -42,9 +42,9 @@ class hackrf_source_c;
+ *
+ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
+ *
+- * As a convention, the _sptr suffix indicates a boost::shared_ptr
++ * As a convention, the _sptr suffix indicates a std::shared_ptr
+ */
+-typedef boost::shared_ptr<hackrf_source_c> hackrf_source_c_sptr;
++typedef std::shared_ptr<hackrf_source_c> hackrf_source_c_sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of hackrf_source_c.
+diff --git a/lib/redpitaya/redpitaya_sink_c.h b/lib/redpitaya/redpitaya_sink_c.h
+index e03a13a..fceaa77 100644
+--- a/lib/redpitaya/redpitaya_sink_c.h
++++ b/lib/redpitaya/redpitaya_sink_c.h
+@@ -29,7 +29,7 @@
+
+ class redpitaya_sink_c;
+
+-typedef boost::shared_ptr< redpitaya_sink_c > redpitaya_sink_c_sptr;
++typedef std::shared_ptr< redpitaya_sink_c > redpitaya_sink_c_sptr;
+
+ redpitaya_sink_c_sptr make_redpitaya_sink_c( const std::string & args = "" );
+
+diff --git a/lib/redpitaya/redpitaya_source_c.h b/lib/redpitaya/redpitaya_source_c.h
+index 7d536ee..f4a2d80 100644
+--- a/lib/redpitaya/redpitaya_source_c.h
++++ b/lib/redpitaya/redpitaya_source_c.h
+@@ -29,7 +29,7 @@
+
+ class redpitaya_source_c;
+
+-typedef boost::shared_ptr< redpitaya_source_c > redpitaya_source_c_sptr;
++typedef std::shared_ptr< redpitaya_source_c > redpitaya_source_c_sptr;
+
+ redpitaya_source_c_sptr make_redpitaya_source_c( const std::string & args = "" );
+
+diff --git a/lib/rfspace/rfspace_source_c.h b/lib/rfspace/rfspace_source_c.h
+index d2bf66d..996f47b 100644
+--- a/lib/rfspace/rfspace_source_c.h
++++ b/lib/rfspace/rfspace_source_c.h
+@@ -38,7 +38,7 @@ class rfspace_source_c;
+ #endif
+
+ /*
+- * We use boost::shared_ptr's instead of raw pointers for all access
++ * We use std::shared_ptr's instead of raw pointers for all access
+ * to gr_blocks (and many other data structures). The shared_ptr gets
+ * us transparent reference counting, which greatly simplifies storage
+ * management issues. This is especially helpful in our hybrid
+@@ -46,9 +46,9 @@ class rfspace_source_c;
+ *
+ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
+ *
+- * As a convention, the _sptr suffix indicates a boost::shared_ptr
++ * As a convention, the _sptr suffix indicates a std::shared_ptr
+ */
+-typedef boost::shared_ptr<rfspace_source_c> rfspace_source_c_sptr;
++typedef std::shared_ptr<rfspace_source_c> rfspace_source_c_sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of rfspace_source_c.
+diff --git a/lib/rtl/rtl_source_c.h b/lib/rtl/rtl_source_c.h
+index de3e349..99f14f4 100644
+--- a/lib/rtl/rtl_source_c.h
++++ b/lib/rtl/rtl_source_c.h
+@@ -35,7 +35,7 @@ class rtl_source_c;
+ typedef struct rtlsdr_dev rtlsdr_dev_t;
+
+ /*
+- * We use boost::shared_ptr's instead of raw pointers for all access
++ * We use std::shared_ptr's instead of raw pointers for all access
+ * to gr::blocks (and many other data structures). The shared_ptr gets
+ * us transparent reference counting, which greatly simplifies storage
+ * management issues. This is especially helpful in our hybrid
+@@ -43,9 +43,9 @@ typedef struct rtlsdr_dev rtlsdr_dev_t;
+ *
+ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
+ *
+- * As a convention, the _sptr suffix indicates a boost::shared_ptr
++ * As a convention, the _sptr suffix indicates a std::shared_ptr
+ */
+-typedef boost::shared_ptr<rtl_source_c> rtl_source_c_sptr;
++typedef std::shared_ptr<rtl_source_c> rtl_source_c_sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of rtl_source_c.
+diff --git a/lib/rtl_tcp/rtl_tcp_source_c.h b/lib/rtl_tcp/rtl_tcp_source_c.h
+index b07e5dd..2c11018 100644
+--- a/lib/rtl_tcp/rtl_tcp_source_c.h
++++ b/lib/rtl_tcp/rtl_tcp_source_c.h
+@@ -26,7 +26,7 @@
+
+ class rtl_tcp_source_c;
+
+-typedef boost::shared_ptr< rtl_tcp_source_c > rtl_tcp_source_c_sptr;
++typedef std::shared_ptr< rtl_tcp_source_c > rtl_tcp_source_c_sptr;
+
+ rtl_tcp_source_c_sptr make_rtl_tcp_source_c( const std::string & args = "" );
+
+diff --git a/lib/rtl_tcp/rtl_tcp_source_f.h b/lib/rtl_tcp/rtl_tcp_source_f.h
+index 84ac57a..e9bc87d 100644
+--- a/lib/rtl_tcp/rtl_tcp_source_f.h
++++ b/lib/rtl_tcp/rtl_tcp_source_f.h
+@@ -59,7 +59,7 @@ enum rtlsdr_tuner {
+ };
+
+ class rtl_tcp_source_f;
+-typedef boost::shared_ptr<rtl_tcp_source_f> rtl_tcp_source_f_sptr;
++typedef std::shared_ptr<rtl_tcp_source_f> rtl_tcp_source_f_sptr;
+
+ rtl_tcp_source_f_sptr make_rtl_tcp_source_f (
+ size_t itemsize,
+diff --git a/lib/sdrplay/sdrplay_source_c.h b/lib/sdrplay/sdrplay_source_c.h
+index b59f44a..9ea6cb9 100644
+--- a/lib/sdrplay/sdrplay_source_c.h
++++ b/lib/sdrplay/sdrplay_source_c.h
+@@ -36,7 +36,7 @@ class sdrplay_source_c;
+ typedef struct sdrplay_dev sdrplay_dev_t;
+
+ /*
+- * We use boost::shared_ptr's instead of raw pointers for all access
++ * We use std::shared_ptr's instead of raw pointers for all access
+ * to gr::blocks (and many other data structures). The shared_ptr gets
+ * us transparent reference counting, which greatly simplifies storage
+ * management issues. This is especially helpful in our hybrid
+@@ -44,9 +44,9 @@ typedef struct sdrplay_dev sdrplay_dev_t;
+ *
+ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
+ *
+- * As a convention, the _sptr suffix indicates a boost::shared_ptr
++ * As a convention, the _sptr suffix indicates a std::shared_ptr
+ */
+-typedef boost::shared_ptr<sdrplay_source_c> sdrplay_source_c_sptr;
++typedef std::shared_ptr<sdrplay_source_c> sdrplay_source_c_sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of sdrplay_source_c.
+diff --git a/lib/soapy/soapy_sink_c.h b/lib/soapy/soapy_sink_c.h
+index 4900d15..514f954 100644
+--- a/lib/soapy/soapy_sink_c.h
++++ b/lib/soapy/soapy_sink_c.h
+@@ -36,7 +36,7 @@ namespace SoapySDR
+ }
+
+ /*
+- * We use boost::shared_ptr's instead of raw pointers for all access
++ * We use std::shared_ptr's instead of raw pointers for all access
+ * to gr_blocks (and many other data structures). The shared_ptr gets
+ * us transparent reference counting, which greatly simplifies storage
+ * management issues. This is especially helpful in our hybrid
+@@ -44,9 +44,9 @@ namespace SoapySDR
+ *
+ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
+ *
+- * As a convention, the _sptr suffix indicates a boost::shared_ptr
++ * As a convention, the _sptr suffix indicates a std::shared_ptr
+ */
+-typedef boost::shared_ptr<soapy_sink_c> soapy_sink_c_sptr;
++typedef std::shared_ptr<soapy_sink_c> soapy_sink_c_sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of soapy_sink_c.
+diff --git a/lib/soapy/soapy_source_c.h b/lib/soapy/soapy_source_c.h
+index b4db1ce..7ae6322 100644
+--- a/lib/soapy/soapy_source_c.h
++++ b/lib/soapy/soapy_source_c.h
+@@ -36,7 +36,7 @@ namespace SoapySDR
+ }
+
+ /*
+- * We use boost::shared_ptr's instead of raw pointers for all access
++ * We use std::shared_ptr's instead of raw pointers for all access
+ * to gr_blocks (and many other data structures). The shared_ptr gets
+ * us transparent reference counting, which greatly simplifies storage
+ * management issues. This is especially helpful in our hybrid
+@@ -44,9 +44,9 @@ namespace SoapySDR
+ *
+ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
+ *
+- * As a convention, the _sptr suffix indicates a boost::shared_ptr
++ * As a convention, the _sptr suffix indicates a std::shared_ptr
+ */
+-typedef boost::shared_ptr<soapy_source_c> soapy_source_c_sptr;
++typedef std::shared_ptr<soapy_source_c> soapy_source_c_sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of soapy_source_c.
+diff --git a/lib/uhd/uhd_sink_c.h b/lib/uhd/uhd_sink_c.h
+index 700fe4a..9b673b0 100644
+--- a/lib/uhd/uhd_sink_c.h
++++ b/lib/uhd/uhd_sink_c.h
+@@ -27,7 +27,7 @@
+
+ class uhd_sink_c;
+
+-typedef boost::shared_ptr< uhd_sink_c > uhd_sink_c_sptr;
++typedef std::shared_ptr< uhd_sink_c > uhd_sink_c_sptr;
+
+ uhd_sink_c_sptr make_uhd_sink_c(const std::string &args = "");
+
+diff --git a/lib/uhd/uhd_source_c.h b/lib/uhd/uhd_source_c.h
+index e80be99..f3b2797 100644
+--- a/lib/uhd/uhd_source_c.h
++++ b/lib/uhd/uhd_source_c.h
+@@ -27,7 +27,7 @@
+
+ class uhd_source_c;
+
+-typedef boost::shared_ptr< uhd_source_c > uhd_source_c_sptr;
++typedef std::shared_ptr< uhd_source_c > uhd_source_c_sptr;
+
+ uhd_source_c_sptr make_uhd_source_c(const std::string &args = "");
+
+diff --git a/lib/xtrx/xtrx_obj.h b/lib/xtrx/xtrx_obj.h
+index e26947d..8f64260 100644
+--- a/lib/xtrx/xtrx_obj.h
++++ b/lib/xtrx/xtrx_obj.h
+@@ -28,7 +28,7 @@
+
+ class xtrx_obj;
+
+-typedef boost::shared_ptr<xtrx_obj> xtrx_obj_sptr;
++typedef std::shared_ptr<xtrx_obj> xtrx_obj_sptr;
+
+ class xtrx_obj
+ {
+diff --git a/lib/xtrx/xtrx_sink_c.h b/lib/xtrx/xtrx_sink_c.h
+index 1263858..e923900 100644
+--- a/lib/xtrx/xtrx_sink_c.h
++++ b/lib/xtrx/xtrx_sink_c.h
+@@ -36,7 +36,7 @@ static const pmt::pmt_t COMMAND_KEY = pmt::string_to_symbol("tx_command");
+
+ class xtrx_sink_c;
+
+-typedef boost::shared_ptr< xtrx_sink_c > xtrx_sink_c_sptr;
++typedef std::shared_ptr< xtrx_sink_c > xtrx_sink_c_sptr;
+
+ xtrx_sink_c_sptr make_xtrx_sink_c( const std::string & args = "" );
+
+diff --git a/lib/xtrx/xtrx_source_c.h b/lib/xtrx/xtrx_source_c.h
+index fda9d77..6ec2fb2 100644
+--- a/lib/xtrx/xtrx_source_c.h
++++ b/lib/xtrx/xtrx_source_c.h
+@@ -32,7 +32,7 @@ static const pmt::pmt_t FREQ_KEY = pmt::string_to_symbol("rx_freq");
+
+ class xtrx_source_c;
+
+-typedef boost::shared_ptr< xtrx_source_c > xtrx_source_c_sptr;
++typedef std::shared_ptr< xtrx_source_c > xtrx_source_c_sptr;
+
+ xtrx_source_c_sptr make_xtrx_source_c( const std::string & args = "" );
+
+diff --git a/swig/osmosdr_swig.i b/swig/osmosdr_swig.i
+index 550008b..da42e6e 100644
+--- a/swig/osmosdr_swig.i
++++ b/swig/osmosdr_swig.i
+@@ -63,7 +63,7 @@
+ };
+
+ %define OSMOSDR_SWIG_BLOCK_MAGIC2(PKG, BASE_NAME)
+-%template(BASE_NAME ## _sptr) boost::shared_ptr<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;
+--
+cgit v1.2.3
+