import pwnypack.target
import struct


__all__ = [
    'pack',
    'unpack',
    'pack_size',
    'P',
    'U',
]


def pack(format, *args, **kwargs):
    endian = kwargs.get('endian', kwargs.get('target', pwnypack.target.target).endian)
    if format and format[0] not in '@=<>!':
        if endian is pwnypack.target.Endianness.little:
            format = '<' + format
        elif endian is pwnypack.target.Endianness.big:
            format = '>' + format
        else:
            raise NotImplementedError('Unsupported endianness: %s' % endian)
    return struct.pack(format, *args)


def unpack(format, data, **kwargs):
    endian = kwargs.get('endian', kwargs.get('target', pwnypack.target.target).endian)
    if format and format[0] not in '@=<>!':
        if endian is pwnypack.target.Endianness.little:
            format = '<' + format
        elif endian is pwnypack.target.Endianness.big:
            format = '>' + format
        else:
            raise NotImplementedError('Unsupported endianness: %s' % endian)
    return struct.unpack(format, data)


def pack_size(fmt, **kwargs):
    endian = kwargs.get('endian', kwargs.get('target', pwnypack.target.target).endian)
    if fmt and fmt[0] not in '@=<>!':
        if endian is pwnypack.target.Endianness.little:
            fmt = '<' + fmt
        elif endian is pwnypack.target.Endianness.big:
            fmt = '>' + fmt
        else:
            raise NotImplementedError('Unsupported endianness: %s' % endian)
    return struct.calcsize(fmt)


def _pack_closure(f, fmt):
    return lambda a, **k: f(fmt, a, **k)

def _unpack_closure(f, fmt):
    return lambda a, **k: f(fmt, a, **k)[0]

for _w, _f in ((8, 'b'), (16, 'h'), (32, 'l'), (64, 'q')):
    locals().update({
        'p%d' % _w: _pack_closure(pack, _f),
        'P%d' % _w: _pack_closure(pack, _f.upper()),
        'u%d' % _w: _unpack_closure(unpack, _f),
        'U%d' % _w: _unpack_closure(unpack, _f.upper()),
    })
    __all__.extend([
        'p%d' % _w,
        'P%d' % _w,
        'u%d' % _w,
        'U%d' % _w,
    ])
del _w, _f, _pack_closure, _unpack_closure


def P(value, **kwargs):
    bits = kwargs.get('bits', kwargs.get('target', pwnypack.target.target).bits)
    return globals()['P%d' % bits](value, **kwargs)


def U(data, **kwargs):
    bits = kwargs.get('bits', kwargs.get('target', pwnypack.target.target).bits)
    return globals()['U%d' % bits](data, **kwargs)

@@ -101,17 +101,35 @@
 ',%0A    '
-U
+p',%0A    'U',%0A    'u
 ',%0A%5D%0A%0A%0Ad
@@ -2283,131 +2283,447 @@
 def 
-U(data, **kwargs):%0A    bits = kwargs.get('bits', kwargs.get('target', pwnypack.target.target).bits)%0A    return globals()%5B'U
+p(value, **kwargs):%0A    bits = kwargs.get('bits', kwargs.get('target', pwnypack.target.target).bits)%0A    return globals()%5B'p%25d' %25 bits%5D(value, **kwargs)%0A%0A%0Adef U(data, **kwargs):%0A    bits = kwargs.get('bits', kwargs.get('target', pwnypack.target.target).bits)%0A    return globals()%5B'U%25d' %25 bits%5D(data, **kwargs)%0A%0A%0Adef u(data, **kwargs):%0A    bits = kwargs.get('bits', kwargs.get('target', pwnypack.target.target).bits)%0A    return globals()%5B'u
 %25d' 

Add short-form unsigned pointer packing.p()/u().