Files
Viper_VRTE/os/_win32.vp
T
TermiNexus e71daeea0e docs(includes): R11 注释英文化——75 个文件的中文注释改写为英文短注释
按规范「注释只讲解作用,不掺杂历史原因,尽量英文」:把 includes 下 75 个 .vp 的中文 # 注释与三引号 docstring 改写为英文,每个注释块压到 2 行以内。

保留要点:作用、约束、危险警告(不得/必须/注意)、ABI 与类型约定(如 BYTEPTR | t.CPtr = i8** 的跨模块坍缩坑)、位宽/长度约定、fail-fast 要求、内存与句柄所有权。

未动:文件头注释(规范豁免,仍是中文)、运行时中文字符串常量(printf / fatal_error / MlirFail 等用户可见消息,属代码字面量)。

验证:独立脚本比对 HEAD 与工作区的代码骨架(剥离 # 注释与三引号 docstring 后的非空行)——75 个文件逐字节一致;行尾 CRLF/LF 未被改动;全文剩余中文仅 547 行头注释、0 条行尾注释。bootstrap 三重重编 SUCCESS;全量 77/77 顺序回归通过。
2026-10-05 16:18:44 +08:00

243 lines
7.9 KiB
Plaintext

import t, c
from stdint import *
import w32.win32base
import w32.win32file
import memhub
import stdlib
# Maximum Windows path length
define MAX_PATH_LEN = 260
# INVALID_FILE_ATTRIBUTES
define INVALID_FILE_ATTRIBUTES = 0xFFFFFFFF
# Module-level global MBuddy pointer (initialized by the user in main)
_mbuddy: memhub.MemBuddy*
# =============================================================================
# File/Directory Attribute Query
# =============================================================================
def _get_attrs(path: str) -> ULONG:
"""Get file attributes. Return INVALID_FILE_ATTRIBUTES on failure."""
return w32.win32file.GetFileAttributesA(path)
def exists(path: str) -> bool:
"""Check whether the file/directory exists"""
attrs: ULONG = _get_attrs(path)
if attrs == INVALID_FILE_ATTRIBUTES:
return False
return True
def isdir(path: str) -> bool:
"""Check whether the path is a directory"""
attrs: ULONG = _get_attrs(path)
if attrs == INVALID_FILE_ATTRIBUTES:
return False
if (attrs & w32.win32file.FILE_ATTRIBUTE_DIRECTORY) != 0:
return True
return False
def isfile(path: str) -> bool:
"""Check whether the path is a regular file"""
attrs: ULONG = _get_attrs(path)
if attrs == INVALID_FILE_ATTRIBUTES:
return False
if (attrs & w32.win32file.FILE_ATTRIBUTE_DIRECTORY) != 0:
return False
return True
def getsize(path: str) -> int64:
"""Return the file size in bytes. Return -1 on failure."""
handle: w32.win32base.HANDLE = w32.win32file.CreateFileA(
path, w32.win32file.GENERIC_READ, w32.win32file.FILE_SHARE_READ,
t.CPtr(0), w32.win32file.OPEN_EXISTING, w32.win32file.FILE_ATTRIBUTE_NORMAL, t.CPtr(0)
)
if handle == w32.win32base.INVALID_HANDLE_VALUE:
return -1
li: w32.win32base.LARGE_INTEGER = w32.win32base.LARGE_INTEGER()
result: BOOL = w32.win32file.GetFileSizeEx(handle, t.CPtr(&li))
w32.win32base.CloseHandle(handle)
if result == 0:
return -1
return li.QuadPart
# =============================================================================
# Working Directory
# =============================================================================
def getcwd() -> str:
"""Return the current working directory (memory allocated via _mbuddy)"""
buf: bytes = _mbuddy.alloc(MAX_PATH_LEN + 1)
if buf == None: return None
length: ULONG = w32.win32file.GetCurrentDirectoryA(MAX_PATH_LEN + 1, buf)
if length == 0:
return None
if length > MAX_PATH_LEN:
# Buffer too small; reallocate
buf2: bytes = _mbuddy.alloc(length + 1)
if buf2 == None: return None
w32.win32file.GetCurrentDirectoryA(length + 1, buf2)
buf2[length] = 0
return str(buf2)
buf[length] = 0
return str(buf)
def chdir(path: str) -> int:
"""Switch the current working directory. Return 0 on success, -1 on failure."""
result: BOOL = w32.win32file.SetCurrentDirectoryA(path)
if result == 0:
return -1
return 0
# =============================================================================
# File/Directory Operations
# =============================================================================
def mkdir(path: str) -> int:
"""Create a directory. Return 0 on success, -1 on failure.
If path is valid UTF-8, convert to UTF-16 and use CreateDirectoryW; otherwise fall back to the A-series."""
if w32.win32base.utf8_is_valid(path) == 0:
result: BOOL = w32.win32file.CreateDirectoryA(path, t.CPtr(0))
if result == 0:
return -1
return 0
wp: w32.win32base.WCHARPTR = w32.win32base.utf8_to_utf16_dup(path)
if wp is None:
result_a: BOOL = w32.win32file.CreateDirectoryA(path, t.CPtr(0))
if result_a == 0:
return -1
return 0
result_w: BOOL = w32.win32file.CreateDirectoryW(t.CPtr(wp), t.CPtr(0))
stdlib.free(wp)
if result_w == 0:
return -1
return 0
def remove(path: str) -> int:
"""Delete a file. Return 0 on success, -1 on failure."""
result: BOOL = w32.win32file.DeleteFileA(path)
if result == 0:
return -1
return 0
def rmdir(path: str) -> int:
"""Delete an empty directory. Return 0 on success, -1 on failure."""
result: BOOL = w32.win32file.RemoveDirectoryA(path)
if result == 0:
return -1
return 0
def rename(old_path: str, new_path: str) -> int:
"""Rename/move a file or directory. Return 0 on success, -1 on failure."""
result: BOOL = w32.win32file.MoveFileExA(
old_path, new_path,
w32.win32file.MOVEFILE_REPLACE_EXISTING | w32.win32file.MOVEFILE_COPY_ALLOWED
)
if result == 0:
return -1
return 0
def chmod(path: str, mode: int) -> int:
"""Modify file attributes (simplified Windows: read-only bit only).
S_IWUSR (0o200) in mode: 0 sets read-only, 1 sets writable. Return 0 on success, -1 on failure."""
if (mode & 0o200) != 0:
# Writable: clear the read-only attribute
result: BOOL = w32.win32file.SetFileAttributesA(
path, w32.win32file.FILE_ATTRIBUTE_NORMAL
)
else:
# Read-only: set the read-only attribute
result: BOOL = w32.win32file.SetFileAttributesA(
path, w32.win32file.FILE_ATTRIBUTE_READONLY
)
if result == 0:
return -1
return 0
# =============================================================================
# Directory Listing (FindFirstFile / FindNextFile)
# =============================================================================
def listdir(path: str, out_names: str*, max_count: ULONG) -> ULONG:
"""List file/subdirectory names under a directory.
out_names is a caller-provided char** array (each entry points to a filename allocated via _mbuddy); max_count is its capacity. Return the count, or 0 on failure."""
# Build search pattern: path\*
path_len: sizet = len(path)
pattern: bytes = _mbuddy.alloc(path_len + 3)
if pattern == None: return 0
i: sizet = 0
for ch in path:
pattern[i] = ch
i += 1
# Append \* suffix
if path[path_len - 1] != '\\' and path[path_len - 1] != '/':
pattern[i] = '\\'
i += 1
pattern[i] = '*'
i += 1
pattern[i] = 0
find_data: w32.win32file.WIN32_FIND_DATAA = w32.win32file.WIN32_FIND_DATAA()
handle: w32.win32base.HANDLE = w32.win32file.FindFirstFileA(pattern, t.CPtr(&find_data))
if handle == w32.win32base.INVALID_HANDLE_VALUE:
return 0
count: ULONG = 0
while count < max_count:
# Skip . and ..
name: str = find_data.cFileName
if name[0] == '.':
if name[1] == 0:
# "."
if w32.win32file.FindNextFileA(handle, t.CPtr(&find_data)) == 0:
break
continue
if name[1] == '.' and name[2] == 0:
# ".."
if w32.win32file.FindNextFileA(handle, t.CPtr(&find_data)) == 0:
break
continue
# Copy the filename into newly allocated memory
name_len: sizet = len(name)
name_buf: bytes = _mbuddy.alloc(name_len + 1)
if name_buf == None: break
j: sizet = 0
for ch in name:
name_buf[j] = ch
j += 1
name_buf[name_len] = 0
out_names[count] = str(name_buf)
count += 1
if w32.win32file.FindNextFileA(handle, t.CPtr(&find_data)) == 0:
break
w32.win32file.FindClose(handle)
return count
# =============================================================================
# Command Execution
# =============================================================================
def system(cmd: str) -> int:
"""Execute a command line command (via the C runtime system()).
Output goes to the child terminal (inherits parent stdout/stderr). Return the exit code (0 = success)."""
return stdlib.system(cmd)