| import os |
| import re |
| |
| _test_data_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../tests") |
| |
| def list_files(): |
| """ |
| Return a list of data files under tests/data |
| |
| These strings are suitable to be passed to read(). |
| """ |
| |
| result = [] |
| for dirname, dirnames, filenames in os.walk(_test_data_dir): |
| dirname = (os.path.relpath(dirname, _test_data_dir) + '/').replace('./', '') |
| for filename in filenames: |
| if filename.endswith('.data') and not filename.startswith('.'): |
| result.append(dirname + filename) |
| return sorted(result) |
| |
| def read(name): |
| """ |
| Read, parse, and return a test data file |
| |
| @param name Filename relative to the tests/data directory |
| @returns A hash from section to the string contents |
| """ |
| |
| section_lines = {} |
| cur_section = None |
| |
| with open(os.path.join(_test_data_dir, name)) as f: |
| for line in f: |
| line = line.rstrip().partition('#')[0].rstrip() |
| if line == '': |
| continue |
| elif line.startswith('--'): |
| cur_section = line[2:].strip() |
| if cur_section in section_lines: |
| raise Exception("section %s already exists in the test data file") |
| section_lines[cur_section] = [] |
| elif cur_section: |
| section_lines[cur_section].append(line) |
| data = { section: '\n'.join(lines) for (section, lines) in section_lines.items() } |
| |
| # Resolve links |
| for k in data: |
| if '@' in k: |
| del data[k] |
| section, path = k.split('@') |
| section = section.strip() |
| path = path.strip() |
| fullpath = os.path.join(_test_data_dir, os.path.dirname(name), path) |
| with file(fullpath) as f: |
| data[section] = f.read() |
| |
| # Special case: convert 'raw' section into binary |
| # Each line is parsed as an integer representing an instruction. |
| if 'raw' in data: |
| insts = [] |
| for line in data['raw'].splitlines(): |
| num, _, _ = line.partition("#") |
| insts.append(int(num, 0)) |
| data['raw'] = insts |
| # |
| # Special case: convert 'mem' section into binary |
| # The string '00 11\n22 33' results in "\x00\x11\x22\x33" |
| # Ignores hexdump prefix ending with a colon. |
| if 'mem' in data: |
| hex_strs = [] |
| for line in data['mem'].splitlines(): |
| if ':' in line: |
| line = line[(line.rindex(':')+1):] |
| hex_strs.extend(re.findall(r"[0-9A-Fa-f]{2}", line)) |
| data['mem'] = ''.join(map(lambda x: chr(int(x, 16)), hex_strs)) |
| |
| return data |