summaryrefslogtreecommitdiff
path: root/grc/model/Platform.py
diff options
context:
space:
mode:
Diffstat (limited to 'grc/model/Platform.py')
-rw-r--r--grc/model/Platform.py155
1 files changed, 155 insertions, 0 deletions
diff --git a/grc/model/Platform.py b/grc/model/Platform.py
new file mode 100644
index 0000000000..e6b17fe3f7
--- /dev/null
+++ b/grc/model/Platform.py
@@ -0,0 +1,155 @@
+"""
+Copyright 2008-2015 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
+from gnuradio import gr
+
+from .base.Platform import Platform as _Platform
+
+from . import extract_docs
+from .Constants import (
+ HIER_BLOCKS_LIB_DIR, BLOCK_DTD, DEFAULT_FLOW_GRAPH, BLOCKS_DIRS,
+ PREFS_FILE, CORE_TYPES, PREFS_FILE_OLD,
+)
+from .Generator import Generator
+from .. gui import Messages
+
+
+class Platform(_Platform):
+ def __init__(self):
+ """
+ Make a platform for gnuradio.
+ """
+ # ensure hier and conf directories
+ if not os.path.exists(HIER_BLOCKS_LIB_DIR):
+ os.mkdir(HIER_BLOCKS_LIB_DIR)
+ if not os.path.exists(os.path.dirname(PREFS_FILE)):
+ os.mkdir(os.path.dirname(PREFS_FILE))
+
+ self.block_docstrings = {}
+ self.block_docstrings_loaded_callback = lambda: None # dummy to be replaced by BlockTreeWindow
+
+ self._docstring_extractor = extract_docs.SubprocessLoader(
+ callback_query_result=self._save_docstring_extraction_result,
+ callback_finished=lambda: self.block_docstrings_loaded_callback()
+ )
+
+ # init
+ _Platform.__init__(
+ self,
+ name='GNU Radio Companion',
+ version=(gr.version(), gr.major_version(), gr.api_version(), gr.minor_version()),
+ key='grc',
+ license=__doc__.strip(),
+ website='http://gnuradio.org/',
+ block_paths=BLOCKS_DIRS,
+ block_dtd=BLOCK_DTD,
+ default_flow_graph=DEFAULT_FLOW_GRAPH,
+ generator=Generator,
+ colors=[(name, color) for name, key, sizeof, color in CORE_TYPES],
+ )
+
+ self._auto_hier_block_generate_chain = set()
+
+ def _save_docstring_extraction_result(self, key, docstrings):
+ docs = {}
+ for match, docstring in docstrings.iteritems():
+ if not docstring or match.endswith('_sptr'):
+ continue
+ docstring = docstring.replace('\n\n', '\n').strip()
+ docs[match] = docstring
+ self.block_docstrings[key] = docs
+
+ @staticmethod
+ def _move_old_pref_file():
+ if PREFS_FILE == PREFS_FILE_OLD:
+ return # prefs file overridden with env var
+ if os.path.exists(PREFS_FILE_OLD) and not os.path.exists(PREFS_FILE):
+ try:
+ import shutil
+ shutil.move(PREFS_FILE_OLD, PREFS_FILE)
+ except Exception as e:
+ print >> sys.stderr, e
+
+ def load_blocks(self):
+ self._docstring_extractor.start()
+ _Platform.load_blocks(self)
+ self._docstring_extractor.finish()
+ # self._docstring_extractor.wait()
+
+ def load_block_xml(self, xml_file):
+ block = _Platform.load_block_xml(self, xml_file)
+ self._docstring_extractor.query(
+ block.get_key(),
+ block.get_imports(raw=True),
+ block.get_make(raw=True)
+ )
+ return block
+
+ @staticmethod
+ def find_file_in_paths(filename, paths, cwd):
+ """Checks the provided paths relative to cwd for a certain filename"""
+ if not os.path.isdir(cwd):
+ cwd = os.path.dirname(cwd)
+ if isinstance(paths, str):
+ paths = (p for p in paths.split(':') if p)
+
+ for path in paths:
+ path = os.path.expanduser(path)
+ if not os.path.isabs(path):
+ path = os.path.normpath(os.path.join(cwd, path))
+ file_path = os.path.join(path, filename)
+ if os.path.exists(os.path.normpath(file_path)):
+ return file_path
+
+ def load_and_generate_flow_graph(self, file_path):
+ """Loads a flowgraph from file and generates it"""
+ Messages.set_indent(len(self._auto_hier_block_generate_chain))
+ Messages.send('>>> Loading: %r\n' % file_path)
+ if file_path in self._auto_hier_block_generate_chain:
+ Messages.send(' >>> Warning: cyclic hier_block dependency\n')
+ return False
+ 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
+ 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')
+ except Exception as e:
+ Messages.send('>>> Load Error: %r: %s\n' % (file_path, str(e)))
+ return False
+ finally:
+ self._auto_hier_block_generate_chain.discard(file_path)
+ Messages.set_indent(len(self._auto_hier_block_generate_chain))
+
+ try:
+ Messages.send('>>> Generating: %r\n' % file_path)
+ generator = self.get_generator()(flow_graph, file_path)
+ generator.write()
+ except Exception as e:
+ Messages.send('>>> Generate Error: %r: %s\n' % (file_path, str(e)))
+ return False
+
+ self.load_block_xml(generator.get_file_path_xml())
+ return True