From db7e2d7dd36feefa491b683c5034d6013eae5dc3 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 13 Dec 2018 14:32:29 -0800 Subject: [PATCH] Adding tool for canonicalizing json files. Fixes #154. Signed-off-by: Tim 'mithro' Ansell --- prjxray/xjson.py | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 prjxray/xjson.py diff --git a/prjxray/xjson.py b/prjxray/xjson.py new file mode 100644 index 00000000..c45d7911 --- /dev/null +++ b/prjxray/xjson.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 +import re +import json +import sys + + +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): + 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'])) + else: + def walker(o, f): + if isinstance(o, dict): + for i in o.values(): + walker(i, f) + elif isinstance(o, list): + for i in o: + walker(i, f) + f(o) + + def f(o): + if isinstance(o, list): + if len(o) > 2: + strings = all(isinstance(x, str) for x in o) + if strings: + o.sort() + + walker(data, f) + + +def pprint(f, data): + sort(data) + json.dump(d, f, sort_keys=True, indent=4) + f.write('\n') + + +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)