import re
import sys
import inspect
import enum as Enum

def find_variable_name(value):
    frame = inspect.currentframe()
    try:
        for var_name, var_value in frame.f_back.f_locals.items():
            if var_value is value:
                return var_name
    finally:
        del frame


def dict_or_object_get_attr(dict_or_object, name, default_attr) :
    if dict_or_object == None or name == None:
        return default_attr
    
    if type(dict_or_object) == dict :
        if name in dict_or_object.keys():
            return dict_or_object[name]
        return default_attr
    
    return getattr(dict_or_object, name, default_attr)

def value_u64_to_s64(value) :
    svalue = value
    if (svalue >> 63) & 0x1 :
        svalue = -((svalue ^ 0xFFFFFFFFFFFFFFFF) + 1)
    return svalue

def value_u32_to_s32(value) :
    svalue = value
    if (svalue & 0x80000000) :
        svalue = -((svalue ^ 0xFFFFFFFF) + 1)
    return svalue

def value_u16_to_s16(value) :
    svalue = value
    if (svalue & 0x8000) :
        svalue = -((svalue ^ 0xFFFF) + 1)
    return svalue

'''
正则表达式
^：匹配字符串开头。
$：匹配字符串结尾。
.：匹配任意字符。
*：匹配前面的字符零次或多次。
+：匹配前面的字符一次或多次。
?：匹配前面的字符零次或一次。
[]：匹配括号中列举的任意一个字符。
[^]：匹配除了括号中列举的字符以外的任意一个字符。
()：标记一个子表达式的开始和结束位置。
\s: 包含空格
\S: 不包含空格
\d: 包含数字
\D: 不包含数字
'''
def comm_str_unpack(comm_str) :
    pattern_bit_regs  = "(\d+)\.(\d+)((\s*)#(\s*)(\d+))*"
    pattern_regs = "(\d+)((\s*)#(\s*)(\d+))*"

    reg_addr = 0
    reg_count = 0
    bit = -1

    bit_reg_result = None
    reg_result = None
    
    if comm_str == None :
        return reg_addr, bit, reg_count
    
    #[8000.2 # 3] or [8000.2]
    bit_reg_result = re.search(pattern_bit_regs, comm_str)
    if bit_reg_result :
        match_str = bit_reg_result.string
        bit_result_value = re.findall('\d+', match_str)
        item_count = len(bit_result_value)
        
        if item_count >= 2 :
            reg_addr  = int(bit_result_value[0])
            bit       = int(bit_result_value[1])
        if item_count == 3:
            reg_count = int(bit_result_value[2])
        else :
            reg_count = 1

    #[8000 # 2] or [8000]
    reg_result = None
    if bit_reg_result == None:
        reg_result = re.search(pattern_regs, comm_str)

    if reg_result != None:  
        match_str = reg_result.string
        reg_result_value = re.findall('\d+', match_str)
        item = len(reg_result_value)
        
        if item >= 1 :
            reg_addr  = int(reg_result_value[0])
    
        if item == 2 :
            reg_count = int(reg_result_value[1])
        else :
            reg_count = 1

    return reg_addr, bit, reg_count

