prjxray/utils/xjson.py

102 lines
2.6 KiB
Python
Executable File

#!/usr/bin/env python3
import io
import json
import re
import sys
from collections import OrderedDict
def extract_numbers(s):
"""
>>> extract_numbers("CLK_HROW_WR10END2_3")
('CLK_HROW_WR', 10, 'END', 2, '_', 3)
>>> extract_numbers("VBRK_WR1END2")
('VBRK_WR', 1, 'END', 2)
"""
bits = []
for m in re.finditer("([^0-9]*)([0-9]*)", s):
if m.group(1):
bits.append(m.group(1))
if m.group(2):
bits.append(int(m.group(2)))
return tuple(bits)
def sort(data):
# FIXME: We assume that a list is a tileconn.json format...
if isinstance(data, list) and len(data) > 0 and 'wire_pairs' in data[0]:
for o in data:
o['wire_pairs'].sort(
key=lambda o: (extract_numbers(o[0]), extract_numbers(o[1])))
data.sort(key=lambda o: (o['tile_types'], o['grid_deltas']))
return data
else:
def key(o):
if o is None:
return None
elif isinstance(o, str):
return extract_numbers(o)
elif isinstance(o, int):
return o
elif isinstance(o, list):
return [key(i) for i in o]
elif isinstance(o, dict):
return [(key(k), key(v)) for k, v in o.items()]
raise ValueError(repr(o))
def rsorter(o):
if isinstance(o, dict):
nitems = []
for k, v in o.items():
nitems.append((key(k), k, rsorter(v)))
nitems.sort(key=lambda n: n[0])
new_dict = OrderedDict()
for _, k, v in nitems:
new_dict[k] = v
return new_dict
elif isinstance(o, list):
if len(o) == 2:
return o
nlist = []
for i in o:
nlist.append((key(i), rsorter(i)))
nlist.sort(key=lambda n: n[0])
new_list = []
for _, i in nlist:
new_list.append(i)
return new_list
else:
return o
return rsorter(data)
def pprint(f, data):
detach = False
if not isinstance(f, io.TextIOBase):
detach = True
f = io.TextIOWrapper(f)
data = sort(data)
json.dump(data, f, indent=4)
f.write('\n')
f.flush()
if detach:
f.detach()
if __name__ == "__main__":
if len(sys.argv) == 1:
import doctest
doctest.testmod()
else:
assert len(sys.argv) == 2
d = json.load(open(sys.argv[1]))
pprint(sys.stdout, d)