diff options
-rw-r--r-- | CMakeLists.txt | 7 | ||||
-rw-r--r-- | cmake/Modules/CodeCoverage.cmake | 197 | ||||
-rw-r--r-- | cmake/Modules/GrBuildTypes.cmake | 33 | ||||
-rw-r--r-- | cmake/Modules/GrTest.cmake | 1 | ||||
-rw-r--r-- | config.h.in | 6 | ||||
-rw-r--r-- | gnuradio-runtime/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gnuradio-runtime/gnuradio-runtime.pc.in | 2 | ||||
-rw-r--r-- | gnuradio-runtime/include/gnuradio/logger.h.in | 51 | ||||
-rw-r--r-- | gr-audio/include/gnuradio/audio/osx_impl.h | 14 | ||||
-rw-r--r-- | gr-audio/lib/osx/osx_common.h | 5 | ||||
-rw-r--r-- | gr-audio/lib/osx/osx_impl.cc | 8 | ||||
-rw-r--r-- | gr-blocks/python/blocks/qa_file_source_sink.py | 79 | ||||
-rw-r--r-- | gr-digital/lib/additive_scrambler_bb_impl.cc | 41 | ||||
-rwxr-xr-x | gr-digital/python/digital/qa_scrambler.py | 31 | ||||
-rw-r--r-- | gr-qtgui/grc/qtgui_label.xml | 4 |
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> |