Skip to content
Snippets Groups Projects
Commit 91ccc467 authored by James Graham's avatar James Graham
Browse files

Use regex for format string processing in FixedFormatUnpacker - fixed xfail in...

Use regex for format string processing in FixedFormatUnpacker - fixed xfail in Fortran formats with repeats
parent ee3f8d56
Branches
Tags
No related merge requests found
...@@ -8,6 +8,7 @@ import random ...@@ -8,6 +8,7 @@ import random
import math import math
import filecmp import filecmp
import logging import logging
import re
from collections import namedtuple from collections import namedtuple
...@@ -470,18 +471,9 @@ class FixedFormatUnpacker(object): ...@@ -470,18 +471,9 @@ class FixedFormatUnpacker(object):
:param format_string: C format string :param format_string: C format string
:return: List of FormatItems :return: List of FormatItems
""" """
items = []
types = {"d": int, "s": str, "f": float} types = {"d": int, "s": str, "f": float}
format_string = format_string.lower() p = re.compile(r'%-?(?P<width>[0-9]+)[.0-9]*(?P<type>[dsfDSF])')
for item in format_string.split("%")[1:]: items = [cls.FormatItem(types[match.group("type")], int(match.group("width"))) for match in p.finditer(format_string)]
try:
item_width = int(item[:-1])
except ValueError:
# Probably a float format specifier, ignore precision, just use width
item_width = int(float(item[:-1]))
item_type = types[item[-1]]
items.append(cls.FormatItem(item_type, item_width))
return items return items
@classmethod @classmethod
...@@ -494,15 +486,12 @@ class FixedFormatUnpacker(object): ...@@ -494,15 +486,12 @@ class FixedFormatUnpacker(object):
""" """
items = [] items = []
types = {"i": int, "a": str, "f": float, "x": None} types = {"i": int, "a": str, "f": float, "x": None}
format_string = format_string.lower() p = re.compile(r'\s*(?P<repeat>[0-9]*)(?P<type>[ixafIXAF])(?P<width>[0-9]*)\s*')
for item in format_string.split(","): for match in p.finditer(format_string):
try: repeat = int(match.group("repeat")) if match.group("repeat") else 1
item_width = int(item[1:]) width = int(match.group("width")) if match.group("width") else 1
except ValueError: for _ in range(repeat):
# Probably a float format specifier, ignore precision, just use width items.append(cls.FormatItem(types[match.group("type")], width))
item_width = int(float(item[1:]))
item_type = types[item[0]]
items.append(cls.FormatItem(item_type, item_width))
return items return items
def unpack(self, string): def unpack(self, string):
......
...@@ -163,7 +163,7 @@ class UtilTest(unittest.TestCase): ...@@ -163,7 +163,7 @@ class UtilTest(unittest.TestCase):
self.assertFalse("four" in enum) self.assertFalse("four" in enum)
def test_fixed_format_unpacker_c(self): def test_fixed_format_unpacker_c(self):
unpacker = FixedFormatUnpacker("%4d%5s%4.1f") unpacker = FixedFormatUnpacker("%-4d%5s%4.1f")
toks = unpacker.unpack("1234hello12.3") toks = unpacker.unpack("1234hello12.3")
self.assertEqual(3, len(toks)) self.assertEqual(3, len(toks))
self.assertEqual(1234, toks[0]) self.assertEqual(1234, toks[0])
...@@ -188,9 +188,8 @@ class UtilTest(unittest.TestCase): ...@@ -188,9 +188,8 @@ class UtilTest(unittest.TestCase):
self.assertEqual("hello", toks[1]) self.assertEqual("hello", toks[1])
self.assertAlmostEqual(12.3, toks[2]) self.assertAlmostEqual(12.3, toks[2])
@unittest.expectedFailure
def test_fixed_format_unpacker_fortran_repeat(self): def test_fixed_format_unpacker_fortran_repeat(self):
unpacker = FixedFormatUnpacker("2I2,X3,A5,X2,F4.1", unpacker = FixedFormatUnpacker("2I2,X3,A5,2X,F4.1",
FixedFormatUnpacker.FormatStyle.Fortran) FixedFormatUnpacker.FormatStyle.Fortran)
toks = unpacker.unpack("1234 x hello x12.3") toks = unpacker.unpack("1234 x hello x12.3")
self.assertEqual(4, len(toks)) self.assertEqual(4, len(toks))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment