test iofbf mode

This commit is contained in:
blueloveTH 2025-05-05 22:52:59 +08:00
parent 332a51945c
commit 52bd04ba45
4 changed files with 27 additions and 6 deletions

View File

@ -68,6 +68,8 @@ typedef struct py_Callbacks {
char* (*importfile)(const char*); char* (*importfile)(const char*);
/// Used by `print` to output a string. /// Used by `print` to output a string.
void (*print)(const char*); void (*print)(const char*);
/// Flush the output buffer of `print`.
void (*flush)();
/// Used by `input` to get a character. /// Used by `input` to get a character.
int (*getchar)(); int (*getchar)();
} py_Callbacks; } py_Callbacks;

View File

@ -29,6 +29,8 @@ static char* pk_default_importfile(const char* path) {
static void pk_default_print(const char* data) { printf("%s", data); } static void pk_default_print(const char* data) { printf("%s", data); }
static void pk_default_flush() { fflush(stdout); }
static void py_TypeInfo__ctor(py_TypeInfo* self, static void py_TypeInfo__ctor(py_TypeInfo* self,
py_Name name, py_Name name,
py_Type index, py_Type index,
@ -67,6 +69,7 @@ void VM__ctor(VM* self) {
self->callbacks.importfile = pk_default_importfile; self->callbacks.importfile = pk_default_importfile;
self->callbacks.print = pk_default_print; self->callbacks.print = pk_default_print;
self->callbacks.flush = pk_default_flush;
self->callbacks.getchar = getchar; self->callbacks.getchar = getchar;
self->last_retval = *py_NIL(); self->last_retval = *py_NIL();

View File

@ -65,6 +65,14 @@ static bool pkpy_is_user_defined_type(int argc, py_Ref argv) {
return true; return true;
} }
static bool pkpy_enable_full_buffering_mode(int argc, py_Ref argv) {
PY_CHECK_ARGC(0);
static char buf[1024 * 1024 * 1];
setvbuf(stdout, buf, _IOFBF, sizeof(buf));
py_newnone(py_retval());
return true;
}
static bool pkpy_currentvm(int argc, py_Ref argv) { static bool pkpy_currentvm(int argc, py_Ref argv) {
PY_CHECK_ARGC(0); PY_CHECK_ARGC(0);
py_newint(py_retval(), py_currentvm()); py_newint(py_retval(), py_currentvm());
@ -411,7 +419,9 @@ static void pk_ComputeThread__register(py_Ref mod) {
py_bindmethod(type, "submit_exec", ComputeThread_submit_exec); py_bindmethod(type, "submit_exec", ComputeThread_submit_exec);
py_bindmethod(type, "submit_eval", ComputeThread_submit_eval); py_bindmethod(type, "submit_eval", ComputeThread_submit_eval);
py_bind(py_tpobject(type), "submit_call(self, eval_src, *args, **kwargs)", ComputeThread_submit_call); py_bind(py_tpobject(type),
"submit_call(self, eval_src, *args, **kwargs)",
ComputeThread_submit_call);
py_bindmethod(type, "exec", ComputeThread_exec); py_bindmethod(type, "exec", ComputeThread_exec);
py_bindmethod(type, "eval", ComputeThread_eval); py_bindmethod(type, "eval", ComputeThread_eval);
@ -453,6 +463,7 @@ void pk__add_module_pkpy() {
py_bindfunc(mod, "memory_usage", pkpy_memory_usage); py_bindfunc(mod, "memory_usage", pkpy_memory_usage);
py_bindfunc(mod, "is_user_defined_type", pkpy_is_user_defined_type); py_bindfunc(mod, "is_user_defined_type", pkpy_is_user_defined_type);
py_bindfunc(mod, "enable_full_buffering_mode", pkpy_enable_full_buffering_mode);
py_bindfunc(mod, "currentvm", pkpy_currentvm); py_bindfunc(mod, "currentvm", pkpy_currentvm);

View File

@ -200,12 +200,12 @@ static bool builtins_input(int argc, py_Ref argv) {
if(!py_checkstr(argv)) return false; if(!py_checkstr(argv)) return false;
prompt = py_tostr(argv); prompt = py_tostr(argv);
} }
pk_current_vm->callbacks.print(prompt); py_callbacks()->print(prompt);
c11_sbuf buf; c11_sbuf buf;
c11_sbuf__ctor(&buf); c11_sbuf__ctor(&buf);
while(true) { while(true) {
int c = pk_current_vm->callbacks.getchar(); int c = py_callbacks()->getchar();
if(c == '\n' || c == '\r') break; if(c == '\n' || c == '\r') break;
if(c == EOF) break; if(c == EOF) break;
c11_sbuf__write_char(&buf, c); c11_sbuf__write_char(&buf, c);
@ -323,11 +323,15 @@ static bool builtins_round(int argc, py_Ref argv) {
} }
static bool builtins_print(int argc, py_Ref argv) { static bool builtins_print(int argc, py_Ref argv) {
// print(*args, sep=' ', end='\n') // print(*args, sep=' ', end='\n', flush=False)
py_TValue* args = py_tuple_data(argv); py_TValue* args = py_tuple_data(argv);
int length = py_tuple_len(argv); int length = py_tuple_len(argv);
PY_CHECK_ARG_TYPE(1, tp_str);
PY_CHECK_ARG_TYPE(2, tp_str);
PY_CHECK_ARG_TYPE(3, tp_bool);
c11_sv sep = py_tosv(py_arg(1)); c11_sv sep = py_tosv(py_arg(1));
c11_sv end = py_tosv(py_arg(2)); c11_sv end = py_tosv(py_arg(2));
bool flush = py_tobool(py_arg(3));
c11_sbuf buf; c11_sbuf buf;
c11_sbuf__ctor(&buf); c11_sbuf__ctor(&buf);
for(int i = 0; i < length; i++) { for(int i = 0; i < length; i++) {
@ -340,7 +344,8 @@ static bool builtins_print(int argc, py_Ref argv) {
} }
c11_sbuf__write_sv(&buf, end); c11_sbuf__write_sv(&buf, end);
c11_string* res = c11_sbuf__submit(&buf); c11_string* res = c11_sbuf__submit(&buf);
pk_current_vm->callbacks.print(res->data); py_callbacks()->print(res->data);
if(flush) py_callbacks()->flush();
c11_string__delete(res); c11_string__delete(res);
py_newnone(py_retval()); py_newnone(py_retval());
return true; return true;
@ -722,7 +727,7 @@ py_TValue pk_builtins__register() {
py_bindfunc(builtins, "divmod", builtins_divmod); py_bindfunc(builtins, "divmod", builtins_divmod);
py_bindfunc(builtins, "round", builtins_round); py_bindfunc(builtins, "round", builtins_round);
py_bind(builtins, "print(*args, sep=' ', end='\\n')", builtins_print); py_bind(builtins, "print(*args, sep=' ', end='\\n', flush=False)", builtins_print);
py_bindfunc(builtins, "isinstance", builtins_isinstance); py_bindfunc(builtins, "isinstance", builtins_isinstance);
py_bindfunc(builtins, "issubclass", builtins_issubclass); py_bindfunc(builtins, "issubclass", builtins_issubclass);