获取c程序中的.h头文件定义的宏信息

一、需求:获取下面头文件中所有的宏信息

#ifndef __USR_H__
#define __USR_H__
#include <stdio.h>

#define VERSION_STRING     "2.05"
#define VERSION_STRING_LEN 32

#define SUCCESS                            0x00
#define ERR_BASE                           0x00
#define aTEST_ERR_BASE0                          0x100

# define ERR_UNKNOWN                       0x123
#define ERR_INVALID1                      (1 + aTEST_ERR_BASE0)
#define ERR_INVALID2                      ERR_BASE + 2
#define ERR_INVALID3                      ERR_BASE + 3
#define ERR_INVALID4                      4 + aTEST_ERR_BASE0
#define ERR_INVALID5                      (ERR_BASE + 5)

#define BACKUP_DIR                 "/home/test"
#define RUN_DIR                     BACKUP_DIR"/.backup"
#define BASE_CONTENT                "msgfrom"BACKUP_DIR

二、运行结果

三、具体程序(使用python)

# @Time    :   2024/4/18 13:52
# @File    :   test.py
# @Author  :   路人甲-甲
# @Version :   1.0
# @Site    :   https://blog.csdn.net/wankeng
# @Desc    :   读取c语言中的.h头文件里定义的#define宏信息,并将其存入字典all_define_dict中

import os
import re

all_define_dict = {}

# 匹配格式为#define  TEST_VALUE  “ABC”的情况
def define_value_for_char(content):
    global  all_define_dict
    m = re.match(r"([a-zA-Z0-9_]+)", content)
    if m:
        match_str = m.group(0)
        match_str_len = len(match_str)
        content = content[match_str_len:]
        #去掉前面的空格
        content = content.replace(" ", "").replace("\t","").replace("\n","")
        # 匹配格式为#define  TEST_VALUE  “ABC”的情况
        if content.startswith("\"") and content.endswith("\""):
            m = re.search(r"[a-zA-Z0-9_/.]+", content)
            if m:
                return match_str, str(m.group(0))
        elif content.startswith("\"") and not content.endswith("\""):
            # 匹配格式为#define  TEST_VALUE  “ABC"/BASE_TEST_CHAR
            m = re.search(r"[a-zA-Z0-9_/.]+", content)
            if m:
                before_str_len = len(m.group(0))
                before_str = m.group(0)
                var_name = content[before_str_len + 2:].strip()
                if var_name in all_define_dict:
                    var_value = all_define_dict.get(var_name, None)
                    if var_value is not None:
                        return match_str, before_str +  var_value
        elif (not content.startswith("\"")) and content.endswith("\""):
            # 匹配格式为#define  TEST_VALUE  BASE_TEST_CHAR“/test"
            m = re.search(r"[a-zA-Z0-9_/.]+", content)
            if m:
                var_name_str_len = len(m.group(0))
                var_name = m.group(0)
                after_str = content[var_name_str_len + 1: -1].strip()
                if var_name in all_define_dict:
                    var_value = all_define_dict.get(var_name, None)
                    if var_value is not None:
                        return match_str, var_value + after_str
    return None, None


#匹配格式为#define  TEST_VALUE  (1 + TEST_VALUE)的情况
#匹配格式为#define  TEST_VALUE  (TEST_VALUE + 1)的情况
#匹配格式为TEST_VALUE + 1 没有括号的情况
def define_value_for_int_calculate(content):
    global all_define_dict
    m = re.match(r"([a-zA-Z0-9_]+)", content)
    if m:
        match_str = m.group(0)
        match_str_len = len(match_str)
        content = content[match_str_len:]

        m = re.match(r"\s+(\([a-zA-Z0-9_])", content)
        if m:
            sub_match_len = len(m.group(0))
            #去掉括号和换行符
            temp_value = content[sub_match_len - 1: -2]

            sub_m = re.match(r"\w+", temp_value)
            before_var_value = None
            final_int_value = None
            if sub_m:
                # 匹配格式为(TEST_VALUE + 1)的情况
                before_var_name = sub_m.group(0)
                before_var_value = all_define_dict.get(before_var_name, None)
                if before_var_value is None:
                # 匹配格式为(1 + TEST_VALUE)的情况
                    sub_m = re.match(r"(\d)+\s+", temp_value)
                    if sub_m:
                        sub_match_len = len(sub_m.group(0))
                        sub_content = temp_value[sub_match_len:]
                        search_m = re.search(r"(\w+)", sub_content)
                        if search_m:
                            before_var_name = search_m.group(0)
                            before_var_value = all_define_dict.get(before_var_name, None)
                if before_var_value is not None:
                    #计算(TEST_VALUE+1)的值
                    final_int_value = eval(temp_value.replace(before_var_name, str(before_var_value)))
            # print(f'{match_str}={final_int_value}={temp_value}={before_var_value}=end')
            if final_int_value is not None:
                return match_str, final_int_value
        else:
            #匹配格式为TEST_VALUE + 1 没有括号的情况
            before_var_value = None
            final_int_value = None
            m = re.search(r"[a-zA-Z0-9_]+", content)
            if m:
                sub_match_len = len(m.group(0))
                #去掉括号和换行符
                temp_value = content[sub_match_len -2: -1]
                if temp_value.startswith("\"") or temp_value.endswith("\""):
                    return None, None
                before_var_name = m.group(0)
                before_var_value = all_define_dict.get(before_var_name, None)
                if before_var_value is not None:
                    #计算TEST_VALUE + 1的值
                    final_int_value = eval(temp_value.replace(before_var_name, str(before_var_value)))
                # print(f'{match_str}={final_int_value}={temp_value}={before_var_value}=end')
                if final_int_value is not None:
                    return match_str, final_int_value
    return None, None

# 匹配格式为#define  TEST_VALUE  1的情况
# 匹配格式为#define  TEST_VALUE  1 + BEFORE_TEST_VALUE
def define_value_for_int(content):
    global all_define_dict
    m = re.match(r"([a-zA-Z0-9_]+)", content)
    if m:
        match_str = m.group(0)
        match_str_len = len(match_str)
        content = content[match_str_len:]
        m = re.match(r"\s+(\d)", content)
        # print(f'---{match_str}={m}={content}={match_str_len}=end')
        if m:
            sub_match_len = len(m.group(0))
            value_contents = content[sub_match_len - 1: -1]
            has_space_or_char = re.search(r"[a-zA-Z_]+", value_contents)
            if has_space_or_char:
                # 匹配格式为#define  TEST_VALUE  1 + BEFORE_TEST_VALUE
                before_var_name = value_contents[len(value_contents) - len(has_space_or_char.group(0)) - 1:]
                # 去掉有可能的空格
                before_var_name = before_var_name.strip()
                if before_var_name in all_define_dict:
                    before_var_value = all_define_dict.get(before_var_name, None)
                    if before_var_value is not None:
                        # 计算1 + BEFORE_TEST_VALUE的值
                        final_int_value = eval(value_contents.replace(before_var_name, str(before_var_value)))
                        if final_int_value is not None:
                            return match_str, final_int_value
            else:
                # 匹配格式为#define  TEST_VALUE  1 单纯的数字
                final_int_value = int(content[sub_match_len - 1: -1])
                if final_int_value is not None:
                    return match_str, final_int_value
    return None, None

# 匹配格式为#define  TEST_VALUE  0x1的情况
def define_value_for_hex(content):
    m = re.match(r"([a-zA-Z0-9_]+)", content)
    if m:
        match_str = m.group(0)
        match_str_len = len(match_str)
        content = content[match_str_len:]
        m = re.match(r"\s+0x", content)
        if m:
            sub_match_len = len(m.group(0))
            dist_value_to_int = int(content[sub_match_len:sub_match_len + 8], 16)
            if dist_value_to_int is not None and len(match_str) > 0:
                return match_str, dist_value_to_int
    return None, None

def get_define_dict(org_content):
    key = None
    value = None
    m = re.match(r"(#define\s+|# define\s+)", org_content)
    if m:
        x = m.group(0)
        s = len(x)
        line = org_content[s:]
        key, value = define_value_for_hex(line)
        if key is None and value is None:
            # 单纯的数字
            key, value = define_value_for_int(line)
        if key is None and value is None:
            # 带有运算符的数字
            key, value = define_value_for_int_calculate(line)
        if key is None and value is None:
            # 字符串
            key, value = define_value_for_char(line)
    return key, value

def loadFromC(fn):
    global all_define_dict
    with open(fn, "r",encoding='utf-8') as reg_file:
        for line in reg_file.readlines():
            if line is None or len(line) == 0 or line.startswith("\n") or line.startswith("\r\n" or line.startswith("^M")):
                continue
            key,value = get_define_dict(line)
            if key is not None and value is not None:
                all_define_dict[key] = value
        reg_file.close()
    return all_define_dict


fn = "./test.h"
ret_dict = loadFromC(fn)
print(len(ret_dict))
for k, v in ret_dict.items():
    print(k, v)

四、后续

我们可以思考,根据上面的方法,可以获取此.h文件里定义的方法、结构体、枚举类等信息。我们可以将此信息拿到之后测试这些方法。具体实现方式请私信。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值