def r_eval(code, environment=None): r_start() cmdSexp = rlib.Rf_allocVector(rlib.STRSXP, 1) rlib.Rf_protect(cmdSexp) ffi_code = ffi.new("char[]", code.encode("ASCII")) rlib.SET_STRING_ELT(cmdSexp, 0, rlib.Rf_mkChar(ffi_code)) status = ffi.new("ParseStatus *") cmdexpr = rlib.Rf_protect( rlib.R_ParseVector(cmdSexp, -1, status, rlib.R_NilValue)) rlib.Rf_unprotect(2) if status[0] != rlib.PARSE_OK: raise RuntimeError("Failed to parse: " + code) if environment == None: environment = rlib.R_GlobalEnv error = ffi.new("int *") result = rlib.Rf_protect( rlib.R_tryEval(rlib.VECTOR_ELT(cmdexpr, 0), environment, error)) if (error[0]): message = r_eval("gsub('\\\n', '', geterrmessage())") raise RuntimeError(message + " at " + code) rtype = result.sxpinfo.type if (rtype == rlib.CHARSXP): result = ffi.string(rlib.R_CHAR(result)).decode("utf-8") elif (rtype == rlib.STRSXP): result = ffi.string(rlib.R_CHAR(rlib.STRING_ELT(result, 0))).decode("utf-8") elif (rtype == rlib.RAWSXP): n = rlib.Rf_xlength(result) result = ffi.buffer(rlib.RAW(result), n) rlib.Rf_unprotect(1) return result
def _showmessage(buffer): _print(ffi.string(buffer).decode("utf-8"))
def _console_write(buffer, size, otype): _print(ffi.string(buffer, size).decode("utf-8"))