summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt7
-rw-r--r--cmake/Modules/CodeCoverage.cmake197
-rw-r--r--cmake/Modules/GrBuildTypes.cmake33
-rw-r--r--cmake/Modules/GrTest.cmake1
-rw-r--r--config.h.in6
-rw-r--r--gnuradio-runtime/CMakeLists.txt1
-rw-r--r--gnuradio-runtime/gnuradio-runtime.pc.in2
-rw-r--r--gnuradio-runtime/include/gnuradio/logger.h.in51
-rw-r--r--gr-audio/include/gnuradio/audio/osx_impl.h14
-rw-r--r--gr-audio/lib/osx/osx_common.h5
-rw-r--r--gr-audio/lib/osx/osx_impl.cc8
-rw-r--r--gr-blocks/python/blocks/qa_file_source_sink.py79
-rw-r--r--gr-digital/lib/additive_scrambler_bb_impl.cc41
-rwxr-xr-xgr-digital/python/digital/qa_scrambler.py31
-rw-r--r--gr-qtgui/grc/qtgui_label.xml4
15 files changed, 403 insertions, 77 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 650cfe3ac4..3b692bc92b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -327,6 +327,13 @@ if(DEFINED ALL_DLL_FILES)
install(FILES ${ALL_DLL_FILES} DESTINATION ${GR_RUNTIME_DIR} COMPONENT "extra_dlls")
endif()
+if(${CMAKE_BUILD_TYPE} STREQUAL "Coverage")
+ include(CodeCoverage)
+ setup_target_for_coverage(coverage "ctest" coverage)
+endif()
+
+
+
########################################################################
# Setup volk as a subproject
########################################################################
diff --git a/cmake/Modules/CodeCoverage.cmake b/cmake/Modules/CodeCoverage.cmake
new file mode 100644
index 0000000000..a0b0ef5269
--- /dev/null
+++ b/cmake/Modules/CodeCoverage.cmake
@@ -0,0 +1,197 @@
+# Copyright (c) 2012 - 2015, Lars Bilke
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+#
+#
+# 2012-01-31, Lars Bilke
+# - Enable Code Coverage
+#
+# 2013-09-17, Joakim Söderberg
+# - Added support for Clang.
+# - Some additional usage instructions.
+#
+# USAGE:
+
+# 0. (Mac only) If you use Xcode 5.1 make sure to patch geninfo as described here:
+# http://stackoverflow.com/a/22404544/80480
+#
+# 1. Copy this file into your cmake modules path.
+#
+# 2. Add the following line to your CMakeLists.txt:
+# INCLUDE(CodeCoverage)
+#
+# 3. Set compiler flags to turn off optimization and enable coverage:
+# SET(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
+# SET(CMAKE_C_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
+#
+# 3. Use the function SETUP_TARGET_FOR_COVERAGE to create a custom make target
+# which runs your test executable and produces a lcov code coverage report:
+# Example:
+# SETUP_TARGET_FOR_COVERAGE(
+# my_coverage_target # Name for custom target.
+# test_driver # Name of the test driver executable that runs the tests.
+# # NOTE! This should always have a ZERO as exit code
+# # otherwise the coverage generation will not complete.
+# coverage # Name of output directory.
+# )
+#
+# 4. Build a Debug build:
+# cmake -DCMAKE_BUILD_TYPE=Debug ..
+# make
+# make my_coverage_target
+#
+#
+
+# Check prereqs
+FIND_PROGRAM( GCOV_PATH gcov )
+FIND_PROGRAM( LCOV_PATH lcov )
+FIND_PROGRAM( GENHTML_PATH genhtml )
+FIND_PROGRAM( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/tests)
+
+IF(NOT GCOV_PATH)
+ MESSAGE(FATAL_ERROR "gcov not found! Aborting...")
+ENDIF() # NOT GCOV_PATH
+
+IF("${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
+ IF("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS 3)
+ MESSAGE(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...")
+ ENDIF()
+ELSEIF(NOT CMAKE_COMPILER_IS_GNUCXX)
+ MESSAGE(FATAL_ERROR "Compiler is not GNU gcc! Aborting...")
+ENDIF() # CHECK VALID COMPILER
+
+SET(CMAKE_CXX_FLAGS_COVERAGE
+ "-g -O0 --coverage -fprofile-arcs -ftest-coverage"
+ CACHE STRING "Flags used by the C++ compiler during coverage builds."
+ FORCE )
+SET(CMAKE_C_FLAGS_COVERAGE
+ "-g -O0 --coverage -fprofile-arcs -ftest-coverage"
+ CACHE STRING "Flags used by the C compiler during coverage builds."
+ FORCE )
+SET(CMAKE_EXE_LINKER_FLAGS_COVERAGE
+ ""
+ CACHE STRING "Flags used for linking binaries during coverage builds."
+ FORCE )
+SET(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
+ ""
+ CACHE STRING "Flags used by the shared libraries linker during coverage builds."
+ FORCE )
+MARK_AS_ADVANCED(
+ CMAKE_CXX_FLAGS_COVERAGE
+ CMAKE_C_FLAGS_COVERAGE
+ CMAKE_EXE_LINKER_FLAGS_COVERAGE
+ CMAKE_SHARED_LINKER_FLAGS_COVERAGE )
+
+IF ( NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "Coverage"))
+ MESSAGE( WARNING "Code coverage results with an optimized (non-Debug) build may be misleading" )
+ENDIF() # NOT CMAKE_BUILD_TYPE STREQUAL "Debug"
+
+
+# Param _targetname The name of new the custom make target
+# Param _testrunner The name of the target which runs the tests.
+# MUST return ZERO always, even on errors.
+# If not, no coverage report will be created!
+# Param _outputname lcov output is generated as _outputname.info
+# HTML report is generated in _outputname/index.html
+# Optional fourth parameter is passed as arguments to _testrunner
+# Pass them in list form, e.g.: "-j;2" for -j 2
+FUNCTION(SETUP_TARGET_FOR_COVERAGE _targetname _testrunner _outputname)
+
+ IF(NOT LCOV_PATH)
+ MESSAGE(FATAL_ERROR "lcov not found! Aborting...")
+ ENDIF() # NOT LCOV_PATH
+
+ IF(NOT GENHTML_PATH)
+ MESSAGE(FATAL_ERROR "genhtml not found! Aborting...")
+ ENDIF() # NOT GENHTML_PATH
+
+ SET(coverage_info "${CMAKE_BINARY_DIR}/${_outputname}.info")
+ SET(coverage_cleaned "${coverage_info}.cleaned")
+
+ SEPARATE_ARGUMENTS(test_command UNIX_COMMAND "${_testrunner}")
+
+ # Setup target
+ ADD_CUSTOM_TARGET(${_targetname}
+
+ # Cleanup lcov
+ ${LCOV_PATH} --directory . --zerocounters
+
+ # Run tests
+ COMMAND ${test_command} ${ARGV3}
+
+ # Capturing lcov counters and generating report
+ COMMAND ${LCOV_PATH} --directory . --capture --output-file ${coverage_info}
+ COMMAND ${LCOV_PATH} --remove ${coverage_info} 'tests/*' '/usr/*' --output-file ${coverage_cleaned}
+ COMMAND ${GENHTML_PATH} -o ${_outputname} ${coverage_cleaned}
+ COMMAND ${CMAKE_COMMAND} -E remove ${coverage_info} ${coverage_cleaned}
+
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report."
+ )
+
+ # Show info where to find the report
+ ADD_CUSTOM_COMMAND(TARGET ${_targetname} POST_BUILD
+ COMMAND ;
+ COMMENT "Open ./${_outputname}/index.html in your browser to view the coverage report."
+ )
+
+ENDFUNCTION() # SETUP_TARGET_FOR_COVERAGE
+
+# Param _targetname The name of new the custom make target
+# Param _testrunner The name of the target which runs the tests
+# Param _outputname cobertura output is generated as _outputname.xml
+# Optional fourth parameter is passed as arguments to _testrunner
+# Pass them in list form, e.g.: "-j;2" for -j 2
+FUNCTION(SETUP_TARGET_FOR_COVERAGE_COBERTURA _targetname _testrunner _outputname)
+
+ IF(NOT PYTHON_EXECUTABLE)
+ MESSAGE(FATAL_ERROR "Python not found! Aborting...")
+ ENDIF() # NOT PYTHON_EXECUTABLE
+
+ IF(NOT GCOVR_PATH)
+ MESSAGE(FATAL_ERROR "gcovr not found! Aborting...")
+ ENDIF() # NOT GCOVR_PATH
+
+ ADD_CUSTOM_TARGET(${_targetname}
+
+ # Run tests
+ ${_testrunner} ${ARGV3}
+
+ # Running gcovr
+ COMMAND ${GCOVR_PATH} -x -r ${CMAKE_SOURCE_DIR} -e '${CMAKE_SOURCE_DIR}/tests/' -o ${_outputname}.xml
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ COMMENT "Running gcovr to produce Cobertura code coverage report."
+ )
+
+ # Show info where to find the report
+ ADD_CUSTOM_COMMAND(TARGET ${_targetname} POST_BUILD
+ COMMAND ;
+ COMMENT "Cobertura code coverage report saved in ${_outputname}.xml."
+ )
+
+ENDFUNCTION() # SETUP_TARGET_FOR_COVERAGE_COBERTURA
diff --git a/cmake/Modules/GrBuildTypes.cmake b/cmake/Modules/GrBuildTypes.cmake
index 34614c9d08..5789d88934 100644
--- a/cmake/Modules/GrBuildTypes.cmake
+++ b/cmake/Modules/GrBuildTypes.cmake
@@ -38,7 +38,7 @@ set(__INCLUDED_GR_BUILD_TYPES_CMAKE TRUE)
# build type below, make sure to add it to this list.
list(APPEND AVAIL_BUILDTYPES
None Debug Release RelWithDebInfo MinSizeRel
- NoOptWithASM O2WithASM O3WithASM
+ Coverage NoOptWithASM O2WithASM O3WithASM
)
########################################################################
@@ -67,6 +67,37 @@ endfunction(GR_CHECK_BUILD_TYPE)
########################################################################
# For GCC and Clang, we can set a build type:
#
+# -DCMAKE_BUILD_TYPE=Coverage
+#
+# This type uses no optimization (-O0), outputs debug symbols (-g) and
+# outputs all intermediary files the build system produces, including
+# all assembly (.s) files. Look in the build directory for these
+# files.
+# NOTE: This is not defined on Windows systems.
+########################################################################
+if(NOT WIN32)
+ SET(CMAKE_CXX_FLAGS_COVERAGE "-Wall -pedantic -pthread -g -O0 -fprofile-arcs -ftest-coverage" CACHE STRING
+ "Flags used by the C++ compiler during Coverage builds." FORCE)
+ SET(CMAKE_C_FLAGS_COVERAGE "-Wall -pedantic -pthread -g -O0 -fprofile-arcs -ftest-coverage" CACHE STRING
+ "Flags used by the C compiler during Coverage builds." FORCE)
+ SET(CMAKE_EXE_LINKER_FLAGS_COVERAGE
+ "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
+ "Flags used for linking binaries during Coverage builds." FORCE)
+ SET(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
+ "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
+ "Flags used by the shared lib linker during Coverage builds." FORCE)
+
+ MARK_AS_ADVANCED(
+ CMAKE_CXX_FLAGS_COVERAGE
+ CMAKE_C_FLAGS_COVERAGE
+ CMAKE_EXE_LINKER_FLAGS_COVERAGE
+ CMAKE_SHARED_LINKER_FLAGS_COVERAGE)
+endif(NOT WIN32)
+
+
+########################################################################
+# For GCC and Clang, we can set a build type:
+#
# -DCMAKE_BUILD_TYPE=NoOptWithASM
#
# This type uses no optimization (-O0), outputs debug symbols (-g) and
diff --git a/cmake/Modules/GrTest.cmake b/cmake/Modules/GrTest.cmake
index 69df96d4c8..5f90be3326 100644
--- a/cmake/Modules/GrTest.cmake
+++ b/cmake/Modules/GrTest.cmake
@@ -113,7 +113,6 @@ function(GR_ADD_TEST test_name)
execute_process(COMMAND chmod +x ${sh_file})
add_test(${test_name} ${SHELL} ${sh_file})
-
endif(UNIX)
if(WIN32)
diff --git a/config.h.in b/config.h.in
index ad6e3d022c..e1f98cdac4 100644
--- a/config.h.in
+++ b/config.h.in
@@ -36,11 +36,5 @@
#ifndef GR_RPCSERVER_THRIFT
#cmakedefine GR_RPCSERVER_THRIFT
#endif
-#ifndef ENABLE_GR_LOG
-#cmakedefine ENABLE_GR_LOG
-#endif
-#ifndef HAVE_LOG4CPP
-#cmakedefine HAVE_LOG4CPP
-#endif
#endif /* GNURADIO_CONFIG_H */
diff --git a/gnuradio-runtime/CMakeLists.txt b/gnuradio-runtime/CMakeLists.txt
index 7660642509..b41fb5889f 100644
--- a/gnuradio-runtime/CMakeLists.txt
+++ b/gnuradio-runtime/CMakeLists.txt
@@ -139,6 +139,7 @@ install(FILES
DESTINATION ${GR_PREFSDIR}
COMPONENT "runtime_runtime"
)
+set(PC_ADD_LIBS -llog4cpp)
endif(ENABLE_GR_LOG AND HAVE_LOG4CPP)
########################################################################
diff --git a/gnuradio-runtime/gnuradio-runtime.pc.in b/gnuradio-runtime/gnuradio-runtime.pc.in
index d4488896cb..acd052d3c6 100644
--- a/gnuradio-runtime/gnuradio-runtime.pc.in
+++ b/gnuradio-runtime/gnuradio-runtime.pc.in
@@ -7,5 +7,5 @@ Name: gnuradio-runtime
Description: GNU Radio core runtime infrastructure
Requires:
Version: @LIBVER@
-Libs: -L${libdir} -lgnuradio-runtime -lgnuradio-pmt
+Libs: -L${libdir} -lgnuradio-runtime -lgnuradio-pmt @PC_ADD_LIBS@
Cflags: -I${includedir}
diff --git a/gnuradio-runtime/include/gnuradio/logger.h.in b/gnuradio-runtime/include/gnuradio/logger.h.in
index 08cb209c7b..13fda6f6c4 100644
--- a/gnuradio-runtime/include/gnuradio/logger.h.in
+++ b/gnuradio-runtime/include/gnuradio/logger.h.in
@@ -35,13 +35,60 @@
*
*/
-#ifndef ENABLE_GR_LOG
+// handle current status of GR_LOG
+#ifdef EXT_ENABLE_GR_LOG
+#undef EXT_ENABLE_GR_LOG
+#endif
+#ifdef ENABLE_GR_LOG
+#define EXT_ENABLE_GR_LOG
+#undef ENABLE_GR_LOG
+#endif
+
+// did GR enable LOG?
#cmakedefine ENABLE_GR_LOG
+
+// if GR does not provide logging and the current module is requesting
+// it, disable it.
+#if defined(EXT_ENABLE_GR_LOG) && !defined(ENABLE_GR_LOG)
+#warning "Logging was requested but is not enabled in GNU Radio, so disabling."
+#undef EXT_ENABLE_GR_LOG
#endif
-#ifndef HAVE_LOG4CPP
+
+// if GR provides logging but the current module is not requesting it,
+// disable it.
+#if !defined(EXT_ENABLE_GR_LOG) && defined(ENABLE_GR_LOG)
+#undef ENABLE_GR_LOG
+#endif
+
+// the other 2 cases work; no need to check them!
+
+// handle current status of LOG4CPP
+#ifdef EXT_HAVE_LOG4CPP
+#undef EXT_HAVE_LOG4CPP
+#endif
+#ifdef HAVE_LOG4CPP
+#define EXT_HAVE_LOG4CPP
+#undef HAVE_LOG4CPP
+#endif
+
+// did GR use log4cpp?
#cmakedefine HAVE_LOG4CPP
+
+// if GR does not use log4cpp and the current module is requesting it,
+// disable it & print a warning.
+#if defined(EXT_HAVE_LOG4CPP) && !defined(HAVE_LOG4CPP)
+#warning "Log4Cpp use was requested but was not in GNU Radio, so disabling."
+#undef EXT_HAVE_LOG4CPP
+#endif
+
+// if GR provides for using log4cpp but the current module is not
+// requesting it, disable it quietly.
+#if !defined(EXT_HAVE_LOG4CPP) && defined(HAVE_LOG4CPP)
+#undef HAVE_LOG4CPP
#endif
+// the other 2 cases work; no need to check them!
+
#ifdef _MSC_VER
typedef unsigned short mode_t;
#else
diff --git a/gr-audio/include/gnuradio/audio/osx_impl.h b/gr-audio/include/gnuradio/audio/osx_impl.h
index 891685a335..6db130447e 100644
--- a/gr-audio/include/gnuradio/audio/osx_impl.h
+++ b/gr-audio/include/gnuradio/audio/osx_impl.h
@@ -33,10 +33,6 @@
#include <AudioToolbox/AudioToolbox.h>
#include <AudioUnit/AudioUnit.h>
-namespace gr {
-namespace audio {
-namespace osx {
-
// Check the version of MacOSX being used
#ifdef __APPLE_CC__
#include <AvailabilityMacros.h>
@@ -50,15 +46,19 @@ namespace osx {
// helper function to print an ASBD
-extern std::ostream& GR_AUDIO_API
+std::ostream& GR_AUDIO_API
operator<<
(std::ostream& s,
const AudioStreamBasicDescription& asbd);
+namespace gr {
+namespace audio {
+namespace osx {
+
// returns the number of channels for the provided AudioDeviceID,
// input and/or output depending on if the pointer is valid.
-extern void GR_AUDIO_API
+void GR_AUDIO_API
get_num_channels_for_audio_device_id
(AudioDeviceID ad_id,
UInt32* n_input,
@@ -70,7 +70,7 @@ get_num_channels_for_audio_device_id
// matching names. If the device name is empty, then match all
// input or output devices.
-extern void GR_AUDIO_API
+void GR_AUDIO_API
find_audio_devices
(const std::string& device_name,
bool is_input,
diff --git a/gr-audio/lib/osx/osx_common.h b/gr-audio/lib/osx/osx_common.h
index 59b866dbe3..5d8a3800a5 100644
--- a/gr-audio/lib/osx/osx_common.h
+++ b/gr-audio/lib/osx/osx_common.h
@@ -29,8 +29,13 @@ namespace gr {
namespace audio {
namespace osx {
+#ifndef _OSX_AU_DEBUG_
#define _OSX_AU_DEBUG_ 0
+#endif
+
+#ifndef _OSX_AU_DEBUG_RENDER_
#define _OSX_AU_DEBUG_RENDER_ 0
+#endif
#define check_error_and_throw(err,what,throw_str) \
if(err) { \
diff --git a/gr-audio/lib/osx/osx_impl.cc b/gr-audio/lib/osx/osx_impl.cc
index aa0320d18a..d18c24c786 100644
--- a/gr-audio/lib/osx/osx_impl.cc
+++ b/gr-audio/lib/osx/osx_impl.cc
@@ -33,10 +33,6 @@
#include <locale>
#include <stdexcept>
-namespace gr {
-namespace audio {
-namespace osx {
-
std::ostream&
operator<<
(std::ostream& s,
@@ -70,6 +66,10 @@ operator<<
return(s);
};
+namespace gr {
+namespace audio {
+namespace osx {
+
static UInt32
_get_num_channels
(AudioDeviceID ad_id,
diff --git a/gr-blocks/python/blocks/qa_file_source_sink.py b/gr-blocks/python/blocks/qa_file_source_sink.py
index 89841d3be6..da1a07b347 100644
--- a/gr-blocks/python/blocks/qa_file_source_sink.py
+++ b/gr-blocks/python/blocks/qa_file_source_sink.py
@@ -22,6 +22,7 @@
from gnuradio import gr, gr_unittest, blocks
import os
+import tempfile
class test_file_source_sink(gr_unittest.TestCase):
@@ -36,22 +37,21 @@ class test_file_source_sink(gr_unittest.TestCase):
src_data = range(1000)
expected_result = range(1000)
- filename = "tmp.32f"
- src = blocks.vector_source_f(src_data)
- snk = blocks.file_sink(gr.sizeof_float, filename)
- snk.set_unbuffered(True)
-
- src2 = blocks.file_source(gr.sizeof_float, filename)
snk2 = blocks.vector_sink_f()
- self.tb.connect(src, snk)
- self.tb.run()
+ with tempfile.NamedTemporaryFile() as temp:
+ src = blocks.vector_source_f(src_data)
+ snk = blocks.file_sink(gr.sizeof_float, temp.name)
+ snk.set_unbuffered(True)
+
+ src2 = blocks.file_source(gr.sizeof_float, temp.name)
- self.tb.disconnect(src, snk)
- self.tb.connect(src2, snk2)
- self.tb.run()
+ self.tb.connect(src, snk)
+ self.tb.run()
- os.remove(filename)
+ self.tb.disconnect(src, snk)
+ self.tb.connect(src2, snk2)
+ self.tb.run()
result_data = snk2.data()
self.assertFloatTuplesAlmostEqual(expected_result, result_data)
@@ -60,30 +60,29 @@ class test_file_source_sink(gr_unittest.TestCase):
src_data = range(1000)
expected_result = range(1000)
- filename = "tmp.32f"
- fhandle0 = open(filename, "wb")
- fd0 = fhandle0.fileno()
+ snk2 = blocks.vector_sink_f()
- src = blocks.vector_source_f(src_data)
- snk = blocks.file_descriptor_sink(gr.sizeof_float, fd0)
+ with tempfile.NamedTemporaryFile() as temp:
+ fhandle0 = open(temp.name, "wb")
+ fd0 = fhandle0.fileno()
- self.tb.connect(src, snk)
- self.tb.run()
- os.fsync(fd0)
- fhandle0.close()
+ src = blocks.vector_source_f(src_data)
+ snk = blocks.file_descriptor_sink(gr.sizeof_float, fd0)
- fhandle1 = open(filename, "rb")
- fd1 = fhandle1.fileno()
- src2 = blocks.file_descriptor_source(gr.sizeof_float, fd1, False)
- snk2 = blocks.vector_sink_f()
+ self.tb.connect(src, snk)
+ self.tb.run()
+ os.fsync(fd0)
+ fhandle0.close()
- self.tb.disconnect(src, snk)
- self.tb.connect(src2, snk2)
- self.tb.run()
- os.fsync(fd1)
- fhandle1.close()
+ fhandle1 = open(temp.name, "rb")
+ fd1 = fhandle1.fileno()
+ src2 = blocks.file_descriptor_source(gr.sizeof_float, fd1, False)
- os.remove(filename)
+ self.tb.disconnect(src, snk)
+ self.tb.connect(src2, snk2)
+ self.tb.run()
+ os.fsync(fd1)
+ fhandle1.close()
result_data = snk2.data()
self.assertFloatTuplesAlmostEqual(expected_result, result_data)
@@ -91,18 +90,16 @@ class test_file_source_sink(gr_unittest.TestCase):
def test_file_source_can_seek_after_open(self):
src_data = range(1000)
- filename = "tmp.32f"
- src = blocks.vector_source_f(src_data)
- snk = blocks.file_sink(gr.sizeof_float, filename)
- snk.set_unbuffered(True)
-
- self.tb.connect(src, snk)
- self.tb.run()
+ with tempfile.NamedTemporaryFile() as temp:
+ src = blocks.vector_source_f(src_data)
+ snk = blocks.file_sink(gr.sizeof_float, temp.name)
+ snk.set_unbuffered(True)
- source = blocks.file_source(gr.sizeof_float, filename)
- self.assertTrue(source.seek(0, os.SEEK_SET))
+ self.tb.connect(src, snk)
+ self.tb.run()
- os.remove(filename)
+ source = blocks.file_source(gr.sizeof_float, temp.name)
+ self.assertTrue(source.seek(0, os.SEEK_SET))
if __name__ == '__main__':
gr_unittest.run(test_file_source_sink, "test_file_source_sink.xml")
diff --git a/gr-digital/lib/additive_scrambler_bb_impl.cc b/gr-digital/lib/additive_scrambler_bb_impl.cc
index 58a2455aa5..d1112ee5f4 100644
--- a/gr-digital/lib/additive_scrambler_bb_impl.cc
+++ b/gr-digital/lib/additive_scrambler_bb_impl.cc
@@ -121,18 +121,35 @@ namespace gr {
unsigned char *out = (unsigned char *)output_items[0];
int reset_index = _get_next_reset_index(noutput_items);
- for(int i = 0; i < noutput_items; i++) {
- unsigned char scramble_byte = 0x00;
- for (int k = 0; k < d_bits_per_byte; k++) {
- scramble_byte ^= (d_lfsr.next_bit() << k);
- }
- out[i] = in[i] ^ scramble_byte;
- d_bytes++;
- if (i == reset_index) {
- d_lfsr.reset();
- d_bytes = 0;
- reset_index = _get_next_reset_index(noutput_items, reset_index);
- }
+ if (d_count >= 0) {
+ for(int i = 0; i < noutput_items; i++) {
+ unsigned char scramble_byte = 0x00;
+ for (int k = 0; k < d_bits_per_byte; k++) {
+ scramble_byte ^= (d_lfsr.next_bit() << k);
+ }
+ out[i] = in[i] ^ scramble_byte;
+ d_bytes++;
+ if (i == reset_index) {
+ d_lfsr.reset();
+ d_bytes = 0;
+ reset_index = _get_next_reset_index(noutput_items, reset_index);
+ }
+ }
+ } else {
+ for(int i = 0; i < noutput_items; i++) {
+ // Reset should occur at/before the item associated with the tag.
+ if (i == reset_index) {
+ d_lfsr.reset();
+ d_bytes = 0;
+ reset_index = _get_next_reset_index(noutput_items, reset_index);
+ }
+ unsigned char scramble_byte = 0x00;
+ for (int k = 0; k < d_bits_per_byte; k++) {
+ scramble_byte ^= (d_lfsr.next_bit() << k);
+ }
+ out[i] = in[i] ^ scramble_byte;
+ d_bytes++;
+ }
}
return noutput_items;
diff --git a/gr-digital/python/digital/qa_scrambler.py b/gr-digital/python/digital/qa_scrambler.py
index 4d35879b1f..522b23245f 100755
--- a/gr-digital/python/digital/qa_scrambler.py
+++ b/gr-digital/python/digital/qa_scrambler.py
@@ -23,6 +23,17 @@
from gnuradio import gr, gr_unittest, digital, blocks
import pmt
+# See gr-digital/lib/additive_scrambler_bb_impl.cc for reference.
+def additive_scramble_lfsr(mask, seed, reglen, bpb, data):
+ l = digital.lfsr(mask, seed, reglen)
+ out = []
+ for d in data:
+ scramble_word = 0
+ for i in xrange(0,bpb):
+ scramble_word ^= l.next_bit() << i
+ out.append(d ^ scramble_word)
+ return tuple(out)
+
class test_scrambler(gr_unittest.TestCase):
def setUp(self):
@@ -98,5 +109,25 @@ class test_scrambler(gr_unittest.TestCase):
self.tb.run()
self.assertEqual(src_data, dst.data())
+ def test_additive_scrambler_tags_oneway(self):
+ src_data = range(0, 10)
+ reset_tag_key = 'reset_lfsr'
+ reset_tag1 = gr.tag_t()
+ reset_tag1.key = pmt.string_to_symbol(reset_tag_key)
+ reset_tag1.offset = 0
+ reset_tag2 = gr.tag_t()
+ reset_tag2.key = pmt.string_to_symbol(reset_tag_key)
+ reset_tag2.offset = 10
+ reset_tag3 = gr.tag_t()
+ reset_tag3.key = pmt.string_to_symbol(reset_tag_key)
+ reset_tag3.offset = 20
+ src = blocks.vector_source_b(src_data * 3, False, 1, (reset_tag1, reset_tag2, reset_tag3))
+ scrambler = digital.additive_scrambler_bb(0x8a, 0x7f, 7, 0, 8, reset_tag_key)
+ dst = blocks.vector_sink_b()
+ self.tb.connect(src, scrambler, dst)
+ self.tb.run()
+ expected_data = additive_scramble_lfsr(0x8a, 0x7f, 7, 8, src_data)
+ self.assertEqual(expected_data * 3, dst.data())
+
if __name__ == '__main__':
gr_unittest.run(test_scrambler, "test_scrambler.xml")
diff --git a/gr-qtgui/grc/qtgui_label.xml b/gr-qtgui/grc/qtgui_label.xml
index 0d844a1ab4..d67f3d7500 100644
--- a/gr-qtgui/grc/qtgui_label.xml
+++ b/gr-qtgui/grc/qtgui_label.xml
@@ -21,7 +21,7 @@ $win = Qt.QToolBar(self)
if $(formatter):
self._$(id)_formatter = $formatter
else:
- self._$(id)_formatter = lambda x: x
+ self._$(id)_formatter = lambda x: $(type.str)(x)
$(win).addWidget(Qt.QLabel($label+": "))
self._$(id)_label = Qt.QLabel(str(self._$(id)_formatter(self.$id)))
@@ -30,7 +30,7 @@ $(gui_hint()($win))
</make>
<callback>self.set_$(id)(self._$(id)_formatter($value))</callback>
- <callback>Qt.QMetaObject.invokeMethod(self._$(id)_label, "setText", Qt.Q_ARG("QString", $(type.str)($id)))</callback>
+ <callback>Qt.QMetaObject.invokeMethod(self._$(id)_label, "setText", Qt.Q_ARG("QString", $id))</callback>
<param>
<name>Label</name>