py/reader: Change close method to ioctl.

To allow more flexibility in the future.

Signed-off-by: Damien George <damien@micropython.org>
pull/8381/head
Damien George 2024-02-22 11:22:13 +11:00
rodzic b3c62f3169
commit 78c5d2e8dd
8 zmienionych plików z 99 dodań i 49 usunięć

Wyświetl plik

@ -49,7 +49,7 @@ typedef struct _mp_reader_vfs_t {
byte buf[];
} mp_reader_vfs_t;
static mp_uint_t mp_reader_vfs_readbyte(void *data) {
static uintptr_t mp_reader_vfs_readbyte(void *data) {
mp_reader_vfs_t *reader = (mp_reader_vfs_t *)data;
if (reader->bufpos >= reader->buflen) {
if (reader->buflen < reader->bufsize) {
@ -70,10 +70,16 @@ static mp_uint_t mp_reader_vfs_readbyte(void *data) {
return reader->buf[reader->bufpos++];
}
static void mp_reader_vfs_close(void *data) {
static intptr_t mp_reader_vfs_ioctl(void *data, uintptr_t request, uintptr_t arg) {
mp_reader_vfs_t *reader = (mp_reader_vfs_t *)data;
mp_stream_close(reader->file);
m_del_obj(mp_reader_vfs_t, reader);
if (request == MP_READER_CLOSE) {
mp_stream_close(reader->file);
m_del_obj(mp_reader_vfs_t, reader);
return 0;
}
return -MP_EINVAL;
}
void mp_reader_new_file(mp_reader_t *reader, qstr filename) {
@ -104,7 +110,7 @@ void mp_reader_new_file(mp_reader_t *reader, qstr filename) {
rf->bufpos = 0;
reader->data = rf;
reader->readbyte = mp_reader_vfs_readbyte;
reader->close = mp_reader_vfs_close;
reader->ioctl = mp_reader_vfs_ioctl;
}
#endif // MICROPY_READER_VFS

Wyświetl plik

@ -26,6 +26,7 @@
*/
#include "py/lexer.h"
#include "py/mperrno.h"
#if MICROPY_ENABLE_COMPILER
@ -35,7 +36,7 @@ typedef struct _mp_lexer_str32_buf_t {
uint8_t byte_off;
} mp_lexer_str32_buf_t;
static mp_uint_t str32_buf_next_byte(void *sb_in) {
static uintptr_t str32_buf_next_byte(void *sb_in) {
mp_lexer_str32_buf_t *sb = (mp_lexer_str32_buf_t *)sb_in;
byte c = sb->val & 0xff;
if (c == 0) {
@ -52,9 +53,13 @@ static mp_uint_t str32_buf_next_byte(void *sb_in) {
return c;
}
static void str32_buf_free(void *sb_in) {
static intptr_t str32_buf_free(void *sb_in, uintptr_t request, uintptr_t arg) {
mp_lexer_str32_buf_t *sb = (mp_lexer_str32_buf_t *)sb_in;
m_del_obj(mp_lexer_str32_buf_t, sb);
if (request == MP_READER_CLOSE) {
m_del_obj(mp_lexer_str32_buf_t, sb);
return 0;
}
return -MP_EINVAL;
}
mp_lexer_t *mp_lexer_new_from_str32(qstr src_name, const char *str, mp_uint_t len, mp_uint_t free_len) {

Wyświetl plik

@ -458,11 +458,18 @@ static mp_uint_t microbit_file_write(mp_obj_t obj, const void *buf, mp_uint_t si
return size;
}
static void microbit_file_close(file_descriptor_obj *fd) {
if (fd->writable) {
flash_write_byte((uint32_t)&(file_system_chunks[fd->start_chunk].header.end_offset), fd->seek_offset);
static intptr_t microbit_file_ioctl(void *fd_in, uintptr_t request, uintptr_t arg) {
file_descriptor_obj *fd = fd_in;
if (request == MP_READER_CLOSE) {
if (fd->writable) {
flash_write_byte((uint32_t)&(file_system_chunks[fd->start_chunk].header.end_offset), fd->seek_offset);
}
fd->open = false;
return 0;
}
fd->open = false;
return -MP_EINVAL;
}
static mp_obj_t microbit_file_list(void) {
@ -495,7 +502,7 @@ static mp_obj_t microbit_file_size(mp_obj_t filename) {
return mp_obj_new_int(len);
}
static mp_uint_t file_read_byte(file_descriptor_obj *fd) {
static uintptr_t file_read_byte(file_descriptor_obj *fd) {
if (file_system_chunks[fd->seek_chunk].next_chunk == UNUSED_CHUNK) {
uint8_t end_offset = file_system_chunks[fd->start_chunk].header.end_offset;
if (end_offset == UNUSED_CHUNK || fd->seek_offset == end_offset) {
@ -516,8 +523,8 @@ mp_lexer_t *os_mbfs_new_reader(const char *filename) {
}
mp_reader_t reader;
reader.data = fd;
reader.readbyte = (mp_uint_t(*)(void*))file_read_byte;
reader.close = (void(*)(void*))microbit_file_close; // no-op
reader.readbyte = (uintptr_t(*)(void*))file_read_byte;
reader.close = microbit_file_ioctl;
return mp_lexer_new(qstr_from_str(filename), reader);
}
@ -538,7 +545,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(os_mbfs_file_name_obj, os_mbfs_file_name);
static mp_obj_t os_mbfs_file_close(mp_obj_t self) {
file_descriptor_obj *fd = (file_descriptor_obj*)self;
microbit_file_close(fd);
microbit_file_ioctl(fd, MP_READER_CLOSE, 0);
return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_1(os_mbfs_file_close_obj, os_mbfs_file_close);

Wyświetl plik

@ -908,7 +908,7 @@ mp_lexer_t *mp_lexer_new_from_fd(qstr filename, int fd, bool close_fd) {
void mp_lexer_free(mp_lexer_t *lex) {
if (lex) {
lex->reader.close(lex->reader.data);
lex->reader.ioctl(lex->reader.data, MP_READER_CLOSE, 0);
vstr_clear(&lex->vstr);
#if MICROPY_PY_FSTRINGS
vstr_clear(&lex->fstring_args);

Wyświetl plik

@ -393,9 +393,14 @@ static mp_raw_code_t *load_raw_code(mp_reader_t *reader, mp_module_context_t *co
return rc;
}
static void reader_close(void *reader_in) {
mp_reader_t *reader = reader_in;
reader->ioctl(reader->data, MP_READER_CLOSE, 0);
}
void mp_raw_code_load(mp_reader_t *reader, mp_compiled_module_t *cm) {
// Set exception handler to close the reader if an exception is raised.
MP_DEFINE_NLR_JUMP_CALLBACK_FUNCTION_1(ctx, reader->close, reader->data);
MP_DEFINE_NLR_JUMP_CALLBACK_FUNCTION_1(ctx, reader_close, reader);
nlr_push_jump_callback(&ctx.callback, mp_call_function_1_from_nlr_jump_callback);
byte header[4];

Wyświetl plik

@ -39,7 +39,7 @@ typedef struct _mp_reader_mem_t {
const byte *end;
} mp_reader_mem_t;
static mp_uint_t mp_reader_mem_readbyte(void *data) {
static uintptr_t mp_reader_mem_readbyte(void *data) {
mp_reader_mem_t *reader = (mp_reader_mem_t *)data;
if (reader->cur < reader->end) {
return *reader->cur++;
@ -48,12 +48,18 @@ static mp_uint_t mp_reader_mem_readbyte(void *data) {
}
}
static void mp_reader_mem_close(void *data) {
static intptr_t mp_reader_mem_ioctl(void *data, uintptr_t request, uintptr_t arg) {
mp_reader_mem_t *reader = (mp_reader_mem_t *)data;
if (reader->free_len > 0) {
m_del(char, (char *)reader->beg, reader->free_len);
if (request == MP_READER_CLOSE) {
if (reader->free_len > 0) {
m_del(char, (char *)reader->beg, reader->free_len);
}
m_del_obj(mp_reader_mem_t, reader);
return 0;
}
m_del_obj(mp_reader_mem_t, reader);
return -MP_EINVAL;
}
void mp_reader_new_mem(mp_reader_t *reader, const byte *buf, size_t len, size_t free_len) {
@ -64,7 +70,7 @@ void mp_reader_new_mem(mp_reader_t *reader, const byte *buf, size_t len, size_t
rm->end = buf + len;
reader->data = rm;
reader->readbyte = mp_reader_mem_readbyte;
reader->close = mp_reader_mem_close;
reader->ioctl = mp_reader_mem_ioctl;
}
#if MICROPY_READER_POSIX
@ -81,7 +87,7 @@ typedef struct _mp_reader_posix_t {
byte buf[20];
} mp_reader_posix_t;
static mp_uint_t mp_reader_posix_readbyte(void *data) {
static uintptr_t mp_reader_posix_readbyte(void *data) {
mp_reader_posix_t *reader = (mp_reader_posix_t *)data;
if (reader->pos >= reader->len) {
if (reader->len == 0) {
@ -101,14 +107,20 @@ static mp_uint_t mp_reader_posix_readbyte(void *data) {
return reader->buf[reader->pos++];
}
static void mp_reader_posix_close(void *data) {
static intptr_t mp_reader_posix_ioctl(void *data, uintptr_t request, uintptr_t arg) {
mp_reader_posix_t *reader = (mp_reader_posix_t *)data;
if (reader->close_fd) {
MP_THREAD_GIL_EXIT();
close(reader->fd);
MP_THREAD_GIL_ENTER();
if (request == MP_READER_CLOSE) {
if (reader->close_fd) {
MP_THREAD_GIL_EXIT();
close(reader->fd);
MP_THREAD_GIL_ENTER();
}
m_del_obj(mp_reader_posix_t, reader);
return 0;
}
m_del_obj(mp_reader_posix_t, reader);
return -MP_EINVAL;
}
void mp_reader_new_file_from_fd(mp_reader_t *reader, int fd, bool close_fd) {
@ -129,7 +141,7 @@ void mp_reader_new_file_from_fd(mp_reader_t *reader, int fd, bool close_fd) {
rp->pos = 0;
reader->data = rp;
reader->readbyte = mp_reader_posix_readbyte;
reader->close = mp_reader_posix_close;
reader->ioctl = mp_reader_posix_ioctl;
}
#if !MICROPY_VFS_POSIX

Wyświetl plik

@ -28,15 +28,23 @@
#include "py/obj.h"
// the readbyte function must return the next byte in the input stream
// it must return MP_READER_EOF if end of stream
// it can be called again after returning MP_READER_EOF, and in that case must return MP_READER_EOF
#define MP_READER_EOF ((mp_uint_t)(-1))
#define MP_READER_EOF ((uintptr_t)(-1))
// Reader ioctl request codes.
#define MP_READER_CLOSE (1)
typedef struct _mp_reader_t {
// Pointer to the context of this reader, passed as the first argument to the methods below.
void *data;
mp_uint_t (*readbyte)(void *data);
void (*close)(void *data);
// The readbyte function must return the next byte in the input stream.
// It must return MP_READER_EOF if end of stream. It can be called again after returning
// MP_READER_EOF, and in that case must return MP_READER_EOF.
uintptr_t (*readbyte)(void *data);
// Ioctl method for performing various control actions.
// On error it must return a negative errno value.
intptr_t (*ioctl)(void *data, uintptr_t request, uintptr_t arg);
} mp_reader_t;
void mp_reader_new_mem(mp_reader_t *reader, const byte *buf, size_t len, size_t free_len);

Wyświetl plik

@ -34,6 +34,7 @@
#include "py/repl.h"
#include "py/gc.h"
#include "py/frozenmod.h"
#include "py/mperrno.h"
#include "py/mphal.h"
#if MICROPY_HW_ENABLE_USB
#include "irq.h"
@ -135,7 +136,7 @@ static int parse_compile_execute(const void *source, mp_parse_input_kind_t input
if (exec_flags & EXEC_FLAG_SOURCE_IS_READER) {
const mp_reader_t *reader = source;
reader->close(reader->data);
reader->ioctl(reader->data, MP_READER_CLOSE, 0);
}
// print EOF after normal output
@ -201,7 +202,7 @@ typedef struct _mp_reader_stdin_t {
uint16_t window_remain;
} mp_reader_stdin_t;
static mp_uint_t mp_reader_stdin_readbyte(void *data) {
static uintptr_t mp_reader_stdin_readbyte(void *data) {
mp_reader_stdin_t *reader = (mp_reader_stdin_t *)data;
if (reader->eof) {
@ -233,18 +234,24 @@ static mp_uint_t mp_reader_stdin_readbyte(void *data) {
return c;
}
static void mp_reader_stdin_close(void *data) {
static intptr_t mp_reader_stdin_ioctl(void *data, uintptr_t request, uintptr_t arg) {
mp_reader_stdin_t *reader = (mp_reader_stdin_t *)data;
if (!reader->eof) {
reader->eof = true;
mp_hal_stdout_tx_strn("\x04", 1); // indicate end to host
for (;;) {
int c = mp_hal_stdin_rx_chr();
if (c == CHAR_CTRL_C || c == CHAR_CTRL_D) {
break;
if (request == MP_READER_CLOSE) {
if (!reader->eof) {
reader->eof = true;
mp_hal_stdout_tx_strn("\x04", 1); // indicate end to host
for (;;) {
int c = mp_hal_stdin_rx_chr();
if (c == CHAR_CTRL_C || c == CHAR_CTRL_D) {
break;
}
}
}
return 0;
}
return -MP_EINVAL;
}
static void mp_reader_new_stdin(mp_reader_t *reader, mp_reader_stdin_t *reader_stdin, uint16_t buf_max) {
@ -260,7 +267,7 @@ static void mp_reader_new_stdin(mp_reader_t *reader, mp_reader_stdin_t *reader_s
reader_stdin->window_remain = window;
reader->data = reader_stdin;
reader->readbyte = mp_reader_stdin_readbyte;
reader->close = mp_reader_stdin_close;
reader->ioctl = mp_reader_stdin_ioctl;
}
static int do_reader_stdin(int c) {