import t, c from stdint import * import platmacro import memhub import string import stdio # Windows backend dependencies import w32.win32base import w32.win32process # POSIX backend dependencies import posix # Module global MBuddy pointer (initialized in user main), Plans to ban _mbuddy: memhub.MemBuddy | t.CPtr # ============================================================================= # C Standard Library IO Declarations # ============================================================================= def fgets(buf: bytes, size: int, stream: t.CVoid | t.CPtr) -> str | t.State: pass def fflush(stream: t.CVoid | t.CPtr) -> int | t.State: pass # C standard library exit (terminates the process after flushing the buffer, cross-platform) def exit(status: int) -> t.State: pass # ============================================================================= # Platform Information # ============================================================================= # Maximum integer value (64-bit platform ssize_t upper limit) maxsize: t.CDefine = 9223372036854775807 # 2^63 - 1 def platform() -> str: """Returns the platform identifier string ('win32' or 'linux').""" if platmacro.IS_WINDOWS: return "win32" return "linux" # ============================================================================= # Process Information # ============================================================================= def get_pid() -> int: """返回当前进程 ID""" if platmacro.IS_WINDOWS: return w32.win32process.GetCurrentProcessId() return posix.getpid() # ============================================================================= # Command Line Arguments (argv) # ============================================================================= # global argv status (initialized on first access) _argc: int = 0 # _argv is a pointer array (char**), must use str | t.CPtr to index with sizeof(char*) # str | t.CPtr is a pointer to char** # bytes | t.CPtr is a pointer to char** _argv: str | t.CPtr def _init_argv(): """Initialize global argv once on first access""" global _argc, _argv if _argc != 0: return if platmacro.IS_WINDOWS: _init_argv_win32() else: _init_argv_posix() def _init_argv_win32(): """Windows: GetCommandLineA + manual parsing (handle spaces/double quotes/backslashes)""" global _argc, _argv cmdline: CHARPTR = w32.win32base.GetCommandLineA() if cmdline == None: return cmdlen: t.CSizeT = string.strlen(cmdline) if cmdlen == 0: return # Allocate buffer for parameter strings (worst case: entire command line + argc \0s) buf: bytes = _mbuddy.alloc(cmdlen + 1) if buf == None: return # Allocate pointer array for argv (worst case: each character is a parameter) 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: # Double quote 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: # Space or Tab (outside quotes): parameter delimiter 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: Read cmdline from /proc/self/cmdline (\0) separated parameters""" global _argc, _argv fd: INT = posix.open("/proc/self/cmdline", posix.O_RDONLY, 0) if fd < 0: return # Read cmdline (4KB) buf: bytes = _mbuddy.alloc(4096) # Need to verify size of buffer if buf == None: posix.close(fd) return total: ssize_t = posix.read(fd, buf, 4096) posix.close(fd) if total <= 0: return # Calculate argument count (\0 delimited) 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 # Allocate pointer array for argv (argc pointers) argv_arr: str | t.CPtr = (str | t.CPtr)(_mbuddy.alloc(argc * platmacro.SIZEOF_POINTER)) if argv_arr == None: return # Populate pointer array (start address of each parameter) 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: """Returns the number of command line arguments. Automatically initializes on the first call.""" if _argc == 0: _init_argv() return _argc def argv(index: int) -> str: """Returns the command line argument at index `index` (starting from 0). Automatically initializes on first call. Returns None if the index is out of range.""" if _argc == 0: _init_argv() if index < 0 or index >= _argc: return None return _argv[index]