直接移动+改调用方模式:35 个函数按功能移至 5 个子模块,主文件 仅保留常量与全局变量(main.vp 仍直接赋值 StubMerger._mbuddy)。 - 子模块函数体内裸调用映射为子模块前缀,全局变量经 StubMerger._xxx 跨模块访问 - 12 个调用方文件 StubMerger.func( → 对应子模块前缀并补 import - 全 App 语法/引用/import 验证通过
410 lines
20 KiB
Plaintext
410 lines
20 KiB
Plaintext
import t, c
|
||
from stdint import *
|
||
import memhub
|
||
import string
|
||
import stdlib
|
||
import llvmlite
|
||
import w32.win32file as win32file
|
||
import w32.win32base as win32base
|
||
import w32.fileio as fileio
|
||
import viperlib
|
||
import sys
|
||
import ast
|
||
import lib.core.VLogger as VLogger
|
||
import lib.core.IncludesScanner as IncludesScanner
|
||
import lib.core.Handles.HandlesStruct as HandlesStruct
|
||
import lib.core.Handles.HandlesImports as HandlesImports
|
||
import lib.core.Handles.HandlesTranslator as HandlesTranslator
|
||
import lib.core.BuildPipeline as BuildPipeline
|
||
import lib.StubGen.VpiReader as VpiReader
|
||
import lib.Projectrans.Utils as Utils
|
||
import lib.Projectrans.Config as Config
|
||
|
||
|
||
import lib.core.StubMergerCollect as StubMergerCollect
|
||
import lib.core.StubMergerTopo as StubMergerTopo
|
||
import lib.core.StubMergerIR as StubMergerIR
|
||
import lib.core.StubMergerBuild as StubMergerBuild
|
||
import lib.core.StubMerger as StubMerger
|
||
|
||
# ============================================================
|
||
# StubMergerStore - StubMerger 拆分(阶段 E):StubMergerStore
|
||
#
|
||
# 直接移动模式:函数实现迁至此模块,原 StubMerger.vp 仅保留
|
||
# 常量/全局变量;调用方经本模块前缀访问。全局变量跨模块经
|
||
# StubMerger._xxx 访问(main.vp 先例)。
|
||
# ============================================================
|
||
|
||
# ============================================================
|
||
# PopulateSha1MapStore - 从扫描结果填充全局 SHA1 映射存储器
|
||
#
|
||
# 遍历 ScanResult.Entries,为每个条目构建 sha1→module_name 映射。
|
||
# 模块名通过 _PathToModuleName(includes/rel_path) 计算。
|
||
# 内存用 stdlib.malloc 分配(全局存储器,不随 mbuddy 释放)。
|
||
#
|
||
# Args:
|
||
# scan_result: IncludesScanner 扫描结果
|
||
#
|
||
# Returns:
|
||
# 填充的条目数,-1 表示失败
|
||
# ============================================================
|
||
def PopulateSha1MapStore(scan_result: IncludesScanner.ScanResult | t.CPtr) -> int:
|
||
"""从扫描结果填充全局 SHA1 映射存储器
|
||
|
||
遍历 ScanResult.Entries,为每个条目构建 sha1→module_name 映射。
|
||
模块名通过 _PathToModuleName(includes/rel_path) 计算。
|
||
内存用 stdlib.malloc 分配(全局存储器,不随 mbuddy 释放)。
|
||
"""
|
||
if scan_result is None:
|
||
return -1
|
||
# 释放旧存储器
|
||
if StubMerger._sha1_store_arr is not None:
|
||
stdlib.free(StubMerger._sha1_store_arr)
|
||
if StubMerger._sha1_store_mod is not None:
|
||
stdlib.free(StubMerger._sha1_store_mod)
|
||
if StubMerger._sha1_store_rel is not None:
|
||
stdlib.free(StubMerger._sha1_store_rel)
|
||
if StubMerger._sha1_store_incdir is not None:
|
||
stdlib.free(StubMerger._sha1_store_incdir)
|
||
StubMerger._sha1_store_arr = stdlib.malloc(MAX_INCLUDES * 17)
|
||
StubMerger._sha1_store_mod = stdlib.malloc(MAX_INCLUDES * 64)
|
||
StubMerger._sha1_store_rel = stdlib.malloc(MAX_INCLUDES * MAX_REL_PATH_LEN)
|
||
StubMerger._sha1_store_incdir = stdlib.malloc(MAX_INCLUDES * MAX_INC_DIR_LEN)
|
||
if StubMerger._sha1_store_arr is None or StubMerger._sha1_store_mod is None or StubMerger._sha1_store_rel is None or StubMerger._sha1_store_incdir is None:
|
||
return -1
|
||
string.memset(StubMerger._sha1_store_arr, 0, MAX_INCLUDES * 17)
|
||
string.memset(StubMerger._sha1_store_mod, 0, MAX_INCLUDES * 64)
|
||
string.memset(StubMerger._sha1_store_rel, 0, MAX_INCLUDES * MAX_REL_PATH_LEN)
|
||
string.memset(StubMerger._sha1_store_incdir, 0, MAX_INCLUDES * MAX_INC_DIR_LEN)
|
||
StubMerger._sha1_store_count = 0
|
||
p_bad: int = 0
|
||
entry_size_p: t.CSizeT = IncludesScanner.FileEntry.__sizeof__()
|
||
for i in range(scan_result.Count):
|
||
if StubMerger._sha1_store_count >= MAX_INCLUDES:
|
||
VLogger.error("includes SHA1 存储超上限,终止", "StubMerger")
|
||
ea: t.CUInt64T = t.CUInt64T(scan_result.Entries) + i * entry_size_p
|
||
ent: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(t.CVoid(ea, t.CPtr))
|
||
if ent is None or ent.Sha1 is None or ent.RelPath is None:
|
||
p_bad += 1
|
||
continue
|
||
# 构建完整路径 includes/{RelPath}(_PathToModuleName 需要)
|
||
rp_len: t.CSizeT = string.strlen(ent.RelPath)
|
||
full_path_buf: bytes = stdlib.malloc(rp_len + 10)
|
||
if full_path_buf is None:
|
||
p_bad += 1
|
||
continue
|
||
viperlib.snprintf(full_path_buf, rp_len + 10, "includes/%s", ent.RelPath)
|
||
mod_name: str = Utils.PathToModuleName(full_path_buf, 1)
|
||
stdlib.free(full_path_buf)
|
||
if mod_name is not None:
|
||
idx: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * 17
|
||
string.strcpy(StubMerger._sha1_store_arr + idx, ent.Sha1)
|
||
idx2: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * 64
|
||
mn_len: t.CSizeT = string.strlen(mod_name)
|
||
if mn_len < 64:
|
||
string.strcpy(StubMerger._sha1_store_mod + idx2, mod_name)
|
||
else:
|
||
string.strncpy(StubMerger._sha1_store_mod + idx2, mod_name, 63)
|
||
StubMerger._sha1_store_mod[idx2 + 63] = '\0'
|
||
stdlib.free(mod_name)
|
||
# 保存 rel_path(供 Phase2 3.5 编译缺失 includes 使用)
|
||
idx3: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * MAX_REL_PATH_LEN
|
||
if rp_len < MAX_REL_PATH_LEN:
|
||
string.strcpy(StubMerger._sha1_store_rel + idx3, ent.RelPath)
|
||
else:
|
||
string.strncpy(StubMerger._sha1_store_rel + idx3, ent.RelPath, MAX_REL_PATH_LEN - 1)
|
||
StubMerger._sha1_store_rel[idx3 + MAX_REL_PATH_LEN - 1] = '\0'
|
||
# 保存所属 includes 根目录(Phase2 预注册/按需编译拼路径用)
|
||
idx_inc: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * MAX_INC_DIR_LEN
|
||
if ent.IncDir is not None:
|
||
icd_len: t.CSizeT = string.strlen(ent.IncDir)
|
||
if icd_len < MAX_INC_DIR_LEN:
|
||
string.strcpy(StubMerger._sha1_store_incdir + idx_inc, ent.IncDir)
|
||
else:
|
||
string.strncpy(StubMerger._sha1_store_incdir + idx_inc, ent.IncDir, MAX_INC_DIR_LEN - 1)
|
||
StubMerger._sha1_store_incdir[idx_inc + MAX_INC_DIR_LEN - 1] = '\0'
|
||
StubMerger._sha1_store_count += 1
|
||
if p_bad > 0:
|
||
fb_pbad: str = VLogger.fmt_buf()
|
||
if fb_pbad is not None:
|
||
viperlib.snprintf(fb_pbad, 1024, "includes SHA1 存储有 %d 个条目失败", p_bad)
|
||
VLogger.error(fb_pbad, "StubMerger")
|
||
return StubMerger._sha1_store_count
|
||
# ============================================================
|
||
# AppendToSha1MapStore - 追加条目到全局 SHA1 映射存储器
|
||
#
|
||
# Phase1 调用 PopulateSha1MapStore 填充 includes 文件,
|
||
# Phase2 扫描 App 源文件后调用此函数追加 App 模块条目,
|
||
# 确保编译 App 自身时跨模块 CDefine 查找能命中 App 模块
|
||
# (如 StubMerger.MAX_INCLUDES 在编译 Phase2 时通过
|
||
# _build_source_path_from_sha1 查找 StubMerger 的源路径)。
|
||
#
|
||
# 若存储器未初始化(PopulateSha1MapStore 未调用),自动初始化。
|
||
# 若 SHA1 已存在(去重),跳过。
|
||
#
|
||
# Args:
|
||
# sha1: SHA1 字符串(16 字符 + null)
|
||
# rel_path: 相对路径(如 "lib/core/StubMerger.vp",
|
||
# 不含 includes/ 前缀,与 _sha1_map.txt 格式一致)
|
||
#
|
||
# Returns:
|
||
# 0 成功(含去重跳过),1 失败
|
||
# ============================================================
|
||
def AppendToSha1MapStore(sha1: str, rel_path: str) -> int:
|
||
"""追加条目到全局 SHA1 映射存储器(Phase2 用)"""
|
||
if sha1 is None or rel_path is None:
|
||
return 1
|
||
# 存储器未初始化:自动初始化(Phase2 可能先于 Phase1 调用)
|
||
if StubMerger._sha1_store_arr is None:
|
||
StubMerger._sha1_store_arr = stdlib.malloc(MAX_INCLUDES * 17)
|
||
StubMerger._sha1_store_mod = stdlib.malloc(MAX_INCLUDES * 64)
|
||
StubMerger._sha1_store_rel = stdlib.malloc(MAX_INCLUDES * MAX_REL_PATH_LEN)
|
||
StubMerger._sha1_store_incdir = stdlib.malloc(MAX_INCLUDES * MAX_INC_DIR_LEN)
|
||
if StubMerger._sha1_store_arr is None or StubMerger._sha1_store_mod is None or StubMerger._sha1_store_rel is None or StubMerger._sha1_store_incdir is None:
|
||
return 1
|
||
string.memset(StubMerger._sha1_store_arr, 0, MAX_INCLUDES * 17)
|
||
string.memset(StubMerger._sha1_store_mod, 0, MAX_INCLUDES * 64)
|
||
string.memset(StubMerger._sha1_store_rel, 0, MAX_INCLUDES * MAX_REL_PATH_LEN)
|
||
string.memset(StubMerger._sha1_store_incdir, 0, MAX_INCLUDES * MAX_INC_DIR_LEN)
|
||
StubMerger._sha1_store_count = 0
|
||
if StubMerger._sha1_store_count >= MAX_INCLUDES:
|
||
return 1
|
||
# 去重:若 SHA1 已存在则跳过
|
||
for i in range(StubMerger._sha1_store_count):
|
||
sidx_d: t.CSizeT = t.CSizeT(i) * 17
|
||
if string.strcmp(StubMerger._sha1_store_arr + sidx_d, sha1) == 0:
|
||
return 0
|
||
# 模块名:rel_path "lib/core/StubMerger.vp" → "lib.core.StubMerger"
|
||
full_path_buf: bytes = stdlib.malloc(string.strlen(rel_path) + 10)
|
||
if full_path_buf is None:
|
||
return 1
|
||
viperlib.snprintf(full_path_buf, string.strlen(rel_path) + 10, "includes/%s", rel_path)
|
||
mod_name: str = Utils.PathToModuleName(full_path_buf, 1)
|
||
stdlib.free(full_path_buf)
|
||
if mod_name is None:
|
||
return 1
|
||
# 写入 SHA1
|
||
idx_a: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * 17
|
||
string.strcpy(StubMerger._sha1_store_arr + idx_a, sha1)
|
||
# 写入模块名
|
||
idx_m: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * 64
|
||
mn_len: t.CSizeT = string.strlen(mod_name)
|
||
if mn_len < 64:
|
||
string.strcpy(StubMerger._sha1_store_mod + idx_m, mod_name)
|
||
else:
|
||
string.strncpy(StubMerger._sha1_store_mod + idx_m, mod_name, 63)
|
||
StubMerger._sha1_store_mod[idx_m + 63] = '\0'
|
||
stdlib.free(mod_name)
|
||
# 写入相对路径
|
||
idx_r: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * MAX_REL_PATH_LEN
|
||
rp_len: t.CSizeT = string.strlen(rel_path)
|
||
if rp_len < MAX_REL_PATH_LEN:
|
||
string.strcpy(StubMerger._sha1_store_rel + idx_r, rel_path)
|
||
else:
|
||
string.strncpy(StubMerger._sha1_store_rel + idx_r, rel_path, MAX_REL_PATH_LEN - 1)
|
||
StubMerger._sha1_store_rel[idx_r + MAX_REL_PATH_LEN - 1] = '\0'
|
||
# App 源文件不属于任何 includes 目录:IncDir 留空(Phase2 回退 includes_dir 参数)
|
||
idx_inc_a: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * MAX_INC_DIR_LEN
|
||
StubMerger._sha1_store_incdir[idx_inc_a] = '\0'
|
||
StubMerger._sha1_store_count += 1
|
||
return 0
|
||
# ============================================================
|
||
# GetSha1StoreCount - 获取全局存储器条目数
|
||
# ============================================================
|
||
def GetSha1StoreCount() -> int:
|
||
"""返回全局 SHA1 存储器的条目数"""
|
||
return StubMerger._sha1_store_count
|
||
# ============================================================
|
||
# LookupSha1ByModName - 从模块名查找 SHA1(直接查全局存储器)
|
||
#
|
||
# 精确匹配失败时,尝试 "{mod_name}.__init__" 回退,
|
||
# 支持 import ast(包)→ ast.__init__ 的 SHA1 查找。
|
||
#
|
||
# Returns:
|
||
# SHA1 字符串指针(指向全局存储器内部,无需释放),None 未找到
|
||
# ============================================================
|
||
def LookupSha1ByModName(mod_name: str) -> str:
|
||
"""从模块名查找 SHA1(精确匹配 + 包名回退),委托通用实现 _FindSha1ByModName"""
|
||
return StubMergerIR._FindSha1ByModName(StubMerger._sha1_store_arr, StubMerger._sha1_store_mod, StubMerger._sha1_store_count, mod_name)
|
||
# ============================================================
|
||
# LookupSha1ByModNameSuffix - 后缀匹配查找模块 SHA1
|
||
#
|
||
# 用于 from .X import Y 的相对导入:impf.module 是 ".X"(带前导点),
|
||
# 去掉前导点后为 "X",SHA1 映射表中键是 "pkg.X",需要后缀匹配。
|
||
# 包含三种匹配方式:精确、后缀、反向后缀。
|
||
#
|
||
# Returns:
|
||
# SHA1 字符串指针(指向全局存储器内部,无需释放),None 未找到
|
||
# ============================================================
|
||
def LookupSha1ByModNameSuffix(mod_suffix: str) -> str:
|
||
"""后缀匹配查找模块 SHA1"""
|
||
if mod_suffix is None:
|
||
return None
|
||
if StubMerger._sha1_store_arr is None or StubMerger._sha1_store_mod is None:
|
||
return None
|
||
if StubMerger._sha1_store_count <= 0:
|
||
return None
|
||
suffix_len_sf: t.CSizeT = string.strlen(mod_suffix)
|
||
if suffix_len_sf == 0:
|
||
return None
|
||
i_sf: int
|
||
for i_sf in range(StubMerger._sha1_store_count):
|
||
idx_sf: t.CSizeT = t.CSizeT(i_sf) * 64
|
||
mod_name_sf: str = StubMerger._sha1_store_mod + idx_sf
|
||
mod_len_sf: t.CSizeT = string.strlen(mod_name_sf)
|
||
if mod_len_sf == 0:
|
||
continue
|
||
# 精确匹配
|
||
if mod_len_sf == suffix_len_sf:
|
||
if string.strcmp(mod_name_sf, mod_suffix) == 0:
|
||
sidx_sf: t.CSizeT = t.CSizeT(i_sf) * 17
|
||
return StubMerger._sha1_store_arr + sidx_sf
|
||
# 后缀匹配:mod_name 以 "." + mod_suffix 结尾
|
||
if mod_len_sf > suffix_len_sf:
|
||
if mod_name_sf[mod_len_sf - suffix_len_sf - 1] == '.':
|
||
cmp_start_sf: str = mod_name_sf + mod_len_sf - suffix_len_sf
|
||
if string.strcmp(cmp_start_sf, mod_suffix) == 0:
|
||
sidx2_sf: t.CSizeT = t.CSizeT(i_sf) * 17
|
||
return StubMerger._sha1_store_arr + sidx2_sf
|
||
# 反向后缀匹配:mod_suffix 以 "." + mod_name 结尾
|
||
if suffix_len_sf > mod_len_sf:
|
||
if mod_suffix[suffix_len_sf - mod_len_sf - 1] == '.':
|
||
cmp_start_rev_sf: str = mod_suffix + suffix_len_sf - mod_len_sf
|
||
if string.strcmp(cmp_start_rev_sf, mod_name_sf) == 0:
|
||
sidx_rev_sf: t.CSizeT = t.CSizeT(i_sf) * 17
|
||
return StubMerger._sha1_store_arr + sidx_rev_sf
|
||
return None
|
||
# ============================================================
|
||
# PopulateIncludesDeps - 将 includes 文件的依赖存入内存
|
||
#
|
||
# Phase B+ 前用 declare_only 翻译 includes 文件,提取 _imported_modules
|
||
# 后调用此函数存入内存。_BuildReachableSha1Set 从内存读取,不读 deps.txt。
|
||
#
|
||
# Args:
|
||
# sha1: includes 文件的 SHA1(16字符)
|
||
# deps_str: 依赖模块名字符串(空格分隔,如 "t c stdint string")
|
||
#
|
||
# Returns:
|
||
# 0 成功,非 0 失败
|
||
# ============================================================
|
||
def PopulateIncludesDeps(sha1: str, deps_str: str) -> int:
|
||
"""将 includes 文件的依赖存入内存"""
|
||
if sha1 is None:
|
||
return 1
|
||
# 延迟初始化
|
||
if StubMerger._includes_deps_sha1 is None:
|
||
StubMerger._includes_deps_sha1 = stdlib.malloc(MAX_INCLUDES * 17)
|
||
StubMerger._includes_deps_str = stdlib.malloc(MAX_INCLUDES * MAX_DEPS_STR_LEN)
|
||
if StubMerger._includes_deps_sha1 is None or StubMerger._includes_deps_str is None:
|
||
return 1
|
||
string.memset(StubMerger._includes_deps_sha1, 0, MAX_INCLUDES * 17)
|
||
string.memset(StubMerger._includes_deps_str, 0, MAX_INCLUDES * MAX_DEPS_STR_LEN)
|
||
StubMerger._includes_deps_count = 0
|
||
if StubMerger._includes_deps_count >= MAX_INCLUDES:
|
||
return 1
|
||
# 去重:若 SHA1 已存在则跳过
|
||
for i in range(StubMerger._includes_deps_count):
|
||
sidx: t.CSizeT = t.CSizeT(i) * 17
|
||
if string.strcmp(StubMerger._includes_deps_sha1 + sidx, sha1) == 0:
|
||
return 0
|
||
# 写入 SHA1
|
||
idx: t.CSizeT = t.CSizeT(StubMerger._includes_deps_count) * 17
|
||
string.strcpy(StubMerger._includes_deps_sha1 + idx, sha1)
|
||
# 写入依赖字符串
|
||
idx2: t.CSizeT = t.CSizeT(StubMerger._includes_deps_count) * MAX_DEPS_STR_LEN
|
||
if deps_str is not None:
|
||
dl: t.CSizeT = string.strlen(deps_str)
|
||
if dl < MAX_DEPS_STR_LEN:
|
||
string.strcpy(StubMerger._includes_deps_str + idx2, deps_str)
|
||
else:
|
||
string.strncpy(StubMerger._includes_deps_str + idx2, deps_str, MAX_DEPS_STR_LEN - 1)
|
||
else:
|
||
StubMerger._includes_deps_str[idx2] = '\0'
|
||
StubMerger._includes_deps_count = StubMerger._includes_deps_count + 1
|
||
return 0
|
||
# ============================================================
|
||
# LookupIncludesDeps - 从内存查找 includes 文件的依赖
|
||
#
|
||
# Args:
|
||
# sha1: includes 文件的 SHA1(16字符)
|
||
#
|
||
# Returns:
|
||
# 依赖模块名字符串指针(空格分隔),None 表示未找到
|
||
# ============================================================
|
||
def LookupIncludesDeps(sha1: str) -> str:
|
||
"""从内存查找 includes 文件的依赖"""
|
||
if sha1 is None or StubMerger._includes_deps_sha1 is None:
|
||
return None
|
||
if StubMerger._includes_deps_count <= 0:
|
||
return None
|
||
for i in range(StubMerger._includes_deps_count):
|
||
sidx: t.CSizeT = t.CSizeT(i) * 17
|
||
if string.strcmp(StubMerger._includes_deps_sha1 + sidx, sha1) == 0:
|
||
idx2: t.CSizeT = t.CSizeT(i) * MAX_DEPS_STR_LEN
|
||
return StubMerger._includes_deps_str + idx2
|
||
return None
|
||
def GetSha1StoreArrPtr() -> bytes | t.CPtr:
|
||
"""返回 SHA1 数组指针(每个条目 17 字节)"""
|
||
return StubMerger._sha1_store_arr
|
||
def GetSha1StoreModArrPtr() -> bytes | t.CPtr:
|
||
"""返回模块名数组指针(每个条目 64 字节)"""
|
||
return StubMerger._sha1_store_mod
|
||
def GetSha1StoreRelArrPtr() -> bytes | t.CPtr:
|
||
"""返回相对路径数组指针(每个条目 MAX_REL_PATH_LEN 字节)"""
|
||
return StubMerger._sha1_store_rel
|
||
def GetSha1StoreIncdirArrPtr() -> bytes | t.CPtr:
|
||
"""返回所属 includes 根目录数组指针(每个条目 MAX_INC_DIR_LEN 字节,空串表示不属于任何 includes 目录)"""
|
||
return StubMerger._sha1_store_incdir
|
||
# ============================================================
|
||
# GetSha1StoreArr - 获取全局存储器数组指针(直接遍历用)
|
||
#
|
||
# 返回 sha1_arr、mod_arr、rel_arr 三个数组的指针和条目数。
|
||
# 调用者直接遍历数组:sha1_arr[i*17]、mod_arr[i*64]、rel_arr[i*MAX_REL_PATH_LEN]
|
||
# 内存归全局存储器所有,调用者不要 free
|
||
# ============================================================
|
||
def GetSha1StoreArr(out_sha1_arr: t.CPtr, out_mod_arr: t.CPtr, out_rel_arr: t.CPtr) -> int:
|
||
"""获取全局存储器数组指针
|
||
|
||
out_sha1_arr/out_mod_arr/out_rel_arr 是调用者提供的 t.CPtr 指针,
|
||
函数将存储器数组指针写入这些位置。
|
||
返回条目数,-1 失败
|
||
"""
|
||
if out_sha1_arr is None or out_mod_arr is None or out_rel_arr is None:
|
||
return -1
|
||
if StubMerger._sha1_store_arr is None or StubMerger._sha1_store_mod is None or StubMerger._sha1_store_rel is None:
|
||
return -1
|
||
sp: t.CPtr = (t.CPtr | t.CPtr)(t.CVoid(out_sha1_arr, t.CPtr))
|
||
if sp is not None:
|
||
sp[0] = StubMerger._sha1_store_arr
|
||
mp: t.CPtr = (t.CPtr | t.CPtr)(t.CVoid(out_mod_arr, t.CPtr))
|
||
if mp is not None:
|
||
mp[0] = StubMerger._sha1_store_mod
|
||
rp: t.CPtr = (t.CPtr | t.CPtr)(t.CVoid(out_rel_arr, t.CPtr))
|
||
if rp is not None:
|
||
rp[0] = StubMerger._sha1_store_rel
|
||
return StubMerger._sha1_store_count
|
||
# ============================================================
|
||
# LookupSha1RelPath - 通过 SHA1 查找相对路径
|
||
#
|
||
# 遍历全局存储器,返回 sha1 对应的相对路径指针(只读,不要 free)。
|
||
# 用于错误提示:将 sha1 转换为人类可读的文件路径。
|
||
#
|
||
# Args:
|
||
# sha1: SHA1 字符串(16 字符)
|
||
#
|
||
# Returns:
|
||
# 相对路径字符串指针(只读),None=未找到
|
||
# ============================================================
|
||
def LookupSha1RelPath(sha1: str) -> str:
|
||
"""通过 SHA1 查找相对路径,返回只读指针,None=未找到"""
|
||
if sha1 is None:
|
||
return None
|
||
if StubMerger._sha1_store_arr is None or StubMerger._sha1_store_rel is None:
|
||
return None
|
||
for i in range(StubMerger._sha1_store_count):
|
||
sidx: t.CSizeT = t.CSizeT(i) * 17
|
||
if string.strcmp(StubMerger._sha1_store_arr + sidx, sha1) == 0:
|
||
ridx: t.CSizeT = t.CSizeT(i) * MAX_REL_PATH_LEN
|
||
return StubMerger._sha1_store_rel + ridx
|
||
return None
|