diff options
author | Damien George <damien.p.george@gmail.com> | 2014-02-05 21:27:05 +0000 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2014-02-05 21:27:05 +0000 |
commit | cdcb4906d41f42789f6610047e8ae6aa79a61e47 (patch) | |
tree | 099453009838e4ba11de4a32cda89f076dc20256 /py | |
parent | b8ec17c2d16407dd186d1f8f76c1e7c420bb7729 (diff) | |
parent | 911089606376e60bd9451a85eb9558a23cde9039 (diff) | |
download | micropython-cdcb4906d41f42789f6610047e8ae6aa79a61e47.tar.gz micropython-cdcb4906d41f42789f6610047e8ae6aa79a61e47.zip |
Merge pull request #262 from pfalcon/sys-path
Implement sys.path support
Diffstat (limited to 'py')
-rw-r--r-- | py/builtinimport.c | 41 | ||||
-rw-r--r-- | py/lexerunix.c | 21 | ||||
-rw-r--r-- | py/misc.h | 16 | ||||
-rw-r--r-- | py/qstrdefs.h | 1 | ||||
-rw-r--r-- | py/runtime.c | 8 | ||||
-rw-r--r-- | py/runtime.h | 1 |
6 files changed, 63 insertions, 25 deletions
diff --git a/py/builtinimport.c b/py/builtinimport.c index a5deed3924..92d9ada897 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -19,6 +19,8 @@ #include "map.h" #include "builtin.h" +mp_obj_t sys_path; + mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) { /* printf("import:\n"); @@ -37,10 +39,43 @@ mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) { } // find the file to import - mp_lexer_t *lex = mp_import_open_file(mod_name); + uint mod_name_len; + const byte* mod_name_p = qstr_data(mod_name, &mod_name_len); + mp_lexer_t *lex = NULL; + + uint path_num = 0; + mp_obj_t *path_items; + if (sys_path != MP_OBJ_NULL) { + mp_obj_list_get(sys_path, &path_num, &path_items); + } + + if (path_num == 0) { + CHECKBUF(fname, PATH_MAX); + CHECKBUF_APPEND(fname, mod_name_p, mod_name_len); + CHECKBUF_APPEND(fname, ".py", sizeof(".py") - 1); + CHECKBUF_APPEND_0(fname); + lex = mp_lexer_new_from_file(fname); + } else { + for (int i = 0; i < path_num; i++) { + CHECKBUF(fname, PATH_MAX); + uint p_len; + const byte *p = mp_obj_str_get_data(path_items[i], &p_len); + if (p_len > 0) { + CHECKBUF_APPEND(fname, p, p_len); + CHECKBUF_APPEND(fname, "/", 1); + } + CHECKBUF_APPEND(fname, mod_name_p, mod_name_len); + CHECKBUF_APPEND(fname, ".py", sizeof(".py") - 1); + CHECKBUF_APPEND_0(fname); + lex = mp_lexer_new_from_file(fname); + if (lex != NULL) { + break; + } + } + } + if (lex == NULL) { - // TODO handle lexer error correctly - return mp_const_none; + nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_ImportError, "ImportError: No module named '%s'", mod_name_p)); } qstr source_name = mp_lexer_source_name(lex); diff --git a/py/lexerunix.c b/py/lexerunix.c index 5d96c468f8..fb62d3d72f 100644 --- a/py/lexerunix.c +++ b/py/lexerunix.c @@ -14,7 +14,6 @@ mp_lexer_t *mp_lexer_new_from_file(const char *filename) { int fd = open(filename, O_RDONLY); if (fd < 0) { - printf("cannot open file %s\n", filename); return NULL; } uint size = lseek(fd, 0, SEEK_END); @@ -31,24 +30,4 @@ mp_lexer_t *mp_lexer_new_from_file(const char *filename) { return mp_lexer_new_from_str_len(qstr_from_str(filename), data, size, size); } -/******************************************************************************/ -/* unix implementation of import */ - -// TODO properly! - -static const char *import_base_dir = NULL; - -void mp_import_set_directory(const char *dir) { - import_base_dir = dir; -} - -mp_lexer_t *mp_import_open_file(qstr mod_name) { - vstr_t *vstr = vstr_new(); - if (import_base_dir != NULL) { - vstr_printf(vstr, "%s/", import_base_dir); - } - vstr_printf(vstr, "%s.py", qstr_str(mod_name)); - return mp_lexer_new_from_file(vstr_str(vstr)); // TODO does lexer need to copy the string? can we free it here? -} - #endif // MICROPY_ENABLE_LEXER_UNIX @@ -10,6 +10,11 @@ typedef unsigned char byte; typedef unsigned int uint; +/** generic ops *************************************************/ + +#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#define MAX(x, y) ((x) > (y) ? (x) : (y)) + /** memomry allocation ******************************************/ // TODO make a lazy m_renew that can increase by a smaller amount than requested (but by at least 1 more element) @@ -85,6 +90,17 @@ void vstr_add_strn(vstr_t *vstr, const char *str, int len); void vstr_cut_tail(vstr_t *vstr, int len); void vstr_printf(vstr_t *vstr, const char *fmt, ...); +/** non-dynamic size-bounded variable buffer/string *************/ + +#define CHECKBUF(buf, max_size) char buf[max_size + 1]; uint buf##_len = max_size; char *buf##_p = buf; +#define CHECKBUF_APPEND(buf, src, src_len) \ + { int l = MIN(src_len, buf##_len); \ + memcpy(buf##_p, src, l); \ + buf##_len -= l; \ + buf##_p += l; } +#define CHECKBUF_APPEND_0(buf) { *buf##_p = 0; } +#define CHECKBUF_LEN(buf) (buf##_p - buf) + #ifdef va_start void vstr_vprintf(vstr_t *vstr, const char *fmt, va_list ap); #endif diff --git a/py/qstrdefs.h b/py/qstrdefs.h index fe1de07252..dcd4ba42c0 100644 --- a/py/qstrdefs.h +++ b/py/qstrdefs.h @@ -73,6 +73,7 @@ Q(max) Q(min) Q(next) Q(ord) +Q(path) Q(pow) Q(print) Q(range) diff --git a/py/runtime.c b/py/runtime.c index 9327f0d6ac..fc18c01510 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -169,8 +169,14 @@ void rt_init(void) { #if MICROPY_CPYTHON_COMPAT // Precreate sys module, so "import sys" didn't throw exceptions. - mp_obj_new_module(MP_QSTR_sys); + mp_obj_t m_sys = mp_obj_new_module(MP_QSTR_sys); + // Avoid warning of unused var + (void)m_sys; #endif + // init sys.path + // for efficiency, left to platform-specific startup code + //sys_path = mp_obj_new_list(0, NULL); + //rt_store_attr(m_sys, MP_QSTR_path, sys_path); mp_module_micropython_init(); diff --git a/py/runtime.h b/py/runtime.h index aafe1a06a3..20595c6a58 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -46,3 +46,4 @@ void rt_locals_set(struct _mp_map_t *m); struct _mp_map_t *rt_globals_get(void); void rt_globals_set(struct _mp_map_t *m); struct _mp_map_t *rt_loaded_modules_get(void); +extern mp_obj_t sys_path; |