Psim_RunScriptInfo
Usage
psim.Psim_RunScriptInfo();
Python Help
py.help(psim.Psim_RunScriptInfo)
Python def
def Psim_RunScriptInfo(self, strScriptText: str, dictIn: dict=None):
# return dictOut, err_msg, scriptType, returnValue
# returnValue:
# -1: error
# 1 : success
# 10: script depends on other objects, possibly other scripts. Cannot run standalone. dictOut will return undefined variable list
#
# scriptType: bitmask of features used in the script
# ### scriptType:
# 0X01:assignments
# 0X02:arithmetics(+-*/pow)
# 0X04:basic math functions(sin,cos,log,...)
# 0X08:if,while
# 0X10:has Function or Formula
# 0X20:conditional
# 0X0100:advanced functions(ReadGraph, ReadFile,...)
encoding = 'utf-8' # 'mbcs' if platform.system() == 'Windows' else 'utf-8'
# Types
c_char_p = ctypes.c_char_p
c_int = ctypes.c_int
PP_c_char = ctypes.POINTER(c_char_p) # char**
PPP_c_char = ctypes.POINTER(PP_c_char) # char***
# Resolve functions
ScriptInfoA = getattr(self.psimHandle, 'ScriptInfoA')
delete_arr_charptr = getattr(self.psimHandle, 'delete_arr_charptr')
# Signatures
ScriptInfoA.argtypes = [
c_char_p, # szScriptFilePath
c_char_p, # szScriptContent (NULL)
c_char_p, # szError
c_int, # nErrorLen
PP_c_char, # pVarNameList_in
PP_c_char, # pVarValueList_in
c_int, # nVarCount_in
PPP_c_char, # ppVarNameList_out
PPP_c_char, # ppVarValueList_out
ctypes.POINTER(c_int), # npVarCount_out
ctypes.POINTER(c_int), # pScriptType_out
]
ScriptInfoA.restype = c_int
delete_arr_charptr.argtypes = [PP_c_char, c_int]
delete_arr_charptr.restype = None
# ---- prepare inputs ----
script_b = strScriptText.encode(encoding)
# Build parallel char* arrays from dictIn (keep refs so they don't get GC'ed)
if dictIn == None:
in_names_b = []
in_vals_b = []
else:
in_names_b = [k.encode(encoding) for k in dictIn.keys()]
in_vals_b = [str(v).encode(encoding) for v in dictIn.values()]
n_in = len(in_names_b)
if n_in > 0:
name_arr = (c_char_p * n_in)(*in_names_b)
val_arr = (c_char_p * n_in)(*in_vals_b)
p_names_in = ctypes.cast(name_arr, PP_c_char)
p_vals_in = ctypes.cast(val_arr, PP_c_char)
else:
p_names_in = None
p_vals_in = None
# Error buffer
ERR_LEN = 2000
err_buf = (ctypes.c_char * ERR_LEN)()
err_ptr = ctypes.cast(err_buf, c_char_p)
# Outputs
names_out = PP_c_char() # will receive char**
vals_out = PP_c_char() # will receive char**
n_out = c_int(0)
scriptType_out = c_int(0)
# ---- call ----
rc = ScriptInfoA(
None, # szScriptFilePath
script_b, # szScriptContent
err_ptr,
ERR_LEN,
p_names_in,
p_vals_in,
n_in,
ctypes.byref(names_out),
ctypes.byref(vals_out),
ctypes.byref(n_out),
ctypes.byref(scriptType_out)
)
# ---- outputs ----
returnValue = rc
scriptType = scriptType_out.value
dictOut = {}
try:
count = n_out.value
if count > 0 and bool(names_out) and bool(vals_out):
# names_out points to an array of c_char_p of length 'count'
for i in range(count):
key_b = names_out[i]
val_b = vals_out[i]
key = key_b.decode(encoding) if key_b else ''
val = val_b.decode(encoding) if val_b else ''
dictOut[key] = val
finally:
# Always free the C++ arrays (if allocated)
if n_out.value > 0 and bool(names_out):
delete_arr_charptr(names_out, n_out.value)
if n_out.value > 0 and bool(vals_out):
delete_arr_charptr(vals_out, n_out.value)
# Build error message string
err_msg = bytes(err_buf).split(b'\x00', 1)[0].decode(encoding, errors='replace')
# if rc == -1:
# # ScriptInfoA returns -1 for error
# if err_msg:
# err_msg = f"rc={rc}: {err_msg}"
# else:
# err_msg = f"rc={rc}"
return dictOut, err_msg, scriptType, returnValue