chiark / gitweb /
utils/split-pieces: Introduce unsigned quick fields.
[catacomb] / utils / split-pieces
index 473e2fea0c92d81b3dc5e2de6ae8595b005334e6..0bffd5009e19cde4ac8a9621a364606b097a0dcc 100755 (executable)
@@ -5,7 +5,7 @@ from itertools import cycle, izip
 import re as RX
 
 def bad_usage():
-  exit('usage: split-pieces { scaf WD | qf WD/N|WD,WD,... } N N ...')
+  exit('usage: split-pieces { scaf WD | qf WD/N|WD,WD,... } N N ...')
 
 ARGC = 1
 def getarg(must = True):
@@ -31,7 +31,7 @@ class ScafConvert (object):
   def unhack(me, nn):
     return sum(n << i*me.piecewd for i, n in enumerate(nn))
 
-class QfConvert (object):
+class BaseQfConvert (object):
   def __init__(me, p, wdseq):
     me.p = p
     me.wdseq = wdseq
@@ -45,17 +45,17 @@ class QfConvert (object):
     else:
       seq = map(int, arg.split(','))
     print ";; piece widths = %r" % seq
-    return QfConvert(p, seq)
+    return cls(p, seq)
   def hack(me, n):
-    if 2*n >= me.p: n -= p
+    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 d >= lim/2: d -= lim; n += 1
-      nn.append(str(d))
+      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
@@ -65,13 +65,23 @@ class QfConvert (object):
     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': QfConvert,
-            'unqf': QfConvert }
+            '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