blob: 51bd6bfbb44b18df16bcf0ba5597e679966d90d2 [file] [log] [blame]
Damien George04b91472014-05-03 23:27:38 +01001/*
2 * This file is part of the Micro Python project, http://micropython.org/
3 *
4 * The MIT License (MIT)
5 *
6 * Copyright (c) 2013, 2014 Damien P. George
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
Damien George51dfcb42015-01-01 20:27:54 +000027#include "py/nlr.h"
28#include "py/builtin.h"
29#include "py/objlist.h"
30#include "py/objtuple.h"
31#include "py/objstr.h"
32#include "py/objint.h"
33#include "py/pfenv.h"
34#include "py/stream.h"
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030035
Damien Georgeee3fd462014-05-24 23:03:12 +010036#if MICROPY_PY_SYS
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030037
Damien George30dd23a2014-08-10 17:50:28 +010038/// \module sys - system specific functions
39
Damien Georgeb92cbe62014-09-15 15:53:09 +010040// These two lists must be initialised per port (after the call to mp_init).
Damien George4ef26c12014-08-10 17:53:43 +010041// TODO document these properly, they aren't constants or functions...
42/// \constant path - a mutable list of directories to search for imported modules
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030043mp_obj_list_t mp_sys_path_obj;
Damien George4ef26c12014-08-10 17:53:43 +010044/// \constant argv - a mutable list of arguments this program started with
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030045mp_obj_list_t mp_sys_argv_obj;
Damien George30dd23a2014-08-10 17:50:28 +010046
47/// \constant version - Python language version that this implementation conforms to, as a string
48STATIC const MP_DEFINE_STR_OBJ(version_obj, "3.4.0");
49
Damien George4ef26c12014-08-10 17:53:43 +010050/// \constant version_info - Python language version that this implementation conforms to, as a tuple of ints
Paul Sokolovskybaaaf652014-04-13 09:46:58 +030051#define I(n) MP_OBJ_NEW_SMALL_INT(n)
52// TODO: CPython is now at 5-element array, but save 2 els so far...
Paul Sokolovskybbae42d2014-04-14 01:46:45 +030053STATIC const mp_obj_tuple_t mp_sys_version_info_obj = {{&mp_type_tuple}, 3, {I(3), I(4), I(0)}};
Paul Sokolovskybaaaf652014-04-13 09:46:58 +030054#undef I
Damien George30dd23a2014-08-10 17:50:28 +010055
Paul Sokolovskyb9b93542014-06-07 23:40:04 +030056#ifdef MICROPY_PY_SYS_PLATFORM
Damien George30dd23a2014-08-10 17:50:28 +010057/// \constant platform - the platform that Micro Python is running on
Paul Sokolovskyb9b93542014-06-07 23:40:04 +030058STATIC const MP_DEFINE_STR_OBJ(platform_obj, MICROPY_PY_SYS_PLATFORM);
59#endif
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030060
Damien Georgeb92cbe62014-09-15 15:53:09 +010061/// \function exit([retval])
62/// Raise a `SystemExit` exception. If an argument is given, it is the
63/// value given to `SystemExit`.
64STATIC mp_obj_t mp_sys_exit(mp_uint_t n_args, const mp_obj_t *args) {
65 mp_obj_t exc;
66 if (n_args == 0) {
67 exc = mp_obj_new_exception(&mp_type_SystemExit);
68 } else {
69 exc = mp_obj_new_exception_arg1(&mp_type_SystemExit, args[0]);
70 }
71 nlr_raise(exc);
72}
73MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_exit_obj, 0, 1, mp_sys_exit);
74
Paul Sokolovsky46c3ab22014-12-06 14:29:09 +020075STATIC mp_obj_t mp_sys_print_exception(mp_uint_t n_args, const mp_obj_t *args) {
76 #if MICROPY_PY_IO
77 mp_obj_t stream_obj = &mp_sys_stdout_obj;
78 if (n_args > 1) {
79 stream_obj = args[1];
80 }
81
82 pfenv_t pfenv;
83 pfenv.data = stream_obj;
84 pfenv.print_strn = (void (*)(void *, const char *, mp_uint_t))mp_stream_write;
85 mp_obj_print_exception((void (*)(void *env, const char *fmt, ...))pfenv_printf, &pfenv, args[0]);
86 #else
87 mp_obj_print_exception(printf_wrapper, NULL, args[0]);
88 #endif
89
90 return mp_const_none;
91}
92MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_print_exception_obj, 1, 2, mp_sys_print_exception);
93
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030094STATIC const mp_map_elem_t mp_module_sys_globals_table[] = {
95 { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_sys) },
Paul Sokolovskyd99e9082014-05-10 16:50:45 +030096
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030097 { MP_OBJ_NEW_QSTR(MP_QSTR_path), (mp_obj_t)&mp_sys_path_obj },
98 { MP_OBJ_NEW_QSTR(MP_QSTR_argv), (mp_obj_t)&mp_sys_argv_obj },
Paul Sokolovskybbae42d2014-04-14 01:46:45 +030099 { MP_OBJ_NEW_QSTR(MP_QSTR_version), (mp_obj_t)&version_obj },
Paul Sokolovskybaaaf652014-04-13 09:46:58 +0300100 { MP_OBJ_NEW_QSTR(MP_QSTR_version_info), (mp_obj_t)&mp_sys_version_info_obj },
Paul Sokolovskyb9b93542014-06-07 23:40:04 +0300101#ifdef MICROPY_PY_SYS_PLATFORM
102 { MP_OBJ_NEW_QSTR(MP_QSTR_platform), (mp_obj_t)&platform_obj },
103#endif
Damien George30dd23a2014-08-10 17:50:28 +0100104 /// \constant byteorder - the byte order of the system ("little" or "big")
Paul Sokolovsky978d2c02014-04-13 09:53:52 +0300105#if MP_ENDIANNESS_LITTLE
106 { MP_OBJ_NEW_QSTR(MP_QSTR_byteorder), MP_OBJ_NEW_QSTR(MP_QSTR_little) },
107#else
108 { MP_OBJ_NEW_QSTR(MP_QSTR_byteorder), MP_OBJ_NEW_QSTR(MP_QSTR_big) },
109#endif
Paul Sokolovsky4e0eeeb2014-07-03 16:50:11 +0300110#if MICROPY_PY_SYS_MAXSIZE
111 #if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE
112 // INT_MAX is not representable as small int, as we know that small int
113 // takes one bit for tag. So, we have little choice but to provide this
114 // value. Apps also should be careful to not try to compare sys.maxsize
115 // with some number (which may not fit in available int size), but instead
116 // count number of significant bits in sys.maxsize.
117 { MP_OBJ_NEW_QSTR(MP_QSTR_maxsize), MP_OBJ_NEW_SMALL_INT(INT_MAX >> 1) },
118 #else
119 { MP_OBJ_NEW_QSTR(MP_QSTR_maxsize), (mp_obj_t)&mp_maxsize_obj },
120 #endif
121#endif
122
Damien Georgeee3fd462014-05-24 23:03:12 +0100123#if MICROPY_PY_SYS_EXIT
Damien George30dd23a2014-08-10 17:50:28 +0100124 // documented per-port
Damien George89755ae2014-05-11 17:35:43 +0100125 { MP_OBJ_NEW_QSTR(MP_QSTR_exit), (mp_obj_t)&mp_sys_exit_obj },
126#endif
127
Damien Georgeee3fd462014-05-24 23:03:12 +0100128#if MICROPY_PY_SYS_STDFILES
Damien George30dd23a2014-08-10 17:50:28 +0100129 // documented per-port
Paul Sokolovsky5500cde2014-04-13 06:43:18 +0300130 { MP_OBJ_NEW_QSTR(MP_QSTR_stdin), (mp_obj_t)&mp_sys_stdin_obj },
131 { MP_OBJ_NEW_QSTR(MP_QSTR_stdout), (mp_obj_t)&mp_sys_stdout_obj },
132 { MP_OBJ_NEW_QSTR(MP_QSTR_stderr), (mp_obj_t)&mp_sys_stderr_obj },
Paul Sokolovsky4165cd12014-04-13 07:00:37 +0300133#endif
Paul Sokolovsky46c3ab22014-12-06 14:29:09 +0200134
135 /*
136 * Extensions to CPython
137 */
138
139 { MP_OBJ_NEW_QSTR(MP_QSTR_print_exception), (mp_obj_t)&mp_sys_print_exception_obj },
Paul Sokolovsky5500cde2014-04-13 06:43:18 +0300140};
141
Damien George3b603f22014-11-29 14:39:27 +0000142STATIC MP_DEFINE_CONST_DICT(mp_module_sys_globals, mp_module_sys_globals_table);
Paul Sokolovsky5500cde2014-04-13 06:43:18 +0300143
144const mp_obj_module_t mp_module_sys = {
145 .base = { &mp_type_module },
146 .name = MP_QSTR_sys,
147 .globals = (mp_obj_dict_t*)&mp_module_sys_globals,
148};
149
150#endif