#! /usr/bin/python from sys import argv, exit from itertools import cycle, izip import re as RX def bad_usage(): exit('usage: split-pieces { scaf WD | qf P WD/N|WD,WD,... } N N ...') ARGC = 1 def getarg(must = True): global ARGC if ARGC < len(argv): ARGC += 1; return argv[ARGC - 1] elif must: bad_usage() else: return None class ScafConvert (object): def __init__(me, piecewd): me.piecewd = piecewd me.fmt = '0x%%0%dx' % ((piecewd + 3)/4) me.mask = (1 << piecewd) - 1 @classmethod def parse(cls): return ScafConvert(int(getarg())) def hack(me, n): nn = [] while n: nn.append(me.fmt % (n&me.mask)) n >>= me.piecewd return nn def unhack(me, nn): return sum(n << i*me.piecewd for i, n in enumerate(nn)) class BaseQfConvert (object): def __init__(me, p, wdseq): me.p = p me.wdseq = wdseq @classmethod def parse(cls): p = eval(getarg()) arg = getarg() if '/' in arg: wd, n = map(int, arg.split('/')) seq = [(wd*(i + 1) + n - 1)/n - (wd*i + n - 1)/n for i in xrange(n)] else: seq = map(int, arg.split(',')) print ";; piece widths = %r" % seq return cls(p, seq) def hack(me, n): if me.SIGNEDP and 2*n >= me.p: n -= me.p nn = [] wds = cycle(me.wdseq) while n: wd = wds.next() lim = 1 << wd; m = lim - 1 d = n&m; n >>= wd if me.SIGNEDP and d >= lim/2: d -= lim; n += 1 nn.append(me.fmt(d)) return nn def unhack(me, nn): a = o = 0 for n, w in izip(nn, cycle(me.wdseq)): a += n << o o += w if a < 0: a += me.p return a class SignedQfConvert (BaseQfConvert): SIGNEDP = True def fmt(me, n): return str(n) class UnsignedQfConvert (BaseQfConvert): SIGNEDP = False def fmt(me, n): return '0x%x' % n R_split = RX.compile(r',\s*|\s+') def spliteval(arg): return map(eval, R_split.split(arg.strip())) convmap = { 'scaf': ScafConvert, 'unscaf': ScafConvert, 'qf': SignedQfConvert, 'unqf': SignedQfConvert, 'uqf': UnsignedQfConvert, 'unuqf': UnsignedQfConvert } op = getarg() cvt = convmap[op].parse() if op.startswith('un'): prepare, conv, format = spliteval, cvt.unhack, str else: prepare, conv, format = eval, cvt.hack, lambda vv: ', '.join(vv) while True: val = getarg(must = False) if val is None: break print format(conv(prepare(val)))