提交新的建议忽略
This commit is contained in:
1 parent
8ad500c4da
commit
f8436c74d2
14 files changed
+1004
-271
No files matched your search
@@ -220,6 +220,9 @@ def _join_path(rel: str, project_dir: str) -> str:
|
||||
- ../includes + Test → Test/../includes(OS 解析为 includes)
|
||||
- 绝对路径保持不变
|
||||
- None 返回 None
|
||||
|
||||
拼接结果经 _normalize_path 规范化:./Test/../includes → ./includes,
|
||||
消除 .. 段,保证路径显示干净且相对寻址正确。
|
||||
"""
|
||||
if rel is None:
|
||||
return None
|
||||
@@ -240,7 +243,7 @@ def _join_path(rel: str, project_dir: str) -> str:
|
||||
if buf is None:
|
||||
return rel
|
||||
viperlib.snprintf(buf, total_len, "%s/%s", project_dir, rel)
|
||||
return buf
|
||||
return _normalize_path(buf)
|
||||
|
||||
# 处理 ./ 或 .\\ 前缀:拼接 project_dir + rel[2:]
|
||||
rel_off: t.CSizeT = 0
|
||||
@@ -261,7 +264,95 @@ def _join_path(rel: str, project_dir: str) -> str:
|
||||
if buf is None:
|
||||
return rel # 分配失败,返回原路径
|
||||
viperlib.snprintf(buf, total_len, "%s/%s", project_dir, rel + rel_off)
|
||||
return buf
|
||||
return _normalize_path(buf)
|
||||
|
||||
|
||||
def _normalize_path(path: str) -> str:
|
||||
"""规范化路径:解析 . 和 .. 段,合并多余分隔符
|
||||
|
||||
例: ./test/BuddyTest/../../includes → ./includes
|
||||
./test/BuddyTest/App → ./test/BuddyTest/App
|
||||
绝对路径(/ 或 \\ 开头,含盘符 C:)保持不变。
|
||||
返回 _mbuddy 分配的字符串;失败时返回原路径。
|
||||
"""
|
||||
if path is None:
|
||||
return None
|
||||
plen: t.CSizeT = string.strlen(path)
|
||||
if plen == 0:
|
||||
return path
|
||||
# 绝对路径(/ 或 \ 开头,或盘符如 C:)不规范化
|
||||
if path[0] == '/' or path[0] == '\\':
|
||||
return path
|
||||
if plen >= 2 and path[1] == ':':
|
||||
return path
|
||||
# 输出缓冲(最坏情况 = 输入长度 + 可能的前缀 ./)
|
||||
out: str = _mbuddy.alloc(plen + 3)
|
||||
if out is None:
|
||||
return path
|
||||
seg_start: t.CSizeT = 0
|
||||
out_len: t.CSizeT = 0
|
||||
has_seg: int = 0
|
||||
i: t.CSizeT = 0
|
||||
while i <= plen:
|
||||
ch: t.CChar = '\0'
|
||||
if i < plen:
|
||||
ch = path[i]
|
||||
if ch == '/' or ch == '\\' or ch == '\0':
|
||||
seg_len: t.CSizeT = i - seg_start
|
||||
if seg_len > 0:
|
||||
# 单段 ".":跳过
|
||||
if seg_len == 1 and path[seg_start] == '.':
|
||||
pass
|
||||
# 单段 "..":弹出上一段(无段可弹时保留,如 ../includes)
|
||||
elif seg_len == 2 and path[seg_start] == '.' and path[seg_start + 1] == '.':
|
||||
if out_len > 0:
|
||||
# 回退到上一个分隔符
|
||||
k: t.CSizeT = out_len
|
||||
while k > 0 and out[k - 1] != '/' and out[k - 1] != '\\':
|
||||
k -= 1
|
||||
if k > 0:
|
||||
out_len = k - 1
|
||||
else:
|
||||
out_len = 0
|
||||
# 仍有剩余段时保持分隔符逻辑
|
||||
if out_len > 0:
|
||||
has_seg = 1
|
||||
else:
|
||||
has_seg = 0
|
||||
else:
|
||||
# 无段可弹:保留 ..
|
||||
out[0] = '.'
|
||||
out[1] = '.'
|
||||
out_len = 2
|
||||
has_seg = 1
|
||||
else:
|
||||
# 普通段:追加分隔符 + 段
|
||||
if has_seg > 0:
|
||||
out[out_len] = '/'
|
||||
out_len += 1
|
||||
jj: t.CSizeT = 0
|
||||
while jj < seg_len:
|
||||
out[out_len] = path[seg_start + jj]
|
||||
out_len += 1
|
||||
jj += 1
|
||||
has_seg = 1
|
||||
seg_start = i + 1
|
||||
i += 1
|
||||
if has_seg == 0:
|
||||
# 全部段被消掉(如 ./..):返回当前目录
|
||||
return "./"
|
||||
# 相对路径补回 ./ 前缀(与原路径风格一致;以 .. 开头的除外)
|
||||
if out[0] != '.' and out[0] != '/':
|
||||
# 右移 2 位留出 "./"(从后往前拷贝,避免覆盖源字符)
|
||||
mv: t.CSizeT = out_len
|
||||
while mv > 0:
|
||||
mv -= 1
|
||||
out[mv + 2] = out[mv]
|
||||
out[0] = '.'
|
||||
out[1] = '/'
|
||||
out_len += 2
|
||||
out[out_len] = '\0'
|
||||
return out
|
||||
|
||||
|
||||
def resolve_paths(project_dir: str) -> int:
|
||||
|
||||
Reference in new issue
Block a user