Source code for spinn_utilities.make_tools.replacer

# Copyright (c) 2018 The University of Manchester
# This program 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 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# 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, see <>.

import logging
import os
import struct
from spinn_utilities.log import FormatAdapter
from .file_converter import FORMAT_EXP
from .file_converter import TOKEN

logger = FormatAdapter(logging.getLogger(__name__))

[docs]class Replacer(object): """ Performs replacements. """ _INT_FMT = struct.Struct("!I") _FLT_FMT = struct.Struct("!f") _DBL_FMT = struct.Struct("!d") def __init__(self, dict_pointer): """ :param str dict_pointer: Where to find the dictionary file """ self._messages = {} rest, _ = os.path.splitext(dict_pointer) dict_path = rest + ".dict" if os.path.isfile(dict_path): with open(dict_path) as dict_info: for line in dict_info: parts = line.strip().split(",", 2) if len(parts) != 3: continue if not parts[0].isdigit(): continue self._messages[parts[0]] = parts else: logger.error("Unable to find a dictionary file at {}".format( dict_path))
[docs] def replace(self, short): """ Apply the replacements to a short message. :param str short: The short message to apply the transform to. :return: The expanded message. :rtype: str """ parts = short.split(TOKEN) if not parts[0].isdigit(): return short if not parts[0] in self._messages: return short (_id, preface, original) = self._messages[parts[0]] replaced = original.encode("latin-1").decode("unicode_escape") if len(parts) > 1: matches = FORMAT_EXP.findall(original) # Remove any blanks due to double spacing matches = [x for x in matches if x != ""] # Start at 0 so first i+1 puts you at 1 as part 0 is the short i = 0 try: for match in matches: i += 1 if match.endswith("f"): replacement = str(self._hex_to_float(parts[i])) elif match.endswith("F"): replacement = str(self._hexes_to_double( parts[i], parts[i+1])) i += 1 else: replacement = parts[i] replaced = replaced.replace(match, replacement, 1) except Exception: # pylint: disable=broad-except return short return preface + replaced
def _hex_to_float(self, hex_str): return self._FLT_FMT.unpack( self._INT_FMT.pack(int(hex_str, 16)))[0] def _hexes_to_double(self, upper, lower): return self._DBL_FMT.unpack( self._INT_FMT.pack(int(upper, 16)) + self._INT_FMT.pack(int(lower, 16)))[0]