Prepare a capstone disassembler instance for a given target and syntax.

    Args:
        syntax(AsmSyntax): The assembler syntax (Intel or AT&T).
        target(~pwnypack.target.Target): The target to create a disassembler
            instance for. The global target is used if this argument is
            ``None``.

    Returns:
        An instance of the capstone disassembler.

    Raises:
        NotImplementedError: If the specified target isn't supported.

def prepare_capstone(syntax=AsmSyntax.att, target=None):
    """
    Prepare a capstone disassembler instance for a given target and syntax.

    Args:
        syntax(AsmSyntax): The assembler syntax (Intel or AT&T).
        target(~pwnypack.target.Target): The target to create a disassembler
            instance for. The global target is used if this argument is
            ``None``.

    Returns:
        An instance of the capstone disassembler.

    Raises:
        NotImplementedError: If the specified target isn't supported.
    """

    if not HAVE_CAPSTONE:
        raise NotImplementedError('pwnypack requires capstone to disassemble to AT&T and Intel syntax')

    if target is None:
        target = pwnypack.target.target

    if target.arch == pwnypack.target.Target.Arch.x86:
        if target.bits is pwnypack.target.Target.Bits.bits_32:
            md = capstone.Cs(capstone.CS_ARCH_X86, capstone.CS_MODE_32)
        else:
            md = capstone.Cs(capstone.CS_ARCH_X86, capstone.CS_MODE_64)
    elif target.arch == pwnypack.target.Target.Arch.arm:
        mode = 0

        if target.bits is pwnypack.target.Target.Bits.bits_32:
            arch = capstone.CS_ARCH_ARM

            if target.mode and pwnypack.target.Target.Mode.arm_thumb:
                mode = capstone.CS_MODE_THUMB
            else:
                mode = capstone.CS_MODE_ARM
                if target.mode and pwnypack.target.Target.Mode.arm_m_class:
                    mode |= capstone.CS_MODE_MCLASS

            if target.mode and pwnypack.target.Target.Mode.arm_v8:
                mode |= capstone.CS_MODE_V8
        else:
            arch = capstone.CS_ARCH_ARM64

        if target.endian is pwnypack.target.Target.Endian.little:
            mode |= capstone.CS_MODE_LITTLE_ENDIAN
        else:
            mode |= capstone.CS_MODE_BIG_ENDIAN

        md = capstone.Cs(arch, mode)
    else:
        raise NotImplementedError('Only x86 is currently supported.')

    md.skipdata = True

    if syntax is AsmSyntax.att:
        md.syntax = capstone.CS_OPT_SYNTAX_ATT
    elif syntax is AsmSyntax.intel:
        md.skipdata_setup(('db', None, None))
    else:
        raise NotImplementedError('capstone engine only implements AT&T and Intel syntax.')

    return md