Commit e503512f authored by Paul Sokolovsky's avatar Paul Sokolovsky Committed by Damien George
Browse files

unix: Implement -m option (execute module from stdlib).

Support for packages as argument not implemented, but otherwise error and
exit handling should be correct. This for example will allow to do:

pip-micropython install micropython-test.pystone
micropython -m test.pystone
parent bc1488a0
......@@ -286,6 +286,14 @@ mp_obj_t mp_builtin___import__(mp_uint_t n_args, const mp_obj_t *args) {
module_obj = mp_obj_new_module(mod_name);
// if args[3] (fromtuple) has magic value False, set up
// this module for command-line "-m" option (set module's
// name to __main__ instead of real name).
if (i == mod_len && fromtuple == mp_const_false) {
mp_obj_module_t *o = module_obj;
mp_obj_dict_store(o->globals, MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR___main__));
}
if (stat == MP_IMPORT_STAT_DIR) {
DEBUG_printf("%s is dir\n", vstr_str(&path));
// https://docs.python.org/3/reference/import.html
......
......@@ -47,6 +47,7 @@
#include "compile.h"
#include "runtime0.h"
#include "runtime.h"
#include "builtin.h"
#include "repl.h"
#include "gc.h"
#include "genhdr/py-version.h"
......@@ -83,8 +84,28 @@ STATIC void sighandler(int signum) {
#endif
#define FORCED_EXIT (0x100)
// returns standard error codes: 0 for success, 1 for all other errors
// if FORCED_EXIT bit is set then script raised SystemExit and the
// If exc is SystemExit, return value where FORCED_EXIT bit set,
// and lower 8 bits are SystemExit value. For all other exceptions,
// return 1.
STATIC int handle_uncaught_exception(mp_obj_t exc) {
// check for SystemExit
if (mp_obj_is_subclass_fast(mp_obj_get_type(exc), &mp_type_SystemExit)) {
// None is an exit value of 0; an int is its value; anything else is 1
mp_obj_t exit_val = mp_obj_exception_get_value(exc);
mp_int_t val = 0;
if (exit_val != mp_const_none && !mp_obj_get_int_maybe(exit_val, &val)) {
val = 1;
}
return FORCED_EXIT | (val & 255);
}
// Report all other exceptions
mp_obj_print_exception(exc);
return 1;
}
// Returns standard error codes: 0 for success, 1 for all other errors,
// except if FORCED_EXIT bit is set then script raised SystemExit and the
// value of the exit is in the lower 8 bits of the return value
STATIC int execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bool is_repl) {
if (lex == NULL) {
......@@ -160,19 +181,7 @@ STATIC int execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind,
#ifndef _WIN32
sigaction(SIGINT, &sa, NULL);
#endif
// check for SystemExit
mp_obj_t exc = (mp_obj_t)nlr.ret_val;
if (mp_obj_is_subclass_fast(mp_obj_get_type(exc), &mp_type_SystemExit)) {
// None is an exit value of 0; an int is its value; anything else is 1
mp_obj_t exit_val = mp_obj_exception_get_value(exc);
mp_int_t val = 0;
if (exit_val != mp_const_none && !mp_obj_get_int_maybe(exit_val, &val)) {
val = 1;
}
return FORCED_EXIT | (val & 255);
}
mp_obj_print_exception((mp_obj_t)nlr.ret_val);
return 1;
return handle_uncaught_exception((mp_obj_t)nlr.ret_val);
}
}
......@@ -320,6 +329,12 @@ void pre_process_options(int argc, char **argv) {
}
}
void set_sys_argv(char *argv[], int argc, int start_arg) {
for (int i = start_arg; i < argc; i++) {
mp_obj_list_append(mp_sys_argv, MP_OBJ_NEW_QSTR(qstr_from_str(argv[i])));
}
}
#ifdef _WIN32
#define PATHLIST_SEP_CHAR ';'
#else
......@@ -417,6 +432,40 @@ int main(int argc, char **argv) {
break;
}
a += 1;
} else if (strcmp(argv[a], "-m") == 0) {
if (a + 1 >= argc) {
return usage(argv);
}
mp_obj_t import_args[4];
import_args[0] = mp_obj_new_str(argv[a + 1], strlen(argv[a + 1]), false);
import_args[1] = import_args[2] = mp_const_none;
// Ask __import__ to handle imported module specially - set its __name__
// to __main__, and also return this leaf module, not top-level package
// containing it.
import_args[3] = mp_const_false;
// TODO: https://docs.python.org/3/using/cmdline.html#cmdoption-m :
// "the first element of sys.argv will be the full path to
// the module file (while the module file is being located,
// the first element will be set to "-m")."
set_sys_argv(argv, argc, a + 1);
mp_obj_t mod;
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mod = mp_builtin___import__(MP_ARRAY_SIZE(import_args), import_args);
nlr_pop();
} else {
// uncaught exception
return handle_uncaught_exception((mp_obj_t)nlr.ret_val);
}
if (mp_obj_is_package(mod)) {
// TODO
fprintf(stderr, "%s: -m for packages not yet implemented\n", argv[0]);
exit(1);
}
ret = 0;
break;
} else if (strcmp(argv[a], "-X") == 0) {
a += 1;
} else if (strcmp(argv[a], "-v") == 0) {
......@@ -447,9 +496,7 @@ int main(int argc, char **argv) {
path_items[0] = MP_OBJ_NEW_QSTR(qstr_from_strn(basedir, p - basedir));
free(pathbuf);
for (int i = a; i < argc; i++) {
mp_obj_list_append(mp_sys_argv, MP_OBJ_NEW_QSTR(qstr_from_str(argv[i])));
}
set_sys_argv(argv, argc, a);
ret = do_file(argv[a]);
break;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment