将 .py 和 .pyi 后缀名改为了 .vp 和 .vpi 后缀名
This commit is contained in:
1 parent
f79c8ca643
commit
cfc30d735c
322 files changed
+246
-31772
No files matched your search
+200
@@ -0,0 +1,200 @@
|
||||
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]
|
||||
Reference in new issue
Block a user