summaryrefslogtreecommitdiff
path: root/grc/src/platforms/python
diff options
context:
space:
mode:
Diffstat (limited to 'grc/src/platforms/python')
-rw-r--r--grc/src/platforms/python/Block.py152
-rw-r--r--grc/src/platforms/python/Connection.py34
-rw-r--r--grc/src/platforms/python/Constants.py.in54
-rw-r--r--grc/src/platforms/python/FlowGraph.py162
-rw-r--r--grc/src/platforms/python/Generator.py142
-rw-r--r--grc/src/platforms/python/Makefile.am48
-rw-r--r--grc/src/platforms/python/Param.py402
-rw-r--r--grc/src/platforms/python/Platform.py69
-rw-r--r--grc/src/platforms/python/Port.py129
-rw-r--r--grc/src/platforms/python/__init__.py1
-rw-r--r--grc/src/platforms/python/utils/Makefile.am30
-rw-r--r--grc/src/platforms/python/utils/__init__.py1
-rw-r--r--grc/src/platforms/python/utils/convert_hier.py78
-rw-r--r--grc/src/platforms/python/utils/expr_utils.py137
-rw-r--r--grc/src/platforms/python/utils/extract_docs.py92
15 files changed, 0 insertions, 1531 deletions
diff --git a/grc/src/platforms/python/Block.py b/grc/src/platforms/python/Block.py
deleted file mode 100644
index 341e5fdc3..000000000
--- a/grc/src/platforms/python/Block.py
+++ /dev/null
@@ -1,152 +0,0 @@
-"""
-Copyright 2008 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
-"""
-
-from .. base.Block import Block as _Block
-from utils import extract_docs
-
-class Block(_Block):
-
- ##for make source to keep track of indexes
- _source_count = 0
- ##for make sink to keep track of indexes
- _sink_count = 0
-
- def __init__(self, flow_graph, n):
- """
- Make a new block from nested data.
- @param flow graph the parent element
- @param n the nested odict
- @return block a new block
- """
- #grab the data
- doc = n.find('doc') or ''
- imports = map(lambda i: i.strip(), n.findall('import'))
- make = n.find('make')
- checks = n.findall('check')
- callbacks = n.findall('callback')
- #build the block
- _Block.__init__(
- self,
- flow_graph=flow_graph,
- n=n,
- )
- self._doc = doc
- self._imports = imports
- self._make = make
- self._callbacks = callbacks
- self._checks = checks
-
- def validate(self):
- """
- Validate this block.
- Call the base class validate.
- Evaluate the checks: each check must evaluate to True.
- Adjust the nports.
- """
- _Block.validate(self)
- #evaluate the checks
- for check in self._checks:
- check_res = self.resolve_dependencies(check)
- try:
- check_eval = self.get_parent().evaluate(check_res)
- try: assert check_eval
- except AssertionError: self._add_error_message('Check "%s" failed.'%check)
- except: self._add_error_message('Check "%s" did not evaluate.'%check)
- #adjust nports
- for ports, Port in (
- (self._sources, self.get_parent().get_parent().Source),
- (self._sinks, self.get_parent().get_parent().Sink),
- ):
- #how many ports?
- num_ports = len(ports)
- #do nothing for 0 ports
- if not num_ports: continue
- #get the nports setting
- port0 = ports[str(0)]
- nports = port0.get_nports()
- #do nothing for no nports
- if not nports: continue
- #do nothing if nports is already num ports
- if nports == num_ports: continue
- #remove excess ports and connections
- if nports < num_ports:
- #remove the connections
- for key in map(str, range(nports, num_ports)):
- port = ports[key]
- for connection in port.get_connections():
- self.get_parent().remove_element(connection)
- #remove the ports
- for key in map(str, range(nports, num_ports)): ports.pop(key)
- continue
- #add more ports
- if nports > num_ports:
- for key in map(str, range(num_ports, nports)):
- n = port0._n
- n['key'] = key
- port = Port(self, n)
- ports[key] = port
- continue
-
- def port_controller_modify(self, direction):
- """
- Change the port controller.
- @param direction +1 or -1
- @return true for change
- """
- changed = False
- #concat the nports string from the private nports settings of both port0
- nports_str = \
- (self.get_sinks() and self.get_sinks()[0]._nports or '') + \
- (self.get_sources() and self.get_sources()[0]._nports or '')
- #modify all params whose keys appear in the nports string
- for param in self.get_params():
- if param.is_enum() or param.get_key() not in nports_str: continue
- #try to increment the port controller by direction
- try:
- value = param.evaluate()
- value = value + direction
- assert 0 < value
- param.set_value(value)
- changed = True
- except: pass
- return changed
-
- def get_doc(self):
- doc = self._doc.strip('\n').replace('\\\n', '')
- #merge custom doc with doxygen docs
- return '\n'.join([doc, extract_docs.extract(self.get_key())]).strip('\n')
-
- def get_imports(self):
- """
- Resolve all import statements.
- Split each import statement at newlines.
- Combine all import statments into a list.
- Filter empty imports.
- @return a list of import statements
- """
- return filter(lambda i: i, sum(map(lambda i: self.resolve_dependencies(i).split('\n'), self._imports), []))
-
- def get_make(self): return self.resolve_dependencies(self._make)
-
- def get_callbacks(self):
- """
- Get a list of function callbacks for this block.
- @return a list of strings
- """
- return map(lambda c: self.get_id() + '.' + self.resolve_dependencies(c), self._callbacks)
diff --git a/grc/src/platforms/python/Connection.py b/grc/src/platforms/python/Connection.py
deleted file mode 100644
index f742ff63d..000000000
--- a/grc/src/platforms/python/Connection.py
+++ /dev/null
@@ -1,34 +0,0 @@
-"""
-Copyright 2008 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
-"""
-
-from .. base.Connection import Connection as _Connection
-
-class Connection(_Connection):
-
- def validate(self):
- """
- Validate the connections.
- The ports must match in type and vector length.
- """
- _Connection.validate(self) #checks type
- #check vector length
- source_vlen = self.get_source().get_vlen()
- sink_vlen = self.get_sink().get_vlen()
- try: assert(source_vlen == sink_vlen)
- except AssertionError: self._add_error_message('Source vector length "%s" does not match sink vector length "%s".'%(source_vlen, sink_vlen))
diff --git a/grc/src/platforms/python/Constants.py.in b/grc/src/platforms/python/Constants.py.in
deleted file mode 100644
index 4a43147fa..000000000
--- a/grc/src/platforms/python/Constants.py.in
+++ /dev/null
@@ -1,54 +0,0 @@
-"""
-Copyright 2008 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
-import stat
-from .. base.Constants import PKG_DIR
-
-PYEXEC = '@PYTHONW@'
-
-#setup paths
-DOCS_DIR = os.path.join(os.environ.get('GR_DOCDIR', '@docdir@'), 'xml')
-DATA_DIR = os.path.join(PKG_DIR, '@reldatadir@')
-BLOCKS_DIR = os.path.join(PKG_DIR, '@relblocksdir@')
-HIER_BLOCKS_LIB_DIR = os.path.join(os.path.expanduser('~'), '.grc_gnuradio')
-
-#file creation modes
-TOP_BLOCK_FILE_MODE = stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP | stat.S_IROTH
-HIER_BLOCK_FILE_MODE = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IROTH
-
-#data files
-FLOW_GRAPH_TEMPLATE = os.path.join(DATA_DIR, 'flow_graph.tmpl')
-BLOCK_DTD = os.path.join(DATA_DIR, 'block.dtd')
-BLOCK_TREE = os.path.join(DATA_DIR, 'block_tree.xml')
-DEFAULT_FLOW_GRAPH = os.path.join(DATA_DIR, 'default_flow_graph.grc')
-
-#coloring
-COMPLEX_COLOR_SPEC = '#3399FF'
-FLOAT_COLOR_SPEC = '#FF8C69'
-INT_COLOR_SPEC = '#00FF99'
-SHORT_COLOR_SPEC = '#FFFF66'
-BYTE_COLOR_SPEC = '#FF66FF'
-COMPLEX_VECTOR_COLOR_SPEC = '#3399AA'
-FLOAT_VECTOR_COLOR_SPEC = '#CC8C69'
-INT_VECTOR_COLOR_SPEC = '#00CC99'
-SHORT_VECTOR_COLOR_SPEC = '#CCCC33'
-BYTE_VECTOR_COLOR_SPEC = '#CC66CC'
-ID_COLOR_SPEC = '#DDDDDD'
diff --git a/grc/src/platforms/python/FlowGraph.py b/grc/src/platforms/python/FlowGraph.py
deleted file mode 100644
index d0b997a58..000000000
--- a/grc/src/platforms/python/FlowGraph.py
+++ /dev/null
@@ -1,162 +0,0 @@
-"""
-Copyright 2008, 2009 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
-"""
-
-from utils import expr_utils
-from .. base.FlowGraph import FlowGraph as _FlowGraph
-from Block import Block
-from Connection import Connection
-
-def _get_value_expr(variable_block):
- """
- Get the expression to evaluate from the value param.
- Parameter blocks need to be evaluated so the stringify flag can be determined.
- @param variable_block the variable or parameter block
- @return the expression string
- """
- value_param = variable_block.get_param('value')
- if variable_block.get_key() == 'parameter': value_param.evaluate()
- return value_param.to_code()
-
-class FlowGraph(_FlowGraph):
-
- _eval_cache = dict()
- def _eval(self, code, namespace):
- """
- Evaluate the code with the given namespace.
- @param code a string with python code
- @param namespace a dict representing the namespace
- @return the resultant object
- """
- my_hash = hash(code + str(namespace))
- #cache if does not exist
- if not self._eval_cache.has_key(my_hash):
- self._eval_cache[my_hash] = eval(code, namespace, namespace)
- #return from cache
- return self._eval_cache[my_hash]
-
- def _get_io_signature(self, pad_key):
- """
- Get an io signature for this flow graph.
- The pad key determines the directionality of the io signature.
- @param pad_key a string of pad_source or pad_sink
- @return a dict with: type, nports, vlen, size
- """
- pads = filter(lambda b: b.get_key() == pad_key, self.get_enabled_blocks())
- if not pads: return {
- 'nports': '0',
- 'type': '',
- 'vlen': '0',
- 'size': '0',
- }
- pad = pads[0] #take only the first, user should not have more than 1
- #load io signature
- return {
- 'nports': str(pad.get_param('nports').evaluate()),
- 'type': str(pad.get_param('type').evaluate()),
- 'vlen': str(pad.get_param('vlen').evaluate()),
- 'size': pad.get_param('type').get_opt('size'),
- }
-
- def get_input_signature(self):
- """
- Get the io signature for the input side of this flow graph.
- The io signature with be "0", "0" if no pad source is present.
- @return a string tuple of type, num_ports, port_size
- """
- return self._get_io_signature('pad_source')
-
- def get_output_signature(self):
- """
- Get the io signature for the output side of this flow graph.
- The io signature with be "0", "0" if no pad sink is present.
- @return a string tuple of type, num_ports, port_size
- """
- return self._get_io_signature('pad_sink')
-
- def get_imports(self):
- """
- Get a set of all import statments in this flow graph namespace.
- @return a set of import statements
- """
- imports = sum([block.get_imports() for block in self.get_enabled_blocks()], [])
- imports = sorted(set(imports))
- return imports
-
- def get_variables(self):
- """
- Get a list of all variables in this flow graph namespace.
- Exclude paramterized variables.
- @return a sorted list of variable blocks in order of dependency (indep -> dep)
- """
- variables = filter(lambda b: b.get_key() in (
- 'variable', 'variable_slider', 'variable_chooser', 'variable_text_box'
- ), self.get_enabled_blocks())
- #map var id to variable block
- id2var = dict([(var.get_id(), var) for var in variables])
- #map var id to variable code
- #variable code is a concatenation of all param code (without the id param)
- id2expr = dict([(var.get_id(), var.get_param('value').get_value()) for var in variables])
- #sort according to dependency
- sorted_ids = expr_utils.sort_variables(id2expr)
- #create list of sorted variable blocks
- variables = [id2var[id] for id in sorted_ids]
- return variables
-
- def get_parameters(self):
- """
- Get a list of all paramterized variables in this flow graph namespace.
- @return a list of paramterized variables
- """
- parameters = filter(lambda b: b.get_key() == 'parameter', self.get_enabled_blocks())
- return parameters
-
- def evaluate(self, expr):
- """
- Evaluate the expression.
- @param expr the string expression
- @throw Exception bad expression
- @return the evaluated data
- """
- if self.is_flagged():
- self.deflag()
- #reload namespace
- n = dict()
- #load imports
- for imp in self.get_imports():
- try: exec imp in n
- except: pass
- #load parameters
- np = dict()
- for parameter in self.get_parameters():
- try:
- e = self._eval(_get_value_expr(parameter), n)
- np[parameter.get_id()] = e
- except: pass
- n.update(np) #merge param namespace
- #load variables
- for variable in self.get_variables():
- try:
- e = self._eval(_get_value_expr(variable), n)
- n[variable.get_id()] = e
- except: pass
- #make namespace public
- self.n = n
- #evaluate
- e = self._eval(expr, self.n)
- return e
diff --git a/grc/src/platforms/python/Generator.py b/grc/src/platforms/python/Generator.py
deleted file mode 100644
index 93321404a..000000000
--- a/grc/src/platforms/python/Generator.py
+++ /dev/null
@@ -1,142 +0,0 @@
-"""
-Copyright 2008 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 subprocess
-from Cheetah.Template import Template
-from utils import expr_utils
-from Constants import \
- TOP_BLOCK_FILE_MODE, HIER_BLOCK_FILE_MODE, \
- HIER_BLOCKS_LIB_DIR, PYEXEC, \
- FLOW_GRAPH_TEMPLATE
-from utils import convert_hier
-from ... gui import Messages
-
-class Generator(object):
-
- def __init__(self, flow_graph, file_path):
- """
- Initialize the generator object.
- Determine the file to generate.
- @param flow_graph the flow graph object
- @param file_path the path to write the file to
- """
- self._flow_graph = flow_graph
- self._generate_options = self._flow_graph.get_option('generate_options')
- if self._generate_options == 'hb':
- self._mode = HIER_BLOCK_FILE_MODE
- dirname = HIER_BLOCKS_LIB_DIR
- else:
- self._mode = TOP_BLOCK_FILE_MODE
- dirname = os.path.dirname(file_path)
- filename = self._flow_graph.get_option('id') + '.py'
- self._file_path = os.path.join(dirname, filename)
-
- def get_file_path(self): return self._file_path
-
- def write(self):
- #do throttle warning
- all_keys = ' '.join(map(lambda b: b.get_key(), self._flow_graph.get_enabled_blocks()))
- if ('usrp' not in all_keys) and ('audio' not in all_keys) and ('throttle' not in all_keys) and self._generate_options != 'hb':
- Messages.send_warning('''\
-This flow graph may not have flow control: no audio or usrp blocks found. \
-Add a Misc->Throttle block to your flow graph to avoid CPU congestion.''')
- #generate
- open(self.get_file_path(), 'w').write(str(self))
- if self._generate_options == 'hb':
- #convert hier block to xml wrapper
- convert_hier.convert_hier(self._flow_graph, self.get_file_path())
- os.chmod(self.get_file_path(), self._mode)
-
- def get_popen(self):
- """
- Execute this python flow graph.
- @return a popen object
- """
- #execute
- cmds = [PYEXEC, '-u', self.get_file_path()] #-u is unbuffered stdio
- if self._generate_options == 'no_gui':
- cmds = ['xterm', '-e'] + cmds
- p = subprocess.Popen(args=cmds, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=False, universal_newlines=True)
- return p
-
- def __str__(self):
- """
- Convert the flow graph to python code.
- @return a string of python code
- """
- imports = self._flow_graph.get_imports()
- variables = self._flow_graph.get_variables()
- parameters = self._flow_graph.get_parameters()
- #list of variables with controls
- controls = filter(lambda v: v.get_key().startswith('variable_'), variables)
- #list of blocks not including variables and imports and parameters and disabled
- blocks = sorted(self._flow_graph.get_enabled_blocks(), lambda x, y: cmp(x.get_id(), y.get_id()))
- probes = filter(lambda b: b.get_key().startswith('probe_'), blocks) #ensure probes are last in the block list
- blocks = filter(lambda b: b not in (imports + parameters + variables + probes), blocks) + probes
- #list of connections where each endpoint is enabled
- connections = self._flow_graph.get_enabled_connections()
- #list of variable names
- var_ids = [var.get_id() for var in parameters + variables]
- #list of callbacks (prepend self.)
- callbacks = [
- expr_utils.expr_prepend(cb, var_ids, 'self.')
- for cb in sum([block.get_callbacks() for block in self._flow_graph.get_enabled_blocks()], [])
- ]
- #map var id to the expression (prepend self.)
- var_id2expr = dict(
- [(var.get_id(), expr_utils.expr_prepend(var.get_make().split('\n')[0], var_ids, 'self.'))
- for var in parameters + variables]
- )
- #create graph structure for variables
- variable_graph = expr_utils.get_graph(var_id2expr)
- #map var id to direct dependents
- #for each var id, make a list of all 2nd order edges
- #use all edges of that id that are not also 2nd order edges
- #meaning: list variables the ONLY depend directly on this variable
- #and not variables that also depend indirectly on this variable
- var_id2deps = dict(
- [(var_id, filter(lambda e: e not in sum([list(variable_graph.get_edges(edge))
- for edge in variable_graph.get_edges(var_id)], []), variable_graph.get_edges(var_id)
- )
- )
- for var_id in var_ids]
- )
- #map var id to callbacks
- var_id2cbs = dict(
- [(var_id, filter(lambda c: var_id in expr_utils.expr_split(c), callbacks))
- for var_id in var_ids]
- )
- #load the namespace
- namespace = {
- 'imports': imports,
- 'flow_graph': self._flow_graph,
- 'variables': variables,
- 'controls': controls,
- 'parameters': parameters,
- 'blocks': blocks,
- 'connections': connections,
- 'generate_options': self._generate_options,
- 'var_id2expr': var_id2expr,
- 'var_id2deps': var_id2deps,
- 'var_id2cbs': var_id2cbs,
- }
- #build the template
- t = Template(open(FLOW_GRAPH_TEMPLATE, 'r').read(), namespace)
- return str(t)
diff --git a/grc/src/platforms/python/Makefile.am b/grc/src/platforms/python/Makefile.am
deleted file mode 100644
index c23d14792..000000000
--- a/grc/src/platforms/python/Makefile.am
+++ /dev/null
@@ -1,48 +0,0 @@
-#
-# Copyright 2008,2009 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.
-#
-
-include $(top_srcdir)/grc/Makefile.inc
-
-SUBDIRS = utils
-
-ourpythondir = $(grc_src_prefix)/platforms/python
-
-ourpython_PYTHON = \
- Block.py \
- Connection.py \
- Constants.py \
- FlowGraph.py \
- Generator.py \
- Param.py \
- Platform.py \
- Port.py \
- __init__.py
-
-Constants.py: $(srcdir)/Constants.py.in Makefile
- sed \
- -e 's|@PYTHONW[@]|$(PYTHONW)|g' \
- -e 's|@reldatadir[@]|$(grc_python_data_reldir)|g' \
- -e 's|@relblocksdir[@]|$(grc_blocks_data_reldir)|g' \
- -e 's|@docdir[@]|$(gr_docdir)|g' \
- $< > $@
-
-EXTRA_DIST = $(srcdir)/Constants.py.in
-BUILT_SOURCES = Constants.py
diff --git a/grc/src/platforms/python/Param.py b/grc/src/platforms/python/Param.py
deleted file mode 100644
index e5ac1dcf6..000000000
--- a/grc/src/platforms/python/Param.py
+++ /dev/null
@@ -1,402 +0,0 @@
-"""
-Copyright 2008, 2009 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
-"""
-
-from utils import expr_utils
-from .. base.Param import Param as _Param, EntryParam
-import Constants
-import numpy
-import os
-import pygtk
-pygtk.require('2.0')
-import gtk
-from gnuradio import eng_notation
-
-class FileParam(EntryParam):
- """Provide an entry box for filename and a button to browse for a file."""
-
- def __init__(self, *args, **kwargs):
- EntryParam.__init__(self, *args, **kwargs)
- input = gtk.Button('...')
- input.connect('clicked', self._handle_clicked)
- self.pack_start(input, False)
-
- def _handle_clicked(self, widget=None):
- """
- If the button was clicked, open a file dialog in open/save format.
- Replace the text in the entry with the new filename from the file dialog.
- """
- #get the paths
- file_path = self.param.is_valid() and self.param.evaluate() or ''
- (dirname, basename) = os.path.isfile(file_path) and os.path.split(file_path) or (file_path, '')
- if not os.path.exists(dirname): dirname = os.getcwd() #fix bad paths
- #build the dialog
- if self.param.get_type() == 'file_open':
- file_dialog = gtk.FileChooserDialog('Open a Data File...', None,
- gtk.FILE_CHOOSER_ACTION_OPEN, ('gtk-cancel',gtk.RESPONSE_CANCEL,'gtk-open',gtk.RESPONSE_OK))
- elif self.param.get_type() == 'file_save':
- file_dialog = gtk.FileChooserDialog('Save a Data File...', None,
- gtk.FILE_CHOOSER_ACTION_SAVE, ('gtk-cancel',gtk.RESPONSE_CANCEL, 'gtk-save',gtk.RESPONSE_OK))
- file_dialog.set_do_overwrite_confirmation(True)
- file_dialog.set_current_name(basename) #show the current filename
- file_dialog.set_current_folder(dirname) #current directory
- file_dialog.set_select_multiple(False)
- file_dialog.set_local_only(True)
- if gtk.RESPONSE_OK == file_dialog.run(): #run the dialog
- file_path = file_dialog.get_filename() #get the file path
- self.entry.set_text(file_path)
- self._handle_changed()
- file_dialog.destroy() #destroy the dialog
-
-#blacklist certain ids, its not complete, but should help
-import __builtin__
-ID_BLACKLIST = ['options', 'gr', 'blks2', 'wxgui', 'wx', 'math', 'forms', 'firdes'] + dir(__builtin__)
-#define types, native python + numpy
-VECTOR_TYPES = (tuple, list, set, numpy.ndarray)
-COMPLEX_TYPES = [complex, numpy.complex, numpy.complex64, numpy.complex128]
-REAL_TYPES = [float, numpy.float, numpy.float32, numpy.float64]
-INT_TYPES = [int, long, numpy.int, numpy.int8, numpy.int16, numpy.int32, numpy.uint64,
- numpy.uint, numpy.uint8, numpy.uint16, numpy.uint32, numpy.uint64]
-#cast to tuple for isinstance, concat subtypes
-COMPLEX_TYPES = tuple(COMPLEX_TYPES + REAL_TYPES + INT_TYPES)
-REAL_TYPES = tuple(REAL_TYPES + INT_TYPES)
-INT_TYPES = tuple(INT_TYPES)
-
-class Param(_Param):
-
- _init = False
- _hostage_cells = list()
-
- ##possible param types
- TYPES = _Param.TYPES + [
- 'complex', 'real', 'int',
- 'complex_vector', 'real_vector', 'int_vector',
- 'hex', 'string',
- 'file_open', 'file_save',
- 'id',
- 'grid_pos', 'import',
- ]
-
- def __repr__(self):
- """
- Get the repr (nice string format) for this param.
- @return the string representation
- """
- if self.get_value() in self.get_option_keys(): return self.get_option(self.get_value()).get_name()
- ##################################################
- # display logic for numbers
- ##################################################
- def num_to_str(num):
- if isinstance(num, COMPLEX_TYPES):
- num = complex(num) #cast to python complex
- if num == 0: return '0' #value is zero
- elif num.imag == 0: return '%s'%eng_notation.num_to_str(num.real) #value is real
- elif num.real == 0: return '%sj'%eng_notation.num_to_str(num.imag) #value is imaginary
- elif num.imag < 0: return '%s-%sj'%(eng_notation.num_to_str(num.real), eng_notation.num_to_str(abs(num.imag)))
- else: return '%s+%sj'%(eng_notation.num_to_str(num.real), eng_notation.num_to_str(num.imag))
- else: return str(num)
- ##################################################
- # split up formatting by type
- ##################################################
- truncate = 0 #default center truncate
- max_len = max(27 - len(self.get_name()), 3)
- e = self.evaluate()
- t = self.get_type()
- if isinstance(e, COMPLEX_TYPES): dt_str = num_to_str(e)
- elif isinstance(e, VECTOR_TYPES): #vector types
- if len(e) > 8:
- dt_str = self.get_value() #large vectors use code
- truncate = 1
- else: dt_str = ', '.join(map(num_to_str, e)) #small vectors use eval
- elif t in ('file_open', 'file_save'):
- dt_str = self.get_value()
- truncate = -1
- else: dt_str = str(e) #other types
- ##################################################
- # truncate
- ##################################################
- if len(dt_str) > max_len:
- if truncate < 0: #front truncate
- dt_str = '...' + dt_str[3-max_len:]
- elif truncate == 0: #center truncate
- dt_str = dt_str[:max_len/2 -3] + '...' + dt_str[-max_len/2:]
- elif truncate > 0: #rear truncate
- dt_str = dt_str[:max_len-3] + '...'
- return dt_str
-
- def get_input_class(self):
- if self.get_type() in ('file_open', 'file_save'): return FileParam
- return _Param.get_input_class(self)
-
- def get_color(self):
- """
- Get the color that represents this param's type.
- @return a hex color code.
- """
- try:
- return {
- #number types
- 'complex': Constants.COMPLEX_COLOR_SPEC,
- 'real': Constants.FLOAT_COLOR_SPEC,
- 'int': Constants.INT_COLOR_SPEC,
- #vector types
- 'complex_vector': Constants.COMPLEX_VECTOR_COLOR_SPEC,
- 'real_vector': Constants.FLOAT_VECTOR_COLOR_SPEC,
- 'int_vector': Constants.INT_VECTOR_COLOR_SPEC,
- #special
- 'hex': Constants.INT_COLOR_SPEC,
- 'string': Constants.BYTE_VECTOR_COLOR_SPEC,
- 'id': Constants.ID_COLOR_SPEC,
- 'grid_pos': Constants.INT_VECTOR_COLOR_SPEC,
- }[self.get_type()]
- except: return _Param.get_color(self)
-
- def get_hide(self):
- """
- Get the hide value from the base class.
- Hide the ID parameter for most blocks. Exceptions below.
- If the parameter controls a port type, vlen, or nports, return part.
- If the parameter is an empty grid position, return part.
- These parameters are redundant to display in the flow graph view.
- @return hide the hide property string
- """
- hide = _Param.get_hide(self)
- if hide: return hide
- #hide ID in non variable blocks
- if self.get_key() == 'id' and self.get_parent().get_key() not in (
- 'variable', 'variable_slider', 'variable_chooser', 'variable_text_box', 'parameter', 'options'
- ): return 'part'
- #hide port controllers for type and nports
- if self.get_key() in ' '.join(map(
- lambda p: ' '.join([p._type, p._nports]), self.get_parent().get_ports())
- ): return 'part'
- #hide port controllers for vlen, when == 1
- if self.get_key() in ' '.join(map(
- lambda p: p._vlen, self.get_parent().get_ports())
- ):
- try:
- assert int(self.evaluate()) == 1
- return 'part'
- except: pass
- #hide empty grid positions
- if self.get_key() == 'grid_pos' and not self.get_value(): return 'part'
- return hide
-
- def evaluate(self):
- """
- Evaluate the value.
- @return evaluated type
- """
- self._lisitify_flag = False
- self._stringify_flag = False
- self._hostage_cells = list()
- def eval_string(v):
- try:
- e = self.get_parent().get_parent().evaluate(v)
- assert isinstance(e, str)
- return e
- except:
- self._stringify_flag = True
- return v
- t = self.get_type()
- v = self.get_value()
- #########################
- # Enum Type
- #########################
- if self.is_enum(): return v
- #########################
- # Numeric Types
- #########################
- elif t in ('raw', 'complex', 'real', 'int', 'complex_vector', 'real_vector', 'int_vector', 'hex'):
- #raise exception if python cannot evaluate this value
- try: e = self.get_parent().get_parent().evaluate(v)
- except Exception, e:
- self._add_error_message('Value "%s" cannot be evaluated: %s'%(v, e))
- raise Exception
- #raise an exception if the data is invalid
- if t == 'raw': return e
- elif t == 'complex':
- try: assert(isinstance(e, COMPLEX_TYPES))
- except AssertionError:
- self._add_error_message('Expression "%s" is invalid for type complex.'%str(e))
- raise Exception
- return e
- elif t == 'real':
- try: assert(isinstance(e, REAL_TYPES))
- except AssertionError:
- self._add_error_message('Expression "%s" is invalid for type real.'%str(e))
- raise Exception
- return e
- elif t == 'int':
- try: assert(isinstance(e, INT_TYPES))
- except AssertionError:
- self._add_error_message('Expression "%s" is invalid for type integer.'%str(e))
- raise Exception
- return e
- #########################
- # Numeric Vector Types
- #########################
- elif t == 'complex_vector':
- if not isinstance(e, VECTOR_TYPES):
- self._lisitify_flag = True
- e = [e]
- try:
- for ei in e:
- assert(isinstance(ei, COMPLEX_TYPES))
- except AssertionError:
- self._add_error_message('Expression "%s" is invalid for type complex vector.'%str(e))
- raise Exception
- return e
- elif t == 'real_vector':
- if not isinstance(e, VECTOR_TYPES):
- self._lisitify_flag = True
- e = [e]
- try:
- for ei in e:
- assert(isinstance(ei, REAL_TYPES))
- except AssertionError:
- self._add_error_message('Expression "%s" is invalid for type real vector.'%str(e))
- raise Exception
- return e
- elif t == 'int_vector':
- if not isinstance(e, VECTOR_TYPES):
- self._lisitify_flag = True
- e = [e]
- try:
- for ei in e:
- assert(isinstance(ei, INT_TYPES))
- except AssertionError:
- self._add_error_message('Expression "%s" is invalid for type integer vector.'%str(e))
- raise Exception
- return e
- elif t == 'hex':
- return hex(e)
- else: raise TypeError, 'Type "%s" not handled'%t
- #########################
- # String Types
- #########################
- elif t in ('string', 'file_open', 'file_save'):
- #do not check if file/directory exists, that is a runtime issue
- e = eval_string(v)
- return str(e)
- #########################
- # Unique ID Type
- #########################
- elif t == 'id':
- #can python use this as a variable?
- try:
- assert(len(v) > 0)
- assert(v[0].isalpha())
- for c in v: assert(c.isalnum() or c in ('_',))
- except AssertionError:
- self._add_error_message('ID "%s" must be alpha-numeric or underscored, and begin with a letter.'%v)
- raise Exception
- params = self.get_all_params('id')
- keys = [param.get_value() for param in params]
- try: assert keys.count(v) <= 1 #id should only appear once, or zero times if block is disabled
- except:
- self._add_error_message('ID "%s" is not unique.'%v)
- raise Exception
- try: assert v not in ID_BLACKLIST
- except:
- self._add_error_message('ID "%s" is blacklisted.'%v)
- raise Exception
- return v
- #########################
- # Grid Position Type
- #########################
- elif t == 'grid_pos':
- if not v: return '' #allow for empty grid pos
- e = self.get_parent().get_parent().evaluate(v)
- try:
- assert(isinstance(e, (list, tuple)) and len(e) == 4)
- for ei in e: assert(isinstance(ei, int))
- except AssertionError:
- self._add_error_message('A grid position must be a list of 4 integers.')
- raise Exception
- row, col, row_span, col_span = e
- #check row, col
- try: assert(row >= 0 and col >= 0)
- except AssertionError:
- self._add_error_message('Row and column must be non-negative.')
- raise Exception
- #check row span, col span
- try: assert(row_span > 0 and col_span > 0)
- except AssertionError:
- self._add_error_message('Row and column span must be greater than zero.')
- raise Exception
- #calculate hostage cells
- for r in range(row_span):
- for c in range(col_span):
- self._hostage_cells.append((row+r, col+c))
- #avoid collisions
- params = filter(lambda p: p is not self, self.get_all_params('grid_pos'))
- for param in params:
- for cell in param._hostage_cells:
- if cell in self._hostage_cells:
- self._add_error_message('Another graphical element is using cell "%s".'%str(cell))
- raise Exception
- return e
- #########################
- # Import Type
- #########################
- elif t == 'import':
- n = dict() #new namespace
- try: exec v in n
- except ImportError:
- self._add_error_message('Import "%s" failed.'%v)
- raise Exception
- except Exception:
- self._add_error_message('Bad import syntax: "%s".'%v)
- raise Exception
- return filter(lambda k: str(k) != '__builtins__', n.keys())
- #########################
- else: raise TypeError, 'Type "%s" not handled'%t
-
- def to_code(self):
- """
- Convert the value to code.
- @return a string representing the code
- """
- #run init tasks in evaluate
- #such as setting flags
- if not self._init:
- self.evaluate()
- self._init = True
- v = self.get_value()
- t = self.get_type()
- if t in ('string', 'file_open', 'file_save'): #string types
- if self._stringify_flag:
- return '"%s"'%v.replace('"', '\"')
- else:
- return v
- elif t in ('complex_vector', 'real_vector', 'int_vector'): #vector types
- if self._lisitify_flag:
- return '(%s, )'%v
- else:
- return '(%s)'%v
- else:
- return v
-
- def get_all_params(self, type):
- """
- Get all the params from the flowgraph that have the given type.
- @param type the specified type
- @return a list of params
- """
- return sum([filter(lambda p: p.get_type() == type, block.get_params()) for block in self.get_parent().get_parent().get_enabled_blocks()], [])
diff --git a/grc/src/platforms/python/Platform.py b/grc/src/platforms/python/Platform.py
deleted file mode 100644
index d2bb4627e..000000000
--- a/grc/src/platforms/python/Platform.py
+++ /dev/null
@@ -1,69 +0,0 @@
-"""
-Copyright 2008 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
-from .. base.Platform import Platform as _Platform
-from FlowGraph import FlowGraph as _FlowGraph
-from Connection import Connection as _Connection
-from Block import Block as _Block
-from Port import Source,Sink
-from Param import Param as _Param
-from Generator import Generator
-from Constants import \
- HIER_BLOCKS_LIB_DIR, BLOCK_DTD, \
- BLOCK_TREE, DEFAULT_FLOW_GRAPH, \
- BLOCKS_DIR
-
-_critical_blocks_only = map(lambda b: os.path.join(BLOCKS_DIR, b), ['options.xml', 'usrp_probe.xml', 'usrp2_probe.xml'])
-
-class Platform(_Platform):
-
- def __init__(self, extra_blocks=[], critical_only=False):
- """
- Make a platform for gnuradio.
- @param extra_blocks a list of block paths to load in addition to main block library
- @param critical_only only load critical blocks (used only for usrp probe scripts to speed up load time)
- """
- #ensure hier dir
- if not os.path.exists(HIER_BLOCKS_LIB_DIR): os.mkdir(HIER_BLOCKS_LIB_DIR)
- if critical_only: block_paths = _critical_blocks_only
- else: block_paths = extra_blocks + [HIER_BLOCKS_LIB_DIR, BLOCKS_DIR]
- #convert block paths to absolute paths, ensure uniqueness
- block_paths = set(map(os.path.abspath, block_paths))
- #init
- _Platform.__init__(
- self,
- name='GRC',
- key='grc',
- block_paths=block_paths,
- block_dtd=BLOCK_DTD,
- block_tree=BLOCK_TREE,
- default_flow_graph=DEFAULT_FLOW_GRAPH,
- generator=Generator,
- )
-
- ##############################################
- # Constructors
- ##############################################
- FlowGraph = _FlowGraph
- Connection = _Connection
- Block = _Block
- Source = Source
- Sink = Sink
- Param = _Param
diff --git a/grc/src/platforms/python/Port.py b/grc/src/platforms/python/Port.py
deleted file mode 100644
index b5bc9696b..000000000
--- a/grc/src/platforms/python/Port.py
+++ /dev/null
@@ -1,129 +0,0 @@
-"""
-Copyright 2008, 2009 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
-"""
-
-from .. base.Port import Port as _Port
-import Constants
-
-class Port(_Port):
-
- ##possible port types
- TYPES = ['complex', 'float', 'int', 'short', 'byte']
-
- def __init__(self, block, n):
- """
- Make a new port from nested data.
- @param block the parent element
- @param n the nested odict
- @return a new port
- """
- vlen = n.find('vlen') or '1'
- nports = n.find('nports') or ''
- optional = n.find('optional') or ''
- #build the port
- _Port.__init__(
- self,
- block=block,
- n=n,
- )
- self._nports = nports
- self._vlen = vlen
- self._optional = bool(optional)
-
- def validate(self):
- _Port.validate(self)
- try: assert(self.get_enabled_connections() or self.get_optional())
- except AssertionError: self._add_error_message('Port is not connected.')
- try: assert(self.is_source() or len(self.get_enabled_connections()) <= 1)
- except AssertionError: self._add_error_message('Port has too many connections.')
-
- def get_vlen(self):
- """
- Get the vector length.
- If the evaluation of vlen cannot be cast to an integer, return 1.
- @return the vector length or 1
- """
- vlen = self.get_parent().resolve_dependencies(self._vlen)
- try: return int(self.get_parent().get_parent().evaluate(vlen))
- except: return 1
-
- def get_nports(self):
- """
- Get the number of ports.
- If already blank, return a blank
- If the evaluation of nports cannot be cast to an integer, return 1.
- @return the number of ports or 1
- """
- nports = self.get_parent().resolve_dependencies(self._nports)
- #return blank if nports is blank
- if not nports: return ''
- try:
- nports = int(self.get_parent().get_parent().evaluate(nports))
- assert 0 < nports
- return nports
- except: return 1
-
- def get_optional(self): return bool(self._optional)
-
- def get_color(self):
- """
- Get the color that represents this port's type.
- Codes differ for ports where the vec length is 1 or greater than 1.
- @return a hex color code.
- """
- try:
- if self.get_vlen() == 1:
- return {#vlen is 1
- 'complex': Constants.COMPLEX_COLOR_SPEC,
- 'float': Constants.FLOAT_COLOR_SPEC,
- 'int': Constants.INT_COLOR_SPEC,
- 'short': Constants.SHORT_COLOR_SPEC,
- 'byte': Constants.BYTE_COLOR_SPEC,
- }[self.get_type()]
- return {#vlen is non 1
- 'complex': Constants.COMPLEX_VECTOR_COLOR_SPEC,
- 'float': Constants.FLOAT_VECTOR_COLOR_SPEC,
- 'int': Constants.INT_VECTOR_COLOR_SPEC,
- 'short': Constants.SHORT_VECTOR_COLOR_SPEC,
- 'byte': Constants.BYTE_VECTOR_COLOR_SPEC,
- }[self.get_type()]
- except: return _Port.get_color(self)
-
-class Source(Port):
-
- def __init__(self, block, n):
- self._n = n #save n
- #key is port index
- n['key'] = str(block._source_count)
- block._source_count = block._source_count + 1
- Port.__init__(self, block, n)
-
- def __del__(self):
- self.get_parent()._source_count = self.get_parent()._source_count - 1
-
-class Sink(Port):
-
- def __init__(self, block, n):
- self._n = n #save n
- #key is port index
- n['key'] = str(block._sink_count)
- block._sink_count = block._sink_count + 1
- Port.__init__(self, block, n)
-
- def __del__(self):
- self.get_parent()._sink_count = self.get_parent()._sink_count - 1
diff --git a/grc/src/platforms/python/__init__.py b/grc/src/platforms/python/__init__.py
deleted file mode 100644
index 8b1378917..000000000
--- a/grc/src/platforms/python/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/grc/src/platforms/python/utils/Makefile.am b/grc/src/platforms/python/utils/Makefile.am
deleted file mode 100644
index b12e51d8e..000000000
--- a/grc/src/platforms/python/utils/Makefile.am
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright 2008 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.
-#
-
-include $(top_srcdir)/grc/Makefile.inc
-
-ourpythondir = $(grc_src_prefix)/platforms/python/utils
-
-ourpython_PYTHON = \
- convert_hier.py \
- expr_utils.py \
- extract_docs.py \
- __init__.py
diff --git a/grc/src/platforms/python/utils/__init__.py b/grc/src/platforms/python/utils/__init__.py
deleted file mode 100644
index 8b1378917..000000000
--- a/grc/src/platforms/python/utils/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/grc/src/platforms/python/utils/convert_hier.py b/grc/src/platforms/python/utils/convert_hier.py
deleted file mode 100644
index 495358984..000000000
--- a/grc/src/platforms/python/utils/convert_hier.py
+++ /dev/null
@@ -1,78 +0,0 @@
-"""
-Copyright 2008 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
-"""
-
-from .. Constants import BLOCK_DTD
-from .... utils import ParseXML
-from .... utils import odict
-
-def convert_hier(flow_graph, python_file):
- #extract info from the flow graph
- input_sig = flow_graph.get_input_signature()
- output_sig = flow_graph.get_output_signature()
- parameters = flow_graph.get_parameters()
- block_key = flow_graph.get_option('id')
- block_name = flow_graph.get_option('title')
- block_category = flow_graph.get_option('category')
- block_desc = flow_graph.get_option('description')
- block_author = flow_graph.get_option('author')
- #build the nested data
- block_n = odict()
- block_n['name'] = block_name
- block_n['key'] = block_key
- block_n['category'] = block_category
- block_n['import'] = 'execfile("%s")'%python_file
- #make data
- block_n['make'] = '%s(\n\t%s,\n)'%(
- block_key,
- ',\n\t'.join(['%s=$%s'%(param.get_id(), param.get_id()) for param in parameters]),
- )
- #callback data
- block_n['callback'] = ['set_%s($%s)'%(param.get_id(), param.get_id()) for param in parameters]
- #param data
- params_n = list()
- for param in parameters:
- param_n = odict()
- param_n['name'] = param.get_param('label').get_value() or param.get_id()
- param_n['key'] = param.get_id()
- param_n['value'] = param.get_param('value').get_value()
- param_n['type'] = 'raw'
- params_n.append(param_n)
- block_n['param'] = params_n
- #sink data
- if int(input_sig['nports']):
- sink_n = odict()
- sink_n['name'] = 'in'
- sink_n['type'] = input_sig['type']
- sink_n['vlen'] = input_sig['vlen']
- sink_n['nports'] = input_sig['nports']
- block_n['sink'] = sink_n
- #source data
- if int(output_sig['nports']):
- source_n = odict()
- source_n['name'] = 'out'
- source_n['type'] = output_sig['type']
- source_n['vlen'] = output_sig['vlen']
- source_n['nports'] = output_sig['nports']
- block_n['source'] = source_n
- #doc data
- block_n['doc'] = "%s\n%s\n%s"%(block_author, block_desc, python_file)
- #write the block_n to file
- xml_file = python_file + '.xml'
- ParseXML.to_file({'block': block_n}, xml_file)
- ParseXML.validate_dtd(xml_file, BLOCK_DTD)
diff --git a/grc/src/platforms/python/utils/expr_utils.py b/grc/src/platforms/python/utils/expr_utils.py
deleted file mode 100644
index 40700993d..000000000
--- a/grc/src/platforms/python/utils/expr_utils.py
+++ /dev/null
@@ -1,137 +0,0 @@
-"""
-Copyright 2008 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 string
-VAR_CHARS = string.letters + string.digits + '_'
-
-class graph(object):
- """
- Simple graph structure held in a dictionary.
- """
-
- def __init__(self): self._graph = dict()
-
- def __str__(self): return str(self._graph)
-
- def add_node(self, node_key):
- if self._graph.has_key(node_key): return
- self._graph[node_key] = set()
-
- def remove_node(self, node_key):
- if not self._graph.has_key(node_key): return
- for edges in self._graph.values():
- if node_key in edges: edges.remove(node_key)
- self._graph.pop(node_key)
-
- def add_edge(self, src_node_key, dest_node_key):
- self._graph[src_node_key].add(dest_node_key)
-
- def remove_edge(self, src_node_key, dest_node_key):
- self._graph[src_node_key].remove(dest_node_key)
-
- def get_nodes(self): return self._graph.keys()
-
- def get_edges(self, node_key): return self._graph[node_key]
-
-def expr_split(expr):
- """
- Split up an expression by non alphanumeric characters, including underscore.
- Leave strings in-tact.
- #TODO ignore escaped quotes, use raw strings.
- @param expr an expression string
- @return a list of string tokens that form expr
- """
- toks = list()
- tok = ''
- quote = ''
- for char in expr:
- if quote or char in VAR_CHARS:
- if char == quote: quote = ''
- tok += char
- elif char in ("'", '"'):
- toks.append(tok)
- tok = char
- quote = char
- else:
- toks.append(tok)
- toks.append(char)
- tok = ''
- toks.append(tok)
- return filter(lambda t: t, toks)
-
-def expr_prepend(expr, vars, prepend):
- """
- Search for vars in the expression and add the prepend.
- @param expr an expression string
- @param vars a list of variable names
- @param prepend the prepend string
- @return a new expression with the prepend
- """
- expr_splits = expr_split(expr)
- for i, es in enumerate(expr_splits):
- if es in vars: expr_splits[i] = prepend + es
- return ''.join(expr_splits)
-
-def get_variable_dependencies(expr, vars):
- """
- Return a set of variables used in this expression.
- @param expr an expression string
- @param vars a list of variable names
- @return a subset of vars used in the expression
- """
- expr_toks = expr_split(expr)
- return set(filter(lambda v: v in expr_toks, vars))
-
-def get_graph(exprs):
- """
- Get a graph representing the variable dependencies
- @param exprs a mapping of variable name to expression
- @return a graph of variable deps
- """
- vars = exprs.keys()
- #get dependencies for each expression, load into graph
- var_graph = graph()
- for var in vars: var_graph.add_node(var)
- for var, expr in exprs.iteritems():
- for dep in get_variable_dependencies(expr, vars):
- var_graph.add_edge(dep, var)
- return var_graph
-
-def sort_variables(exprs):
- """
- Get a list of variables in order of dependencies.
- @param exprs a mapping of variable name to expression
- @return a list of variable names
- @throws AssertionError circular dependencies
- """
- var_graph = get_graph(exprs)
- sorted_vars = list()
- #determine dependency order
- while var_graph.get_nodes():
- #get a list of nodes with no edges
- indep_vars = filter(lambda var: not var_graph.get_edges(var), var_graph.get_nodes())
- assert indep_vars
- #add the indep vars to the end of the list
- sorted_vars.extend(sorted(indep_vars))
- #remove each edge-less node from the graph
- for var in indep_vars: var_graph.remove_node(var)
- return reversed(sorted_vars)
-
-if __name__ == '__main__':
- for i in sort_variables({'x':'1', 'y':'x+1', 'a':'x+y', 'b':'y+1', 'c':'a+b+x+y'}): print i
diff --git a/grc/src/platforms/python/utils/extract_docs.py b/grc/src/platforms/python/utils/extract_docs.py
deleted file mode 100644
index 523519f97..000000000
--- a/grc/src/platforms/python/utils/extract_docs.py
+++ /dev/null
@@ -1,92 +0,0 @@
-"""
-Copyright 2008, 2009 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
-"""
-
-from .. Constants import DOCS_DIR
-from lxml import etree
-import os
-import re
-
-DOXYGEN_NAME_XPATH = '/doxygen/compounddef/compoundname'
-DOXYGEN_BRIEFDESC_GR_XPATH = '/doxygen/compounddef/briefdescription'
-DOXYGEN_DETAILDESC_GR_XPATH = '/doxygen/compounddef/detaileddescription'
-
-def extract_txt(xml):
- """
- Recursivly pull the text out of an xml tree.
- @param xml the xml tree
- @return a string
- """
- text = (xml.text or '').replace('\n', '')
- tail = (xml.tail or '').replace('\n', '')
- if xml.tag == 'para': tail += '\n\n'
- if xml.tag == 'linebreak': text += '\n'
- if xml.tag == 'parametername': text += ': '
- return text + ''.join(
- map(lambda x: extract_txt(x), xml)
- ) + tail
-
-def _extract(key):
- """
- Extract the documentation from the doxygen generated xml files.
- If multiple files match, combine the docs.
- @param key the block key
- @return a string with documentation
- """
- UBUNTU_DOCS_DIR = '/usr/share/doc/gnuradio-doc/xml'
- if os.path.exists(DOCS_DIR): docs_dir = DOCS_DIR
- elif os.path.exists(UBUNTU_DOCS_DIR): docs_dir = UBUNTU_DOCS_DIR
- else: return ''
- #extract matches
- pattern = key.replace('_', '_*').replace('x', '\w')
- prog = re.compile('^class%s\..*$'%pattern)
- matches = filter(lambda f: prog.match(f), os.listdir(docs_dir))
- #combine all matches
- doc_strs = list()
- for match in matches:
- try:
- xml_file = os.path.join(docs_dir, match)
- xml = etree.parse(xml_file)
- #extract descriptions
- comp_name = extract_txt(xml.xpath(DOXYGEN_NAME_XPATH)[0]).strip()
- comp_name = ' --- ' + comp_name + ' --- '
- if re.match('(gr|usrp2|trellis)_.*', key):
- brief_desc = extract_txt(xml.xpath(DOXYGEN_BRIEFDESC_GR_XPATH)[0]).strip()
- detailed_desc = extract_txt(xml.xpath(DOXYGEN_DETAILDESC_GR_XPATH)[0]).strip()
- else:
- brief_desc = ''
- detailed_desc = ''
- #combine
- doc_strs.append('\n\n'.join([comp_name, brief_desc, detailed_desc]).strip())
- except IndexError: pass #bad format
- return '\n\n'.join(doc_strs)
-
-_docs_cache = dict()
-def extract(key):
- """
- Call the private extract and cache the result.
- @param key the block key
- @return a string with documentation
- """
- try: assert _docs_cache.has_key(key)
- except: _docs_cache[key] = _extract(key)
- return _docs_cache[key]
-
-if __name__ == '__main__':
- import sys
- print extract(sys.argv[1])