summaryrefslogtreecommitdiff
path: root/extmod/uos_dupterm.c
diff options
context:
space:
mode:
Diffstat (limited to 'extmod/uos_dupterm.c')
-rw-r--r--extmod/uos_dupterm.c96
1 files changed, 72 insertions, 24 deletions
diff --git a/extmod/uos_dupterm.c b/extmod/uos_dupterm.c
index 1d6f02dce..d4326d326 100644
--- a/extmod/uos_dupterm.c
+++ b/extmod/uos_dupterm.c
@@ -4,6 +4,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2016 Paul Sokolovsky
+ * Copyright (c) 2017 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -31,12 +32,13 @@
#include "py/objtuple.h"
#include "py/objarray.h"
#include "py/stream.h"
+#include "lib/utils/interrupt_char.h"
#if MICROPY_PY_OS_DUPTERM
-void mp_uos_deactivate(const char *msg, mp_obj_t exc) {
- mp_obj_t term = MP_STATE_PORT(term_obj);
- MP_STATE_PORT(term_obj) = NULL;
+void mp_uos_deactivate(size_t dupterm_idx, const char *msg, mp_obj_t exc) {
+ mp_obj_t term = MP_STATE_VM(dupterm_objs[dupterm_idx]);
+ MP_STATE_VM(dupterm_objs[dupterm_idx]) = MP_OBJ_NULL;
mp_printf(&mp_plat_print, msg);
if (exc != MP_OBJ_NULL) {
mp_obj_print_exception(&mp_plat_print, exc);
@@ -44,48 +46,94 @@ void mp_uos_deactivate(const char *msg, mp_obj_t exc) {
mp_stream_close(term);
}
+int mp_uos_dupterm_rx_chr(void) {
+ for (size_t idx = 0; idx < MICROPY_PY_OS_DUPTERM; ++idx) {
+ if (MP_STATE_VM(dupterm_objs[idx]) == MP_OBJ_NULL) {
+ continue;
+ }
+
+ nlr_buf_t nlr;
+ if (nlr_push(&nlr) == 0) {
+ mp_obj_t readinto_m[3];
+ mp_load_method(MP_STATE_VM(dupterm_objs[idx]), MP_QSTR_readinto, readinto_m);
+ readinto_m[2] = MP_STATE_VM(dupterm_arr_obj);
+ mp_obj_t res = mp_call_method_n_kw(1, 0, readinto_m);
+ if (res == mp_const_none) {
+ nlr_pop();
+ } else if (res == MP_OBJ_NEW_SMALL_INT(0)) {
+ mp_uos_deactivate(idx, "dupterm: EOF received, deactivating\n", MP_OBJ_NULL);
+ nlr_pop();
+ } else {
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(MP_STATE_VM(dupterm_arr_obj), &bufinfo, MP_BUFFER_READ);
+ nlr_pop();
+ if (*(byte*)bufinfo.buf == mp_interrupt_char) {
+ // Signal keyboard interrupt to be raised as soon as the VM resumes
+ mp_keyboard_interrupt();
+ return -2;
+ }
+ return *(byte*)bufinfo.buf;
+ }
+ } else {
+ mp_uos_deactivate(idx, "dupterm: Exception in read() method, deactivating: ", nlr.ret_val);
+ }
+ }
+
+ // No chars available
+ return -1;
+}
+
void mp_uos_dupterm_tx_strn(const char *str, size_t len) {
- if (MP_STATE_PORT(term_obj) != MP_OBJ_NULL) {
+ for (size_t idx = 0; idx < MICROPY_PY_OS_DUPTERM; ++idx) {
+ if (MP_STATE_VM(dupterm_objs[idx]) == MP_OBJ_NULL) {
+ continue;
+ }
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mp_obj_t write_m[3];
- mp_load_method(MP_STATE_PORT(term_obj), MP_QSTR_write, write_m);
+ mp_load_method(MP_STATE_VM(dupterm_objs[idx]), MP_QSTR_write, write_m);
- mp_obj_array_t *arr = MP_OBJ_TO_PTR(MP_STATE_PORT(dupterm_arr_obj));
+ mp_obj_array_t *arr = MP_OBJ_TO_PTR(MP_STATE_VM(dupterm_arr_obj));
void *org_items = arr->items;
arr->items = (void*)str;
arr->len = len;
- write_m[2] = MP_STATE_PORT(dupterm_arr_obj);
+ write_m[2] = MP_STATE_VM(dupterm_arr_obj);
mp_call_method_n_kw(1, 0, write_m);
- arr = MP_OBJ_TO_PTR(MP_STATE_PORT(dupterm_arr_obj));
+ arr = MP_OBJ_TO_PTR(MP_STATE_VM(dupterm_arr_obj));
arr->items = org_items;
arr->len = 1;
nlr_pop();
} else {
- mp_uos_deactivate("dupterm: Exception in write() method, deactivating: ", nlr.ret_val);
+ mp_uos_deactivate(idx, "dupterm: Exception in write() method, deactivating: ", nlr.ret_val);
}
}
}
STATIC mp_obj_t mp_uos_dupterm(size_t n_args, const mp_obj_t *args) {
- if (n_args == 0) {
- if (MP_STATE_PORT(term_obj) == MP_OBJ_NULL) {
- return mp_const_none;
- } else {
- return MP_STATE_PORT(term_obj);
- }
+ mp_int_t idx = 0;
+ if (n_args == 2) {
+ idx = mp_obj_get_int(args[1]);
+ }
+
+ if (idx < 0 || idx >= MICROPY_PY_OS_DUPTERM) {
+ mp_raise_ValueError("invalid dupterm index");
+ }
+
+ mp_obj_t previous_obj = MP_STATE_VM(dupterm_objs[idx]);
+ if (previous_obj == MP_OBJ_NULL) {
+ previous_obj = mp_const_none;
+ }
+ if (args[0] == mp_const_none) {
+ MP_STATE_VM(dupterm_objs[idx]) = MP_OBJ_NULL;
} else {
- if (args[0] == mp_const_none) {
- MP_STATE_PORT(term_obj) = MP_OBJ_NULL;
- } else {
- MP_STATE_PORT(term_obj) = args[0];
- if (MP_STATE_PORT(dupterm_arr_obj) == MP_OBJ_NULL) {
- MP_STATE_PORT(dupterm_arr_obj) = mp_obj_new_bytearray(1, "");
- }
+ MP_STATE_VM(dupterm_objs[idx]) = args[0];
+ if (MP_STATE_VM(dupterm_arr_obj) == MP_OBJ_NULL) {
+ MP_STATE_VM(dupterm_arr_obj) = mp_obj_new_bytearray(1, "");
}
- return mp_const_none;
}
+
+ return previous_obj;
}
-MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_uos_dupterm_obj, 0, 1, mp_uos_dupterm);
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_uos_dupterm_obj, 1, 2, mp_uos_dupterm);
#endif