Akihiko Odaki | 956af7d | 2023-10-09 17:40:51 +0100 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | # SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | |
Akihiko Odaki | 6c2313e | 2023-11-06 18:50:58 +0000 | [diff] [blame] | 4 | import os, sys, xml.etree.ElementTree |
Akihiko Odaki | 956af7d | 2023-10-09 17:40:51 +0100 | [diff] [blame] | 5 | |
| 6 | def writeliteral(indent, bytes): |
| 7 | sys.stdout.write(' ' * indent) |
| 8 | sys.stdout.write('"') |
| 9 | quoted = True |
| 10 | |
| 11 | for c in bytes: |
| 12 | if not quoted: |
| 13 | sys.stdout.write('\n') |
| 14 | sys.stdout.write(' ' * indent) |
| 15 | sys.stdout.write('"') |
| 16 | quoted = True |
| 17 | |
| 18 | if c == b'"'[0]: |
| 19 | sys.stdout.write('\\"') |
| 20 | elif c == b'\\'[0]: |
| 21 | sys.stdout.write('\\\\') |
| 22 | elif c == b'\n'[0]: |
| 23 | sys.stdout.write('\\n"') |
| 24 | quoted = False |
| 25 | elif c >= 32 and c < 127: |
| 26 | sys.stdout.write(c.to_bytes(1, 'big').decode()) |
| 27 | else: |
| 28 | sys.stdout.write(f'\{c:03o}') |
| 29 | |
| 30 | if quoted: |
| 31 | sys.stdout.write('"') |
| 32 | |
| 33 | sys.stdout.write('#include "qemu/osdep.h"\n' \ |
| 34 | '#include "exec/gdbstub.h"\n' \ |
| 35 | '\n' |
| 36 | 'const GDBFeature gdb_static_features[] = {\n') |
| 37 | |
| 38 | for input in sys.argv[1:]: |
| 39 | with open(input, 'rb') as file: |
| 40 | read = file.read() |
| 41 | |
Akihiko Odaki | 6c2313e | 2023-11-06 18:50:58 +0000 | [diff] [blame] | 42 | parser = xml.etree.ElementTree.XMLPullParser(['start', 'end']) |
| 43 | parser.feed(read) |
| 44 | events = parser.read_events() |
| 45 | event, element = next(events) |
| 46 | if event != 'start': |
| 47 | sys.stderr.write(f'unexpected event: {event}\n') |
| 48 | exit(1) |
| 49 | if element.tag != 'feature': |
| 50 | sys.stderr.write(f'unexpected start tag: {element.tag}\n') |
| 51 | exit(1) |
| 52 | |
Akihiko Odaki | eb37086 | 2024-02-27 14:43:20 +0000 | [diff] [blame] | 53 | feature_name = element.attrib['name'] |
Akihiko Odaki | 6c2313e | 2023-11-06 18:50:58 +0000 | [diff] [blame] | 54 | regnum = 0 |
Akihiko Odaki | eb37086 | 2024-02-27 14:43:20 +0000 | [diff] [blame] | 55 | regnames = [] |
Akihiko Odaki | 6c2313e | 2023-11-06 18:50:58 +0000 | [diff] [blame] | 56 | regnums = [] |
| 57 | tags = ['feature'] |
| 58 | for event, element in events: |
| 59 | if event == 'end': |
| 60 | if element.tag != tags[len(tags) - 1]: |
| 61 | sys.stderr.write(f'unexpected end tag: {element.tag}\n') |
| 62 | exit(1) |
| 63 | |
| 64 | tags.pop() |
| 65 | if element.tag == 'feature': |
| 66 | break |
| 67 | elif event == 'start': |
| 68 | if len(tags) < 2 and element.tag == 'reg': |
| 69 | if 'regnum' in element.attrib: |
| 70 | regnum = int(element.attrib['regnum']) |
| 71 | |
Akihiko Odaki | eb37086 | 2024-02-27 14:43:20 +0000 | [diff] [blame] | 72 | regnames.append(element.attrib['name']) |
Akihiko Odaki | 6c2313e | 2023-11-06 18:50:58 +0000 | [diff] [blame] | 73 | regnums.append(regnum) |
| 74 | regnum += 1 |
| 75 | |
| 76 | tags.append(element.tag) |
| 77 | else: |
| 78 | raise Exception(f'unexpected event: {event}\n') |
| 79 | |
| 80 | if len(tags): |
| 81 | sys.stderr.write('unterminated feature tag\n') |
| 82 | exit(1) |
| 83 | |
| 84 | base_reg = min(regnums) |
| 85 | num_regs = max(regnums) - base_reg + 1 if len(regnums) else 0 |
| 86 | |
Akihiko Odaki | 956af7d | 2023-10-09 17:40:51 +0100 | [diff] [blame] | 87 | sys.stdout.write(' {\n') |
| 88 | writeliteral(8, bytes(os.path.basename(input), 'utf-8')) |
| 89 | sys.stdout.write(',\n') |
| 90 | writeliteral(8, read) |
Akihiko Odaki | eb37086 | 2024-02-27 14:43:20 +0000 | [diff] [blame] | 91 | sys.stdout.write(',\n') |
| 92 | writeliteral(8, bytes(feature_name, 'utf-8')) |
| 93 | sys.stdout.write(',\n (const char * const []) {\n') |
| 94 | |
| 95 | for index, regname in enumerate(regnames): |
| 96 | sys.stdout.write(f' [{regnums[index] - base_reg}] =\n') |
| 97 | writeliteral(16, bytes(regname, 'utf-8')) |
| 98 | sys.stdout.write(',\n') |
| 99 | |
| 100 | sys.stdout.write(f' }},\n {num_regs},\n }},\n') |
Akihiko Odaki | 956af7d | 2023-10-09 17:40:51 +0100 | [diff] [blame] | 101 | |
| 102 | sys.stdout.write(' { NULL }\n};\n') |