diff options
-rw-r--r-- | gr-utils/python/utils/CMakeLists.txt | 1 | ||||
-rwxr-xr-x | gr-utils/python/utils/grcc | 89 | ||||
-rwxr-xr-x | grc/compiler.py | 76 | ||||
-rw-r--r-- | grc/core/Config.py | 4 | ||||
-rw-r--r-- | grc/core/FlowGraph.py | 18 | ||||
-rw-r--r-- | grc/core/Platform.py | 23 | ||||
-rw-r--r-- | grc/core/utils/shlex.py | 47 | ||||
-rw-r--r-- | grc/gui/Executor.py | 41 | ||||
-rw-r--r-- | grc/scripts/CMakeLists.txt | 2 | ||||
-rwxr-xr-x | grc/scripts/gnuradio-companion | 34 | ||||
-rwxr-xr-x | grc/scripts/grcc | 64 | ||||
-rw-r--r-- | grc/tests/resources/test_compiler.grc | 253 | ||||
-rw-r--r-- | grc/tests/test_compiler.py | 38 |
13 files changed, 532 insertions, 158 deletions
diff --git a/gr-utils/python/utils/CMakeLists.txt b/gr-utils/python/utils/CMakeLists.txt index 46a21c1508..3ce335c4ed 100644 --- a/gr-utils/python/utils/CMakeLists.txt +++ b/gr-utils/python/utils/CMakeLists.txt @@ -49,6 +49,5 @@ GR_PYTHON_INSTALL( gr_plot_short gr_plot_qt gr_read_file_metadata - grcc DESTINATION ${GR_RUNTIME_DIR} ) diff --git a/gr-utils/python/utils/grcc b/gr-utils/python/utils/grcc deleted file mode 100755 index e93802f051..0000000000 --- a/gr-utils/python/utils/grcc +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2012 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# 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. -# - -import os -import sys -from argparse import ArgumentParser -import warnings -warnings.simplefilter('ignore') - -from gnuradio import gr - -try: - from grc.core.Platform import Platform -except ImportError: - from gnuradio.grc.core.Platform import Platform - - -class GRCC: - def __init__(self, grcfile, out_dir): - self.out_dir = out_dir - self.platform = Platform( - prefs_file=gr.prefs(), - version=gr.version(), - version_parts=(gr.major_version(), gr.api_version(), gr.minor_version()) - ) - data = self.platform.parse_flow_graph(grcfile) - - self.fg = self.platform.get_new_flow_graph() - self.fg.import_data(data) - self.fg.grc_file_path = os.path.abspath(grcfile) - self.fg.validate() - - if not self.fg.is_valid(): - raise StandardError("\n\n".join( - ["Validation failed:"] + self.fg.get_error_messages() - )) - - self.gen = self.platform.Generator(self.fg, out_dir) - self.gen.write() - - def exec_program(self): - progname = self.fg.get_option('id') - os.system("{0}/{1}.py".format(self.out_dir, progname)) - - -def main(): - description = "Compiles a GRC file (.grc) into a GNU Radio Python program. The program is stored in ~/.grc_gnuradio by default, but this location can be changed with the -d option." - - parser = ArgumentParser(description=description) - parser.add_argument("-d", "--directory", - default='{0}/.grc_gnuradio/'.format(os.environ["HOME"]), - help="Specify the directory to output the compile program [default=%(default)s]") - parser.add_argument("-e", "--execute", action="store_true", default=False, - help="Run the program after compiling [default=%(default)s]") - parser.add_argument('grc_file', metavar="GRC_FILE", help=".grc file to compile") - args = parser.parse_args() - - try: - g = GRCC(args.grc_file, args.directory + "/") - except Exception as e: - sys.stderr.write(str(e) + "\n") - sys.stderr.write("Error during file compilation.\n") - sys.exit(1) - - if args.execute: - g.exec_program() - - -if __name__ == "__main__": - main() diff --git a/grc/compiler.py b/grc/compiler.py new file mode 100755 index 0000000000..0cda0d946d --- /dev/null +++ b/grc/compiler.py @@ -0,0 +1,76 @@ +# Copyright 2016 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# 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. + +from __future__ import print_function, absolute_import + +import argparse +import os +import subprocess + +from gnuradio import gr + +from .core import Messages +from .core.Platform import Platform + + +def argument_parser(): + parser = argparse.ArgumentParser(description=( + "Compile a GRC file (.grc) into a GNU Radio Python program and run it." + )) + parser.add_argument("-o", "--output", metavar='DIR', default='.', + help="Output directory for compiled program [default=%(default)s]") + parser.add_argument("-u", "--user-lib-dir", action='store_true', default=False, + help="Output to default hier_block library (overwrites -o)") + parser.add_argument("-r", "--run", action="store_true", default=False, + help="Run the program after compiling [default=%(default)s]") + parser.add_argument(metavar="GRC_FILE", dest='grc_files', nargs='+', + help=".grc file to compile") + return parser + + +def main(args=None): + args = args or argument_parser().parse_args() + + platform = Platform( + name='GNU Radio Companion Compiler', + prefs_file=gr.prefs(), + version=gr.version(), + version_parts=(gr.major_version(), gr.api_version(), gr.minor_version()) + ) + out_dir = args.output if not args.user_lib_dir else platform.config.hier_block_lib_dir + if os.path.exists(out_dir): + pass # all is well + elif args.save_to_lib: + os.mkdir(out_dir) # create missing hier_block lib directory + else: + exit('Error: Invalid output directory') + + Messages.send_init(platform) + flow_graph = file_path = None + for grc_file in args.grc_files: + os.path.exists(grc_file) or exit('Error: missing ' + grc_file) + Messages.send('\n') + + flow_graph, file_path = platform.load_and_generate_flow_graph( + os.path.abspath(grc_file), os.path.abspath(out_dir)) + if not file_path: + exit('Compilation error') + if file_path and args.run: + run_command_args = flow_graph.get_run_command(file_path, split=True) + subprocess.call(run_command_args) diff --git a/grc/core/Config.py b/grc/core/Config.py index 78ff344998..744ad06ba9 100644 --- a/grc/core/Config.py +++ b/grc/core/Config.py @@ -32,10 +32,12 @@ class Config(object): hier_block_lib_dir = os.environ.get('GRC_HIER_PATH', Constants.DEFAULT_HIER_BLOCK_LIB_DIR) - def __init__(self, prefs_file, version, version_parts=None): + def __init__(self, prefs_file, version, version_parts=None, name=None): self.prefs = prefs_file self.version = version self.version_parts = version_parts or version[1:].split('-', 1)[0].split('.')[:3] + if name: + self.name = name @property def block_paths(self): diff --git a/grc/core/FlowGraph.py b/grc/core/FlowGraph.py index 949eecaa71..ecae11cf1a 100644 --- a/grc/core/FlowGraph.py +++ b/grc/core/FlowGraph.py @@ -16,16 +16,16 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA import imp -import time from itertools import ifilter, chain from operator import methodcaller, attrgetter - import re +import sys +import time from . import Messages from .Constants import FLOW_GRAPH_FILE_FORMAT_VERSION from .Element import Element -from .utils import odict, expr_utils +from .utils import odict, expr_utils, shlex _parameter_matcher = re.compile('^(parameter)$') _monitors_searcher = re.compile('(ctrlport_monitor)') @@ -186,6 +186,16 @@ class FlowGraph(Element): """ return self._options_block.get_param(key).get_evaluated() + def get_run_command(self, file_path, split=False): + run_command = self.get_option('run_command') + try: + run_command = run_command.format( + python=shlex.quote(sys.executable), + filename=shlex.quote(file_path)) + return shlex.split(run_command) if split else run_command + except Exception as e: + raise ValueError("Can't parse run command {!r}: {}".format(run_command, e)) + ############################################## # Access Elements ############################################## @@ -410,7 +420,7 @@ class FlowGraph(Element): cwd=self.grc_file_path ) if file_path: # grc file found. load and get block - self.platform.load_and_generate_flow_graph(file_path) + self.platform.load_and_generate_flow_graph(file_path, hier_only=True) block = self.new_block(key) # can be None if not block: # looks like this block key cannot be found diff --git a/grc/core/Platform.py b/grc/core/Platform.py index 0dc6eb055a..b73dade2e8 100644 --- a/grc/core/Platform.py +++ b/grc/core/Platform.py @@ -93,42 +93,43 @@ class Platform(Element): if os.path.exists(os.path.normpath(file_path)): return file_path - def load_and_generate_flow_graph(self, file_path): + def load_and_generate_flow_graph(self, file_path, out_path=None, hier_only=False): """Loads a flow graph from file and generates it""" Messages.set_indent(len(self._auto_hier_block_generate_chain)) - Messages.send('>>> Loading: %r\n' % file_path) + Messages.send('>>> Loading: {}\n'.format(file_path)) if file_path in self._auto_hier_block_generate_chain: Messages.send(' >>> Warning: cyclic hier_block dependency\n') - return False + return None, None self._auto_hier_block_generate_chain.add(file_path) try: flow_graph = self.get_new_flow_graph() flow_graph.grc_file_path = file_path - # Other, nested higiter_blocks might be auto-loaded here + # Other, nested hier_blocks might be auto-loaded here flow_graph.import_data(self.parse_flow_graph(file_path)) flow_graph.rewrite() flow_graph.validate() if not flow_graph.is_valid(): raise Exception('Flowgraph invalid') - if not flow_graph.get_option('generate_options').startswith('hb'): + if hier_only and not flow_graph.get_option('generate_options').startswith('hb'): raise Exception('Not a hier block') except Exception as e: Messages.send('>>> Load Error: {}: {}\n'.format(file_path, str(e))) - return False + return None, None finally: self._auto_hier_block_generate_chain.discard(file_path) Messages.set_indent(len(self._auto_hier_block_generate_chain)) try: - Messages.send('>>> Generating: {}\n'.format(file_path)) - generator = self.Generator(flow_graph, file_path) + generator = self.Generator(flow_graph, out_path or file_path) + Messages.send('>>> Generating: {}\n'.format(generator.file_path)) generator.write() except Exception as e: Messages.send('>>> Generate Error: {}: {}\n'.format(file_path, str(e))) - return False + return None, None - self.load_block_xml(generator.get_file_path_xml()) - return True + if flow_graph.get_option('generate_options').startswith('hb'): + self.load_block_xml(generator.get_file_path_xml()) + return flow_graph, generator.file_path def build_block_library(self): """load the blocks and block tree from the search paths""" diff --git a/grc/core/utils/shlex.py b/grc/core/utils/shlex.py new file mode 100644 index 0000000000..6b620fa396 --- /dev/null +++ b/grc/core/utils/shlex.py @@ -0,0 +1,47 @@ +# Copyright 2016 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# 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. + +from __future__ import absolute_import + +import re +import shlex + +# back port from python3 + +_find_unsafe = re.compile(r'[^\w@%+=:,./-]').search + + +def _shlex_quote(s): + """Return a shell-escaped version of the string *s*.""" + if not s: + return "''" + if _find_unsafe(s) is None: + return s + + # use single quotes, and put single quotes into double quotes + # the string $'b is then quoted as '$'"'"'b' + return "'" + s.replace("'", "'\"'\"'") + "'" + + +if not hasattr(shlex, 'quote'): + quote = _shlex_quote +else: + quote = shlex.quote + +split = shlex.split diff --git a/grc/gui/Executor.py b/grc/gui/Executor.py index bf9eecb9a8..f5a75ab55b 100644 --- a/grc/gui/Executor.py +++ b/grc/gui/Executor.py @@ -15,15 +15,14 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -import gobject -import os -import threading -import shlex import subprocess -import sys -import re +import threading from distutils.spawn import find_executable +import gobject +import os + +from ..core.utils import shlex from ..core import Messages @@ -40,6 +39,7 @@ class ExecFlowGraphThread(threading.Thread): threading.Thread.__init__(self) self.page = flow_graph_page # store page and dont use main window calls in run + self.flow_graph = self.page.get_flow_graph() self.xterm_executable = xterm_executable self.update_callback = callback @@ -56,16 +56,9 @@ class ExecFlowGraphThread(threading.Thread): """ Execute this python flow graph. """ - run_command = self.page.get_flow_graph().get_option('run_command') generator = self.page.get_generator() - - try: - run_command = run_command.format( - python=shlex_quote(sys.executable), - filename=shlex_quote(generator.file_path)) - run_command_args = shlex.split(run_command) - except Exception as e: - raise ValueError("Can't parse run command {!r}: {}".format(run_command, e)) + run_command = self.flow_graph.get_run_command(generator.file_path) + run_command_args = shlex.split(run_command) # When in no gui mode on linux, use a graphical terminal (looks nice) xterm_executable = find_executable(self.xterm_executable) @@ -101,21 +94,3 @@ class ExecFlowGraphThread(threading.Thread): Messages.send_end_exec(self.process.returncode) self.page.set_proc(None) self.update_callback() - - -########################################################### -# back-port from python3 -########################################################### -_find_unsafe = re.compile(r'[^\w@%+=:,./-]').search - - -def shlex_quote(s): - """Return a shell-escaped version of the string *s*.""" - if not s: - return "''" - if _find_unsafe(s) is None: - return s - - # use single quotes, and put single quotes into double quotes - # the string $'b is then quoted as '$'"'"'b' - return "'" + s.replace("'", "'\"'\"'") + "'" diff --git a/grc/scripts/CMakeLists.txt b/grc/scripts/CMakeLists.txt index 9751952118..20366e0212 100644 --- a/grc/scripts/CMakeLists.txt +++ b/grc/scripts/CMakeLists.txt @@ -19,7 +19,7 @@ ######################################################################## GR_PYTHON_INSTALL( - PROGRAMS gnuradio-companion + PROGRAMS gnuradio-companion grcc DESTINATION ${GR_RUNTIME_DIR} ) diff --git a/grc/scripts/gnuradio-companion b/grc/scripts/gnuradio-companion index 34bb0bf110..bacbbe2334 100755 --- a/grc/scripts/gnuradio-companion +++ b/grc/scripts/gnuradio-companion @@ -1,22 +1,20 @@ #!/usr/bin/env python -""" -Copyright 2016 Free Software Foundation, Inc. -This file is part of GNU Radio - -GNU Radio Companion 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 2 -of the License, or (at your option) any later version. - -GNU Radio Companion 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 -""" +# Copyright 2016 Free Software Foundation, Inc. +# This file is part of GNU Radio +# +# GNU Radio Companion 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 2 +# of the License, or (at your option) any later version. +# +# GNU Radio Companion 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 import os import sys diff --git a/grc/scripts/grcc b/grc/scripts/grcc new file mode 100755 index 0000000000..c3a53a91a6 --- /dev/null +++ b/grc/scripts/grcc @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# Copyright 2016 Free Software Foundation, Inc. +# This file is part of GNU Radio +# +# GNU Radio Companion 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 2 +# of the License, or (at your option) any later version. +# +# GNU Radio Companion 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 + +import os +import sys + + +GR_IMPORT_ERROR_MESSAGE = """\ +Cannot import gnuradio. + +Is the model path environment variable set correctly? + All OS: PYTHONPATH + +Is the library path environment variable set correctly? + Linux: LD_LIBRARY_PATH + Windows: PATH + MacOSX: DYLD_LIBRARY_PATH +""" + + +def die(error, message): + msg = "{0}\n\n({1})".format(message, error) + exit(type(error).__name__ + '\n\n' + msg) + + +def check_gnuradio_import(): + try: + from gnuradio import gr + except ImportError as err: + die(err, GR_IMPORT_ERROR_MESSAGE) + + +def run_main(): + script_path = os.path.dirname(os.path.abspath(__file__)) + source_tree_subpath = "/grc/scripts" + + if not script_path.endswith(source_tree_subpath): + # run the installed version + from gnuradio.grc.compiler import main + else: + print("Running from source tree") + sys.path.insert(1, script_path[:-len(source_tree_subpath)]) + from grc.compiler import main + exit(main()) + + +if __name__ == '__main__': + check_gnuradio_import() + run_main() diff --git a/grc/tests/resources/test_compiler.grc b/grc/tests/resources/test_compiler.grc new file mode 100644 index 0000000000..cc56acedca --- /dev/null +++ b/grc/tests/resources/test_compiler.grc @@ -0,0 +1,253 @@ +<?xml version='1.0' encoding='utf-8'?> +<?grc format='1' created='3.7.11'?> +<flow_graph> + <timestamp>Thu Sep 15 12:56:40 2016</timestamp> + <block> + <key>options</key> + <param> + <key>author</key> + <value></value> + </param> + <param> + <key>window_size</key> + <value></value> + </param> + <param> + <key>category</key> + <value>[GRC Hier Blocks]</value> + </param> + <param> + <key>comment</key> + <value></value> + </param> + <param> + <key>description</key> + <value></value> + </param> + <param> + <key>_enabled</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(8, 8)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + <param> + <key>generate_options</key> + <value>no_gui</value> + </param> + <param> + <key>hier_block_src_path</key> + <value>.:</value> + </param> + <param> + <key>id</key> + <value>top_block</value> + </param> + <param> + <key>max_nouts</key> + <value>0</value> + </param> + <param> + <key>qt_qss_theme</key> + <value></value> + </param> + <param> + <key>realtime_scheduling</key> + <value></value> + </param> + <param> + <key>run_command</key> + <value>{python} -u {filename}</value> + </param> + <param> + <key>run_options</key> + <value>run</value> + </param> + <param> + <key>run</key> + <value>True</value> + </param> + <param> + <key>thread_safe_setters</key> + <value></value> + </param> + <param> + <key>title</key> + <value></value> + </param> + </block> + <block> + <key>blocks_add_const_vxx</key> + <param> + <key>alias</key> + <value></value> + </param> + <param> + <key>comment</key> + <value></value> + </param> + <param> + <key>const</key> + <value>1</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(360, 28)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + <param> + <key>id</key> + <value>blocks_add_const_vxx_0</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + </block> + <block> + <key>blocks_null_sink</key> + <param> + <key>alias</key> + <value></value> + </param> + <param> + <key>bus_conns</key> + <value>[[0,],]</value> + </param> + <param> + <key>comment</key> + <value></value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(504, 32)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + <param> + <key>id</key> + <value>blocks_null_sink_0</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>num_inputs</key> + <value>1</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + </block> + <block> + <key>blocks_vector_source_x</key> + <param> + <key>alias</key> + <value></value> + </param> + <param> + <key>comment</key> + <value></value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(208, 12)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + <param> + <key>id</key> + <value>blocks_vector_source_x_0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>repeat</key> + <value>False</value> + </param> + <param> + <key>tags</key> + <value>[]</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>vector</key> + <value>(0, 0, 0)</value> + </param> + </block> + <connection> + <source_block_id>blocks_add_const_vxx_0</source_block_id> + <sink_block_id>blocks_null_sink_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>blocks_vector_source_x_0</source_block_id> + <sink_block_id>blocks_add_const_vxx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> +</flow_graph> diff --git a/grc/tests/test_compiler.py b/grc/tests/test_compiler.py new file mode 100644 index 0000000000..27b5670871 --- /dev/null +++ b/grc/tests/test_compiler.py @@ -0,0 +1,38 @@ +# Copyright 2016 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# 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. + +from argparse import Namespace +from os import path +import tempfile + +from grc.compiler import main + + +def test_compiler(capsys): + args = Namespace( + output=tempfile.gettempdir(), + user_lib_dir=False, + grc_files=[path.join(path.dirname(__file__), 'resources', 'test_compiler.grc')], + run=True + ) + + main(args) + + out, err = capsys.readouterr() + assert not err |