try:
    import idc
    import idaapi
    import ida_funcs
except:
    pass

"""
# Module `ida-is`

Shortcut functions for quickly checking or manipulating an address or function's flags. 

## Flag checks

### Usage:

    if HasAnyName(0x140000000) or HasAnyName('__ImageBase') or \
            HasAnyName(ida_funcs.get_func(0x140000000)):
        # ...

    # Effectively identical to:
    #     return idc.get_full_flags(_get_ea_by_any(ea)) & idc.FF_ANYNAME != 0
     
    
#### Functions

     def HasAnyName(ea)
     def HasLabel(ea)
     def HasName(ea)
     def HasUserName(ea)
     def IsAlign(ea)
     def IsBin0(ea)
     def IsBin1(ea)
     def IsByte(ea)
     def IsChar0(ea)
     def IsChar1(ea)
     def IsChunkHead(ea)
     def IsChunkStart(ea)
     def IsCode_(ea)
     def IsData(ea)
     def IsDec0(ea)
     def IsDec1(ea)
     def IsDefarg0(ea)
     def IsDefarg1(ea)
     def IsDouble(ea)
     def IsDword(ea)
     def IsEnum0(ea)
     def IsEnum1(ea)
     def IsExtern(ea)
     def IsExtra(ea)
     def IsFloat(ea)
     def IsFlow(ea)
     
     def IsFunc_(ea)
     def IsHead(ea)
     def IsHex0(ea)
     def IsHex1(ea)
     def IsManual0(ea)
     def IsManual1(ea)
     def IsOct0(ea)
     def IsOct1(ea)
     def IsOff0(ea)
     def IsOff1(ea)
     def IsOword(ea)
     def IsPackReal(ea)
     def IsQword(ea)
     def IsRef(ea)
     def IsSeg0(ea)
     def IsSeg1(ea)
     def IsStkvar0(ea)
     def IsStkvar1(ea)
     def IsStrlit(ea)
     def IsStroff0(ea)
     def IsStroff1(ea)
     def IsStruct(ea)
     def IsTail(ea)
     def IsTbyte(ea)
     def IsUnknown(ea)
     def IsWord(ea)

## Function Flag Checking

     def IsFuncBottomBP(ea)
     def IsFuncEntry(ea)
     def IsFuncFar(ea)
     def IsFuncFrame(ea)
     def IsFuncFuzzySp(ea)
     def IsFuncHead(ea)
     def IsFuncHidden(ea)
     def IsFuncLib(ea)
     def IsFuncLumina(ea)
     def IsFuncNoRet(ea)
     def IsFuncNoRetPending(ea)
     def IsFuncPrologOk(ea)
     def IsFuncPurgedOk(ea)
     def IsFuncSpReady(ea)
     def IsFuncStart(ea)
     def IsFuncStaticDef(ea)
     def IsFuncTail(ea)
     def IsFuncThunk(ea)
     def IsFuncUserFar(ea)


## Function Flags Setting

### Usage:

    SetFuncFar(0x140000000, true), SetFuncFar('__ImageBase', true), \
            SetFuncFar(ida_funcs.get_func(0x140000000), true)

    # Effectively:
    #     def SetFuncFar(ea, v):
    #         if v:
    #             _SetFuncFlags(_get_ea_by_any(ea), lambda x: x | ida_funcs.FUNC_FAR)
    #         else:
    #             _SetFuncFlags(_get_ea_by_any(ea), lambda x: x & ida_funcs.FUNC_FAR)
     
    
#### Functions

     def SetFuncBottomBP(ea, v)
     def SetFuncFar(ea, v)
     def SetFuncFrame(ea, v)
     def SetFuncFuzzySp(ea, v)
     def SetFuncHidden(ea, v)
     def SetFuncLib(ea, v)
     def SetFuncLumina(ea, v)
     def SetFuncNoRet(ea, v)
     def SetFuncNoRetPending(ea, v)
     def SetFuncPrologOk(ea, v)
     def SetFuncPurgedOk(ea, v)
     def SetFuncSpReady(ea, v)
     def SetFuncStaticDef(ea, v)
     def SetFuncTail(ea, v)
     def SetFuncThunk(ea, v)
     def SetFuncUserFar(ea, v)

-----
Generated by *pdoc* 0.10.0 (<https://pdoc3.github.io>).
"""

try:
    import __builtin__ as builtins
    integer_types = (int, long)
    string_types = (str, unicode)
    string_type = unicode
    byte_type = str
    long_type = long
except:
    import builtins
    integer_types = (int,)
    string_types = (str, bytes)
    byte_type = bytes
    string_type = str
    long_type = int
    long = int

def _get_ea_by_any(val, d=object):
    """
    returns the address of a val (and if address is
    a number, looks up the val first).

    an easy way to accept either address or val as input.
    """

    if isinstance(val, list):
        return [_get_ea_by_any(x) for x in val]
    if isinstance(val, str):
        r = idaapi.str2ea(val)
        if r and r != idc.BADADDR:
            return r

        match = re.match(r'(sub|off|loc|byte|word|dword|qword|nullsub|locret)_([0-9A-F]+)$', val)
        if match:
            return int(match.group(2), 16)

        return 0

    if isinstance(val, idaapi.vdui_t):
        val = val.cfunc

    if val is None:
        return idc.get_screen_ea() if d == object else d

    if isinstance(val, (int, long)):
        return val

    try:
        for attr_name in ['start_ea', 'ea', 'entry_ea', 'start', 'min_ea']:
            if hasattr(val, attr_name):
                return getattr(val, attr_name)
    except AttributeError:
        pass 

    raise ValueError("Don't know how to convert {} '{}' to address".format(type(val), val))

def _GetFunc(ea=None):
    ea = _get_ea_by_any(ea)
    func = ida_funcs.get_func(ea)
    return func


def _GetFuncStart(ea=None):
    ea = _get_ea_by_any(ea)
    if isinstance(ea, list):
        return [_GetFuncStart(x) for x in ea]

    func = ida_funcs.get_func(ea)
    if not func:
        return idc.BADADDR
    return func.start_ea

def _GetFuncEnd(ea=None):
    ea = _get_ea_by_any(ea)
    func = ida_funcs.get_func(ea)
    if not func:
        return idc.BADADDR
    return func.end_ea

def _GetChunkStart(ea=None):
    ea = _get_ea_by_any(ea)
    return idc.get_fchunk_attr(ea, FUNCATTR_START)

def _SetFuncFlags(ea, callback):
    flags = idc.get_func_flags(ea)
    if flags == -1:
        return
    flags = callback(flags)
    return idc.set_func_flags(ea, flags)


def IsChunkHead(ea): return _GetFuncStart(_get_ea_by_any(ea)) != ea and _GetChunkStart(_get_ea_by_any(ea)) == ea
def IsFuncHead(ea):  return _GetFuncStart(_get_ea_by_any(ea)) == ea # idaapi.is_func(idc.get_full_flags(ea))
IsChunkStart = IsChunkHead
IsFuncStart = IsFuncHead
def IsFunc_(ea):     return idaapi.get_func(_get_ea_by_any(ea)) is not None
def IsCode_(ea):     return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_CLS) == idc.FF_CODE
def IsData(ea):      return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_CLS) == idc.FF_DATA
def IsTail(ea):      return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_CLS) == idc.FF_TAIL
def IsUnknown(ea):   return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_CLS) == idc.FF_UNK
def IsHead(ea):      return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.FF_DATA) != 0
def IsFlow(ea):      return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.FF_FLOW) != 0
def IsExtra(ea):     return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.FF_LINE) != 0
def IsRef(ea):       return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.FF_REF) != 0
def HasName(ea):     return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.FF_NAME) != 0
def HasLabel(ea):    return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.FF_LABL) != 0
def HasUserName(ea): return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.FF_ANYNAME) == idc.FF_NAME
def HasAnyName(ea):  return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.FF_ANYNAME) != 0
def IsDefarg0(ea):   return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_0TYPE) != idc.FF_0VOID
def IsDefarg1(ea):   return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_1TYPE) != idc.FF_1VOID
def IsDec0(ea):      return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_0TYPE) == idc.FF_0NUMD
def IsDec1(ea):      return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_1TYPE) == idc.FF_1NUMD
def IsHex0(ea):      return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_0TYPE) == idc.FF_0NUMH
def IsHex1(ea):      return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_1TYPE) == idc.FF_1NUMH
def IsOct0(ea):      return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_0TYPE) == idc.FF_0NUMO
def IsOct1(ea):      return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_1TYPE) == idc.FF_1NUMO
def IsBin0(ea):      return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_0TYPE) == idc.FF_0NUMB
def IsBin1(ea):      return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_1TYPE) == idc.FF_1NUMB
def IsOff0(ea):      return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_0TYPE) == idc.FF_0OFF
def IsOff1(ea):      return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_1TYPE) == idc.FF_1OFF
def IsChar0(ea):     return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_0TYPE) == idc.FF_0CHAR
def IsChar1(ea):     return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_1TYPE) == idc.FF_1CHAR
def IsSeg0(ea):      return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_0TYPE) == idc.FF_0SEG
def IsSeg1(ea):      return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_1TYPE) == idc.FF_1SEG
def IsEnum0(ea):     return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_0TYPE) == idc.FF_0ENUM
def IsEnum1(ea):     return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_1TYPE) == idc.FF_1ENUM
def IsManual0(ea):   return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_0TYPE) == idc.FF_0FOP
def IsManual1(ea):   return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_1TYPE) == idc.FF_1FOP
def IsStroff0(ea):   return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_0TYPE) == idc.FF_0STRO
def IsStroff1(ea):   return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_1TYPE) == idc.FF_1STRO
def IsStkvar0(ea):   return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_0TYPE) == idc.FF_0STK
def IsStkvar1(ea):   return (idc.get_full_flags(_get_ea_by_any(ea)) & idc.MS_1TYPE) == idc.FF_1STK
def IsByte(ea):      return idc.is_data(idc.get_full_flags(ea)) and (idc.get_full_flags(_get_ea_by_any(ea)) & idc.DT_TYPE) == idc.FF_BYTE
def IsWord(ea):      return idc.is_data(idc.get_full_flags(ea)) and (idc.get_full_flags(_get_ea_by_any(ea)) & idc.DT_TYPE) == idc.FF_WORD
def IsDword(ea):     return idc.is_data(idc.get_full_flags(ea)) and (idc.get_full_flags(_get_ea_by_any(ea)) & idc.DT_TYPE) == idc.FF_DWORD
def IsQword(ea):     return idc.is_data(idc.get_full_flags(ea)) and (idc.get_full_flags(_get_ea_by_any(ea)) & idc.DT_TYPE) == idc.FF_QWORD
def IsOword(ea):     return idc.is_data(idc.get_full_flags(ea)) and (idc.get_full_flags(_get_ea_by_any(ea)) & idc.DT_TYPE) == idc.FF_OWORD
def IsTbyte(ea):     return idc.is_data(idc.get_full_flags(ea)) and (idc.get_full_flags(_get_ea_by_any(ea)) & idc.DT_TYPE) == idc.FF_TBYTE
def IsFloat(ea):     return idc.is_data(idc.get_full_flags(ea)) and (idc.get_full_flags(_get_ea_by_any(ea)) & idc.DT_TYPE) == idc.FF_FLOAT
def IsDouble(ea):    return idc.is_data(idc.get_full_flags(ea)) and (idc.get_full_flags(_get_ea_by_any(ea)) & idc.DT_TYPE) == idc.FF_DOUBLE
def IsPackReal(ea):  return idc.is_data(idc.get_full_flags(ea)) and (idc.get_full_flags(_get_ea_by_any(ea)) & idc.DT_TYPE) == idc.FF_PACKREAL
def IsStrlit(ea):    return idc.is_data(idc.get_full_flags(ea)) and (idc.get_full_flags(_get_ea_by_any(ea)) & idc.DT_TYPE) == idc.FF_STRLIT
def IsStruct(ea):    return idc.is_data(idc.get_full_flags(ea)) and (idc.get_full_flags(_get_ea_by_any(ea)) & idc.DT_TYPE) == idc.FF_STRUCT
def IsAlign(ea):     return idc.is_data(idc.get_full_flags(ea)) and (idc.get_full_flags(_get_ea_by_any(ea)) & idc.DT_TYPE) == idc.FF_ALIGN
def IsExtern(ea):    return idc.get_full_flags(_get_ea_by_any(ea)) & 0x30505400 == 0x30505400

def IsFuncEntry(ea):  return _GetFunc(ea) and ida_funcs.is_func_entry(_GetFunc(ea))
def IsFuncTail(ea):   return _GetFunc(ea) and ida_funcs.is_func_tail(_GetFunc(ea))

def IsFuncBottomBP(ea):     return idc.get_func_flags(_get_ea_by_any(ea)) & ida_funcs.FUNC_BOTTOMBP != 0
def IsFuncFar(ea):          return idc.get_func_flags(_get_ea_by_any(ea)) & ida_funcs.FUNC_FAR != 0
def IsFuncFrame(ea):        return idc.get_func_flags(_get_ea_by_any(ea)) & ida_funcs.FUNC_FRAME != 0
def IsFuncFuzzySp(ea):      return idc.get_func_flags(_get_ea_by_any(ea)) & ida_funcs.FUNC_FUZZY_SP != 0
def IsFuncHidden(ea):       return idc.get_func_flags(_get_ea_by_any(ea)) & ida_funcs.FUNC_HIDDEN != 0
def IsFuncLib(ea):          return idc.get_func_flags(_get_ea_by_any(ea)) & ida_funcs.FUNC_LIB != 0
def IsFuncLumina(ea):       return idc.get_func_flags(_get_ea_by_any(ea)) & ida_funcs.FUNC_LUMINA != 0
def IsFuncNoRet(ea):        return idc.get_func_flags(_get_ea_by_any(ea)) & ida_funcs.FUNC_NORET != 0
def IsFuncNoRetPending(ea): return idc.get_func_flags(_get_ea_by_any(ea)) & ida_funcs.FUNC_NORET_PENDING != 0
def IsFuncPrologOk(ea):     return idc.get_func_flags(_get_ea_by_any(ea)) & ida_funcs.FUNC_PROLOG_OK != 0
def IsFuncPurgedOk(ea):     return idc.get_func_flags(_get_ea_by_any(ea)) & ida_funcs.FUNC_PURGED_OK != 0
def IsFuncSpReady(ea):      return idc.get_func_flags(_get_ea_by_any(ea)) & ida_funcs.FUNC_SP_READY != 0
def IsFuncStaticDef(ea):    return idc.get_func_flags(_get_ea_by_any(ea)) & ida_funcs.FUNC_STATICDEF != 0
#  def IsFuncTail(ea):         return idc.get_func_flags(_get_ea_by_any(ea)) & ida_funcs.FUNC_TAIL != 0
def IsFuncThunk(ea):        return idc.get_func_flags(_get_ea_by_any(ea)) & ida_funcs.FUNC_THUNK != 0
def IsFuncUserFar(ea):      return idc.get_func_flags(_get_ea_by_any(ea)) & ida_funcs.FUNC_USERFAR != 0


def SetFuncNoRet(ea, v):
    if v:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x | ida_funcs.FUNC_NORET)
    else:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x & ida_funcs.FUNC_NORET)

def SetFuncFar(ea, v):
    if v:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x | ida_funcs.FUNC_FAR)
    else:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x & ida_funcs.FUNC_FAR)

def SetFuncLib(ea, v):
    if v:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x | ida_funcs.FUNC_LIB)
    else:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x & ida_funcs.FUNC_LIB)

def SetFuncStaticDef(ea, v):
    if v:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x | ida_funcs.FUNC_STATICDEF)
    else:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x & ida_funcs.FUNC_STATICDEF)

def SetFuncFrame(ea, v):
    if v:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x | ida_funcs.FUNC_FRAME)
    else:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x & ida_funcs.FUNC_FRAME)

def SetFuncUserFar(ea, v):
    if v:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x | ida_funcs.FUNC_USERFAR)
    else:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x & ida_funcs.FUNC_USERFAR)

def SetFuncHidden(ea, v):
    if v:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x | ida_funcs.FUNC_HIDDEN)
    else:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x & ida_funcs.FUNC_HIDDEN)

def SetFuncThunk(ea, v):
    if v:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x | ida_funcs.FUNC_THUNK)
    else:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x & ida_funcs.FUNC_THUNK)

def SetFuncBottomBP(ea, v):
    if v:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x | ida_funcs.FUNC_BOTTOMBP)
    else:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x & ida_funcs.FUNC_BOTTOMBP)

def SetFuncNoRetPending(ea, v):
    if v:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x | ida_funcs.FUNC_NORET_PENDING)
    else:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x & ida_funcs.FUNC_NORET_PENDING)

def SetFuncSpReady(ea, v):
    if v:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x | ida_funcs.FUNC_SP_READY)
    else:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x & ida_funcs.FUNC_SP_READY)

def SetFuncFuzzySp(ea, v):
    if v:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x | ida_funcs.FUNC_FUZZY_SP)
    else:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x & ida_funcs.FUNC_FUZZY_SP)

def SetFuncPrologOk(ea, v):
    if v:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x | ida_funcs.FUNC_PROLOG_OK)
    else:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x & ida_funcs.FUNC_PROLOG_OK)

def SetFuncPurgedOk(ea, v):
    if v:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x | ida_funcs.FUNC_PURGED_OK)
    else:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x & ida_funcs.FUNC_PURGED_OK)

def SetFuncTail(ea, v):
    if v:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x | ida_funcs.FUNC_TAIL)
    else:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x & ida_funcs.FUNC_TAIL)

def SetFuncLumina(ea, v):
    if v:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x | ida_funcs.FUNC_LUMINA)
    else:
        _SetFuncFlags(_get_ea_by_any(ea), lambda x: x & ida_funcs.FUNC_LUMINA)
"""
Python>lib = [x for x in c if IsFuncLib(x)]
Python>for ea in lib: SetType(ea, 'int unknown(void);')
Python>for ea in lib: LabelAddressPlus(ea, '')
Python>for ea in lib: _SetFuncFlags(_get_ea_by_any(ea), lambda x: x & ~ida_funcs.FUNC_LIB)
"""
