chiark / gitweb /
utils/split-pieces (QfConvert): Rename to `BaseQfConvert'.
[catacomb] / utils / split-pieces
CommitLineData
a81dbb3f
MW
1#! /usr/bin/python
2
3from sys import argv, exit
4from itertools import cycle, izip
5import re as RX
6
7def bad_usage():
29f2f4de 8 exit('usage: split-pieces { scaf WD | qf P WD/N|WD,WD,... } N N ...')
a81dbb3f
MW
9
10ARGC = 1
11def getarg(must = True):
12 global ARGC
13 if ARGC < len(argv): ARGC += 1; return argv[ARGC - 1]
14 elif must: bad_usage()
15 else: return None
16
17class ScafConvert (object):
18 def __init__(me, piecewd):
19 me.piecewd = piecewd
20 me.fmt = '0x%%0%dx' % ((piecewd + 3)/4)
21 me.mask = (1 << piecewd) - 1
22 @classmethod
23 def parse(cls):
24 return ScafConvert(int(getarg()))
25 def hack(me, n):
26 nn = []
27 while n:
28 nn.append(me.fmt % (n&me.mask))
29 n >>= me.piecewd
30 return nn
31 def unhack(me, nn):
32 return sum(n << i*me.piecewd for i, n in enumerate(nn))
33
83d31c09 34class BaseQfConvert (object):
a81dbb3f
MW
35 def __init__(me, p, wdseq):
36 me.p = p
37 me.wdseq = wdseq
38 @classmethod
39 def parse(cls):
40 p = eval(getarg())
41 arg = getarg()
42 if '/' in arg:
43 wd, n = map(int, arg.split('/'))
44 seq = [(wd*(i + 1) + n - 1)/n - (wd*i + n - 1)/n for i in xrange(n)]
45 else:
46 seq = map(int, arg.split(','))
47 print ";; piece widths = %r" % seq
de3d07cf 48 return cls(p, seq)
a81dbb3f
MW
49 def hack(me, n):
50 if 2*n >= me.p: n -= p
51 nn = []
52 wds = cycle(me.wdseq)
53 while n:
54 wd = wds.next()
55 lim = 1 << wd; m = lim - 1
56 d = n&m; n >>= wd
57 if d >= lim/2: d -= lim; n += 1
58 nn.append(str(d))
59 return nn
60 def unhack(me, nn):
61 a = o = 0
62 for n, w in izip(nn, cycle(me.wdseq)):
63 a += n << o
64 o += w
65 if a < 0: a += me.p
66 return a
67
68R_split = RX.compile(r',\s*|\s+')
69def spliteval(arg): return map(eval, R_split.split(arg.strip()))
70
71convmap = { 'scaf': ScafConvert,
72 'unscaf': ScafConvert,
83d31c09
MW
73 'qf': BaseQfConvert,
74 'unqf': BaseQfConvert }
a81dbb3f
MW
75op = getarg()
76cvt = convmap[op].parse()
77if op.startswith('un'): prepare, conv, format = spliteval, cvt.unhack, str
78else: prepare, conv, format = eval, cvt.hack, lambda vv: ', '.join(vv)
79
80while True:
81 val = getarg(must = False)
82 if val is None: break
83 print format(conv(prepare(val)))