<commit_before>import idaapi
import idc
import string
from . import exceptions


def get_func(func_ea):
    if isinstance(func_ea, idaapi.func_t):
        return func_ea
    func = idaapi.get_func(func_ea)
    if func is None:
        raise exceptions.SarkNoFunction("No function at 0x{:08X}".format(func_ea))

    return func


def get_ea(func_ea):
    if isinstance(func_ea, idaapi.func_t):
        return func_ea.startEA
    return func_ea


def is_string_printable(string_):
    return all(char in string.printable for char in string_)


def string_to_query(string_):
    if is_string_printable(string_):
        return '"{}"'.format(string_)

    return " ".join(char.encode("hex") for char in string_)


def iter_find_string(query, start=None, end=None, down=True):
    query = string_to_query(query)
    return iter_find_query(query, start, end, down)


def iter_find_query(query, start=None, end=None, down=True):
    start, end = fix_addresses(start, end)

    if down:
        direction = idc.SEARCH_DOWN
    else:
        direction = idc.SEARCH_UP

    current = idc.FindBinary(start, direction, query)
    while current < end:
        yield current
        current = idc.FindBinary(current + 1, direction, query)


def fix_addresses(start=None, end=None):
    if start in (None, idaapi.BADADDR):
        start = idaapi.cvar.inf.minEA

    if end in (None, idaapi.BADADDR):
        end = idaapi.cvar.inf.maxEA

    return start, end


def set_name(address, name, anyway=False):
    success = idaapi.set_name(address, name, idaapi.SN_NOWARN | idaapi.SN_NOCHECK)
    if success:
        return

    if anyway:
        success = idaapi.do_name_anyway(address, name)
        if success:
            return

        raise exceptions.SarkSetNameFailed("Failed renaming 0x{:08X} to {!r}.".format(address, name))

    raise exceptions.SarkErrorNameAlreadyExists(
        "Can't rename 0x{:08X}. Name {!r} already exists.".format(address, name))


<commit_msg>Docs.<commit_after>import idaapi
import idc
import string
from . import exceptions


def get_func(func_ea):
    """get_func(func_t or ea) -> func_t

    Take an IDA function (`idaapi.func_t`) or an address (EA) and return
    an IDA function object.

    Use this when APIs can take either a function or an address.

    :param func_ea: `idaapi.func_t` or ea of the function.
    :return: `idaapi.func_t`
    """
    if isinstance(func_ea, idaapi.func_t):
        return func_ea
    func = idaapi.get_func(func_ea)
    if func is None:
        raise exceptions.SarkNoFunction("No function at 0x{:08X}".format(func_ea))

    return func


def get_ea(func_ea):
    """get_ea(func_t or ea) -> ea

    Same as `get_func`, but returns the EA.

    :param func_ea: `idaapi.func_t` or EA.
    :return: The ea.
    """
    if isinstance(func_ea, idaapi.func_t):
        return func_ea.startEA
    return func_ea


def is_string_printable(string_):
    """Check if a string is printable"""
    return all(char in string.printable for char in string_)


def string_to_query(string_):
    if is_string_printable(string_):
        return '"{}"'.format(string_)

    return " ".join(char.encode("hex") for char in string_)


def iter_find_string(query, start=None, end=None, down=True):
    query = string_to_query(query)
    return iter_find_query(query, start, end, down)


def iter_find_query(query, start=None, end=None, down=True):
    start, end = fix_addresses(start, end)

    if down:
        direction = idc.SEARCH_DOWN
    else:
        direction = idc.SEARCH_UP

    current = idc.FindBinary(start, direction, query)
    while current < end:
        yield current
        current = idc.FindBinary(current + 1, direction, query)


def fix_addresses(start=None, end=None):
    if start in (None, idaapi.BADADDR):
        start = idaapi.cvar.inf.minEA

    if end in (None, idaapi.BADADDR):
        end = idaapi.cvar.inf.maxEA

    return start, end


def set_name(address, name, anyway=False):
    success = idaapi.set_name(address, name, idaapi.SN_NOWARN | idaapi.SN_NOCHECK)
    if success:
        return

    if anyway:
        success = idaapi.do_name_anyway(address, name)
        if success:
            return

        raise exceptions.SarkSetNameFailed("Failed renaming 0x{:08X} to {!r}.".format(address, name))

    raise exceptions.SarkErrorNameAlreadyExists(
        "Can't rename 0x{:08X}. Name {!r} already exists.".format(address, name))



{'fraction_non_alphanumeric': 0.10512007249660173, 'fraction_numerical': 0.004531037607612143, 'mean_word_length': 3.1611687087653157, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3568663', 'n_tokens_mistral': 1545, 'n_tokens_neox': 1480, 'n_words': 384}