Files
TransPyC/includes/sys.py
2026-07-18 19:25:40 +08:00

201 lines
5.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import t, c
from stdint import *
import platmacro
import memhub
import string
import stdio
# Windows 后端依赖
import w32.win32base
import w32.win32process
# POSIX 后端依赖
import posix
# 模块级全局 MBuddy 指针(由用户在 main 中赋值初始化)
_mbuddy: memhub.MemBuddy | t.CPtr
# =============================================================================
# C 标准库 IO 声明
# =============================================================================
def fgets(buf: t.CChar | t.CPtr, size: t.CInt, stream: t.CVoid | t.CPtr) -> t.CChar | t.CPtr | t.CExtern | t.CExport: pass
def fflush(stream: t.CVoid | t.CPtr) -> t.CInt | t.CExtern | t.CExport: pass
# C 标准库 exit刷新缓冲区后终止进程跨平台
def exit(status: INT) -> VOID | t.CExtern | t.CExport: pass
# =============================================================================
# 平台信息
# =============================================================================
# 最大整数值64 位平台 ssize_t 上限)
maxsize: t.CDefine = 9223372036854775807
def platform() -> str:
"""返回平台标识字符串('win32''linux'"""
if platmacro.IS_WINDOWS:
return "win32"
return "linux"
# =============================================================================
# 进程信息
# =============================================================================
def get_pid() -> int:
"""返回当前进程 ID"""
if platmacro.IS_WINDOWS:
return w32.win32process.GetCurrentProcessId()
return posix.getpid()
# =============================================================================
# 命令行参数argv
# =============================================================================
# 全局 argv 状态(首次访问时初始化)
_argc: INT = 0
# _argv 是指针数组char**),必须用 str | t.CPtr 使索引按 sizeof(char*) 步长
# str 本身是 char*| t.CPtr 再加一层指针 = char**
# bytes | t.CPtr 也是 char**,可以同样用
_argv: str | t.CPtr
def _init_argv():
"""初始化全局 argv首次访问时调用一次"""
global _argc, _argv
if _argc != 0:
return
if platmacro.IS_WINDOWS:
_init_argv_win32()
else:
_init_argv_posix()
def _init_argv_win32():
"""WindowsGetCommandLineA + 手动解析(处理空格/双引号/反斜杠)"""
global _argc, _argv
cmdline: CHARPTR = w32.win32base.GetCommandLineA()
if cmdline == None:
return
cmdlen: t.CSizeT = string.strlen(cmdline)
if cmdlen == 0:
return
# 分配参数字符串缓冲区(最坏情况:整个命令行 + argc 个 \0
buf: bytes = _mbuddy.alloc(cmdlen + 1)
if buf == None:
return
# 分配指针数组(最坏情况:每个字符都是一个参数)
max_args: t.CSizeT = cmdlen + 1
argv_arr: str | t.CPtr = (str | t.CPtr)(_mbuddy.alloc(max_args * platmacro.SIZEOF_POINTER))
if argv_arr == None:
return
argc: INT = 0
i: t.CSizeT = 0
j: t.CSizeT = 0
in_quote: bool = False
in_arg: bool = False
while i < cmdlen:
ch: t.CInt = cmdline[i]
if ch == 34: # 双引号
in_quote = not in_quote
if not in_arg:
argv_arr[argc] = str(buf + j)
argc += 1
in_arg = True
elif (ch == 32 or ch == 9) and not in_quote:
# 空格或 Tab引号外参数分隔符
if in_arg:
buf[j] = 0
j += 1
in_arg = False
else:
if not in_arg:
argv_arr[argc] = str(buf + j)
argc += 1
in_arg = True
buf[j] = ch
j += 1
i += 1
if in_arg:
buf[j] = 0
_argc = argc
_argv = argv_arr
def _init_argv_posix():
"""POSIX读取 /proc/self/cmdline参数以 \\0 分隔,末尾双 \\0"""
global _argc, _argv
fd: INT = posix.open("/proc/self/cmdline", posix.O_RDONLY, 0)
if fd < 0:
return
# 读取 cmdline4KB 足够大多数情况)
buf: bytes = _mbuddy.alloc(4096)
if buf == None:
posix.close(fd)
return
total: ssize_t = posix.read(fd, buf, 4096)
posix.close(fd)
if total <= 0:
return
# 计算参数个数(\0 分隔)
argc: INT = 0
i: t.CSizeT = 0
total_size: t.CSizeT = t.CSizeT(total)
while i < total_size:
if buf[i] == 0:
argc += 1
i += 1
if argc == 0:
return
# 分配指针数组
argv_arr: str | t.CPtr = (str | t.CPtr)(_mbuddy.alloc(argc * platmacro.SIZEOF_POINTER))
if argv_arr == None:
return
# 填充指针(每个参数的起始地址)
argv_arr[0] = str(buf)
idx: INT = 1
i = 0
while i < total_size and idx < argc:
if buf[i] == 0:
argv_arr[idx] = str(buf + i + 1)
idx += 1
i += 1
_argc = argc
_argv = argv_arr
def argc() -> int:
"""返回命令行参数个数。首次调用时自动初始化。"""
if _argc == 0:
_init_argv()
return _argc
def argv(index: int) -> str:
"""返回第 index 个命令行参数index 从 0 开始)。
首次调用时自动初始化。索引越界返回 None。"""
if _argc == 0:
_init_argv()
if index < 0 or index >= _argc:
return None
return _argv[index]