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(): """Windows:GetCommandLineA + 手动解析(处理空格/双引号/反斜杠)""" 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 # 读取 cmdline(4KB 足够大多数情况) 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]