from ctypes import (
    CDLL, c_bool, c_buffer, c_byte, c_char, c_char_p, c_double, c_float,
    c_int, c_int8, c_int16, c_int32, c_int64, c_long, c_longdouble,
    c_longlong, c_short, c_size_t, c_ubyte, c_uint, c_uint8, c_uint16,
    c_uint32, c_uint64, c_ulong, c_ulonglong, c_ushort, c_void_p, c_wchar,
    c_wchar_p, cast, create_string_buffer, get_errno, POINTER, pointer,
    set_errno, sizeof, Structure,
)

class UserFloatingPointRegisters64(Structure):
    _fields_ = [
        ('cwd', c_uint16),
        ('swd', c_uint16),
        ('fop', c_uint16),
        ('rip', c_uint64),
        ('rdp', c_uint64),
        ('mxcsr', c_uint32),
        ('mxcr_mask', c_uint32),
        ('st_space', c_uint32 * 32),
        ('xmm_space', c_uint32 * 64),
        ('padding', c_uint32 * 24),
    ]

class UserRegisters64(Structure):
    _fields_ = [
        ('r15', c_uint64),
        ('r14', c_uint64),
        ('r13', c_uint64),
        ('r12', c_uint64),
        ('rbp', c_uint64),
        ('rbx', c_uint64),
        ('r11', c_uint64),
        ('r10', c_uint64),
        ('r9', c_uint64),
        ('r8', c_uint64),
        ('rax', c_uint64),
        ('rcx', c_uint64),
        ('rdx', c_uint64),
        ('rsi', c_uint64),
        ('rdi', c_uint64),
        ('orig_rax', c_uint64),
        ('rip', c_uint64),
        ('cs', c_uint64),
        ('eflags', c_uint64),
        ('rsp', c_uint64),
        ('ss', c_uint64),
        ('fs_base', c_uint64),
        ('gs_base', c_uint64),
        ('ds', c_uint64),
        ('es', c_uint64),
        ('fs', c_uint64),
        ('gs', c_uint64),
    ]


class User64(Structure):
    _fields_ = [
        ('regs', UserRegisters64),
        ('u_fpvalid', c_int32),
        ('i387', UserFloatingPointRegisters64),
        ('u_tsize', c_uint64),
        ('u_dszie', c_uint64),
        ('u_ssize', c_uint64),
        ('start_code', c_uint64),
        ('start_stack', c_uint64),
        ('signal', c_int64),
        ('reserved', c_int32),
        ('u_ar0', POINTER(UserRegisters64)),
        ('u_fpstate', POINTER(UserFloatingPointRegisters64)),
        ('magic', c_uint64),
        ('u_comm', c_char * 32),
        ('u_debugreg', c_int64 * 8),
    ]

class UserFloatingPointRegisters32(Structure):
    _fields_ = [
        ('cwd', c_uint32),
        ('swd', c_uint32),
        ('twd', c_uint32),
        ('fip', c_uint32),
        ('fcs', c_uint32),
        ('foo', c_uint32),
        ('fos', c_uint32),
        ('st_space', c_uint32 * 20),
    ]

class UserRegisters32(Structure):
    _fields_ = [
        ('ebx', c_uint32),
        ('ecx', c_uint32),
        ('edx', c_uint32),
        ('esi', c_uint32),
        ('edi', c_uint32),
        ('ebp', c_uint32),
        ('eax', c_uint32),
        ('xds', c_uint32),
        ('xes', c_uint32),
        ('xfs', c_uint32),
        ('xgs', c_uint32),
        ('orig_eax', c_uint32),
        ('eip', c_uint32),
        ('xcs', c_uint32),
        ('eflags', c_uint32),
        ('esp', c_uint32),
        ('xss', c_uint32),
    ]

class User32(Structure):
    _fields_ = [
        ('regs', UserRegisters32),
        ('u_fpvalid', c_int),
        ('i387', UserFloatingPointRegisters32),
        ('u_tsize', c_uint32),
        ('u_dsize', c_uint32),
        ('u_ssize', c_uint32),
        ('start_code', c_uint32),
        ('start_stack', c_uint32),
        ('signal', c_int32),
        ('reserved', c_int32),
        ('u_ar0', POINTER(UserRegisters32)),
        ('u_fpstate', POINTER(UserFloatingPointRegisters32)),
        ('magic', c_uint32),
        ('u_comm', c_char * 32),
        ('u_debugreg', c_uint32 * 8),
    ]

if sizeof(c_void_p) == 4: # pragma: nocover
    UserFloatingPointRegisters = UserFloatingPointRegisters32
    UserRegisters = UserRegisters32
    User = User32
else:  # pragma: nocover
    UserFloatingPointRegisters = UserFloatingPointRegisters64
    UserRegisters = UserRegisters64
    User = User64

##  
##  Local variables:
##  tab-width: 8
##  indent-tabs-mode: nil
##  End:
##  vi: set expandtab tabstop=8
