diff options
author | Damien George <damien.p.george@gmail.com> | 2017-03-14 11:16:31 +1100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2017-03-14 11:52:05 +1100 |
commit | 1831034be13fef5344583c557ff089df31788251 (patch) | |
tree | 391459a654f8b48a5d21af14dc7b9c677ed9af51 /extmod/vfs_reader.c | |
parent | 9773506ab131422433c830e18ab044f0c7d3e0b0 (diff) |
py: Allow lexer to raise exceptions during construction.
This patch refactors the error handling in the lexer, to simplify it (ie
reduce code size).
A long time ago, when the lexer/parser/compiler were first written, the
lexer and parser were designed so they didn't use exceptions (ie nlr) to
report errors but rather returned an error code. Over time that has
gradually changed, the parser in particular has more and more ways of
raising exceptions. Also, the lexer never really handled all errors without
raising, eg there were some memory errors which could raise an exception
(and in these rare cases one would get a fatal nlr-not-handled fault).
This patch accepts the fact that the lexer can raise exceptions in some
cases and allows it to raise exceptions to handle all its errors, which are
for the most part just out-of-memory errors during construction of the
lexer. This makes the lexer a bit simpler, and also the persistent code
stuff is simplified.
What this means for users of the lexer is that calls to it must be wrapped
in a nlr handler. But all uses of the lexer already have such an nlr
handler for the parser (and compiler) so that doesn't put any extra burden
on the callers.
Diffstat (limited to 'extmod/vfs_reader.c')
-rw-r--r-- | extmod/vfs_reader.c | 29 |
1 files changed, 9 insertions, 20 deletions
diff --git a/extmod/vfs_reader.c b/extmod/vfs_reader.c index 9509582d2..891098aa1 100644 --- a/extmod/vfs_reader.c +++ b/extmod/vfs_reader.c @@ -27,7 +27,7 @@ #include <stdio.h> #include <string.h> -#include "py/nlr.h" +#include "py/runtime.h" #include "py/stream.h" #include "py/reader.h" #include "extmod/vfs.h" @@ -69,30 +69,19 @@ STATIC void mp_reader_vfs_close(void *data) { m_del_obj(mp_reader_vfs_t, reader); } -int mp_reader_new_file(mp_reader_t *reader, const char *filename) { - mp_reader_vfs_t *rf = m_new_obj_maybe(mp_reader_vfs_t); - if (rf == NULL) { - return MP_ENOMEM; - } - // TODO we really should just let this function raise a uPy exception - nlr_buf_t nlr; - if (nlr_push(&nlr) == 0) { - mp_obj_t arg = mp_obj_new_str(filename, strlen(filename), false); - rf->file = mp_vfs_open(1, &arg, (mp_map_t*)&mp_const_empty_map); - int errcode; - rf->len = mp_stream_rw(rf->file, rf->buf, sizeof(rf->buf), &errcode, MP_STREAM_RW_READ | MP_STREAM_RW_ONCE); - nlr_pop(); - if (errcode != 0) { - return errcode; - } - } else { - return MP_ENOENT; // assume error was "file not found" +void mp_reader_new_file(mp_reader_t *reader, const char *filename) { + mp_reader_vfs_t *rf = m_new_obj(mp_reader_vfs_t); + mp_obj_t arg = mp_obj_new_str(filename, strlen(filename), false); + rf->file = mp_vfs_open(1, &arg, (mp_map_t*)&mp_const_empty_map); + int errcode; + rf->len = mp_stream_rw(rf->file, rf->buf, sizeof(rf->buf), &errcode, MP_STREAM_RW_READ | MP_STREAM_RW_ONCE); + if (errcode != 0) { + mp_raise_OSError(errcode); } rf->pos = 0; reader->data = rf; reader->readbyte = mp_reader_vfs_readbyte; reader->close = mp_reader_vfs_close; - return 0; // success } #endif // MICROPY_READER_VFS |