diff options
author | Damien George <damien.p.george@gmail.com> | 2014-04-10 15:00:58 +0100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2014-04-10 15:00:58 +0100 |
commit | ffa9bddfc4006aebb2689826f700ea167f4de54d (patch) | |
tree | a4098618f4ba934a893b84294f549622f771a744 /py/lexerunix.c | |
parent | f0954e3fac03c35a91e544c2ffddc12b82d7f8a0 (diff) | |
download | micropython-ffa9bddfc4006aebb2689826f700ea167f4de54d.tar.gz micropython-ffa9bddfc4006aebb2689826f700ea167f4de54d.zip |
Make lexerunix not allocate RAM for the entire script.
Now reads in small chunks at a time.
Diffstat (limited to 'py/lexerunix.c')
-rw-r--r-- | py/lexerunix.c | 50 |
1 files changed, 36 insertions, 14 deletions
diff --git a/py/lexerunix.c b/py/lexerunix.c index 73d30f2476..52fbe740ae 100644 --- a/py/lexerunix.c +++ b/py/lexerunix.c @@ -13,23 +13,45 @@ #include <sys/stat.h> #include <sys/types.h> -mp_lexer_t *mp_lexer_new_from_file(const char *filename) { - int fd = open(filename, O_RDONLY); - if (fd < 0) { - return NULL; +typedef struct _mp_lexer_file_buf_t { + int fd; + char buf[20]; + uint len; + uint pos; +} mp_lexer_file_buf_t; + +STATIC unichar file_buf_next_char(mp_lexer_file_buf_t *fb) { + if (fb->pos >= fb->len) { + if (fb->len < sizeof(fb->buf)) { + return MP_LEXER_CHAR_EOF; + } else { + int n = read(fb->fd, fb->buf, sizeof(fb->buf)); + if (n <= 0) { + return MP_LEXER_CHAR_EOF; + } + fb->len = n; + fb->pos = 0; + } } - uint size = lseek(fd, 0, SEEK_END); - lseek(fd, 0, SEEK_SET); - char *data = m_new(char, size); - int read_size = read(fd, data, size); - close(fd); - if (read_size != size) { - printf("error reading file %s\n", filename); - m_del(char, data, size); + return fb->buf[fb->pos++]; +} + +STATIC void file_buf_close(mp_lexer_file_buf_t *fb) { + close(fb->fd); + m_del_obj(mp_lexer_file_buf_t, fb); +} + +mp_lexer_t *mp_lexer_new_from_file(const char *filename) { + mp_lexer_file_buf_t *fb = m_new_obj(mp_lexer_file_buf_t); + fb->fd = open(filename, O_RDONLY); + if (fb->fd < 0) { + m_del_obj(mp_lexer_file_buf_t, fb); return NULL; } - - return mp_lexer_new_from_str_len(qstr_from_str(filename), data, size, size); + int n = read(fb->fd, fb->buf, sizeof(fb->buf)); + fb->len = n; + fb->pos = 0; + return mp_lexer_new(qstr_from_str(filename), fb, (mp_lexer_stream_next_char_t)file_buf_next_char, (mp_lexer_stream_close_t)file_buf_close); } #endif // MICROPY_ENABLE_LEXER_UNIX |