blob: 06bd4c80e10f2a2c40355080e7a8bc36af5f8e83 [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
Paul Sokolovsky4e0eeeb2014-07-03 16:50:11 +030027#include <stdint.h>
Damien Georgeb92cbe62014-09-15 15:53:09 +010028
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030029#include "mpconfig.h"
Damien Georgeb92cbe62014-09-15 15:53:09 +010030#include "nlr.h"
Paul Sokolovsky59c675a2014-06-21 22:43:22 +030031#include "misc.h"
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030032#include "qstr.h"
33#include "obj.h"
34#include "builtin.h"
35#include "runtime.h"
36#include "objlist.h"
Paul Sokolovskybaaaf652014-04-13 09:46:58 +030037#include "objtuple.h"
Paul Sokolovskybbae42d2014-04-14 01:46:45 +030038#include "objstr.h"
Paul Sokolovsky4e0eeeb2014-07-03 16:50:11 +030039#include "mpz.h"
40#include "objint.h"
Paul Sokolovsky46c3ab22014-12-06 14:29:09 +020041#include "pfenv.h"
42#include "stream.h"
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030043
Damien Georgeee3fd462014-05-24 23:03:12 +010044#if MICROPY_PY_SYS
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030045
Damien George30dd23a2014-08-10 17:50:28 +010046/// \module sys - system specific functions
47
Damien Georgeb92cbe62014-09-15 15:53:09 +010048// These two lists must be initialised per port (after the call to mp_init).
Damien George4ef26c12014-08-10 17:53:43 +010049// TODO document these properly, they aren't constants or functions...
50/// \constant path - a mutable list of directories to search for imported modules
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030051mp_obj_list_t mp_sys_path_obj;
Damien George4ef26c12014-08-10 17:53:43 +010052/// \constant argv - a mutable list of arguments this program started with
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030053mp_obj_list_t mp_sys_argv_obj;
Damien George30dd23a2014-08-10 17:50:28 +010054
55/// \constant version - Python language version that this implementation conforms to, as a string
56STATIC const MP_DEFINE_STR_OBJ(version_obj, "3.4.0");
57
Damien George4ef26c12014-08-10 17:53:43 +010058/// \constant version_info - Python language version that this implementation conforms to, as a tuple of ints
Paul Sokolovskybaaaf652014-04-13 09:46:58 +030059#define I(n) MP_OBJ_NEW_SMALL_INT(n)
60// TODO: CPython is now at 5-element array, but save 2 els so far...
Paul Sokolovskybbae42d2014-04-14 01:46:45 +030061STATIC 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 +030062#undef I
Damien George30dd23a2014-08-10 17:50:28 +010063
Paul Sokolovskyb9b93542014-06-07 23:40:04 +030064#ifdef MICROPY_PY_SYS_PLATFORM
Damien George30dd23a2014-08-10 17:50:28 +010065/// \constant platform - the platform that Micro Python is running on
Paul Sokolovskyb9b93542014-06-07 23:40:04 +030066STATIC const MP_DEFINE_STR_OBJ(platform_obj, MICROPY_PY_SYS_PLATFORM);
67#endif
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030068
Damien Georgeb92cbe62014-09-15 15:53:09 +010069/// \function exit([retval])
70/// Raise a `SystemExit` exception. If an argument is given, it is the
71/// value given to `SystemExit`.
72STATIC mp_obj_t mp_sys_exit(mp_uint_t n_args, const mp_obj_t *args) {
73 mp_obj_t exc;
74 if (n_args == 0) {
75 exc = mp_obj_new_exception(&mp_type_SystemExit);
76 } else {
77 exc = mp_obj_new_exception_arg1(&mp_type_SystemExit, args[0]);
78 }
79 nlr_raise(exc);
80}
81MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_exit_obj, 0, 1, mp_sys_exit);
82
Paul Sokolovsky46c3ab22014-12-06 14:29:09 +020083STATIC mp_obj_t mp_sys_print_exception(mp_uint_t n_args, const mp_obj_t *args) {
84 #if MICROPY_PY_IO
85 mp_obj_t stream_obj = &mp_sys_stdout_obj;
86 if (n_args > 1) {
87 stream_obj = args[1];
88 }
89
90 pfenv_t pfenv;
91 pfenv.data = stream_obj;
92 pfenv.print_strn = (void (*)(void *, const char *, mp_uint_t))mp_stream_write;
93 mp_obj_print_exception((void (*)(void *env, const char *fmt, ...))pfenv_printf, &pfenv, args[0]);
94 #else
95 mp_obj_print_exception(printf_wrapper, NULL, args[0]);
96 #endif
97
98 return mp_const_none;
99}
100MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_print_exception_obj, 1, 2, mp_sys_print_exception);
101
Paul Sokolovsky5500cde2014-04-13 06:43:18 +0300102STATIC const mp_map_elem_t mp_module_sys_globals_table[] = {
103 { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_sys) },
Paul Sokolovskyd99e9082014-05-10 16:50:45 +0300104
Paul Sokolovsky5500cde2014-04-13 06:43:18 +0300105 { MP_OBJ_NEW_QSTR(MP_QSTR_path), (mp_obj_t)&mp_sys_path_obj },
106 { MP_OBJ_NEW_QSTR(MP_QSTR_argv), (mp_obj_t)&mp_sys_argv_obj },
Paul Sokolovskybbae42d2014-04-14 01:46:45 +0300107 { MP_OBJ_NEW_QSTR(MP_QSTR_version), (mp_obj_t)&version_obj },
Paul Sokolovskybaaaf652014-04-13 09:46:58 +0300108 { MP_OBJ_NEW_QSTR(MP_QSTR_version_info), (mp_obj_t)&mp_sys_version_info_obj },
Paul Sokolovskyb9b93542014-06-07 23:40:04 +0300109#ifdef MICROPY_PY_SYS_PLATFORM
110 { MP_OBJ_NEW_QSTR(MP_QSTR_platform), (mp_obj_t)&platform_obj },
111#endif
Damien George30dd23a2014-08-10 17:50:28 +0100112 /// \constant byteorder - the byte order of the system ("little" or "big")
Paul Sokolovsky978d2c02014-04-13 09:53:52 +0300113#if MP_ENDIANNESS_LITTLE
114 { MP_OBJ_NEW_QSTR(MP_QSTR_byteorder), MP_OBJ_NEW_QSTR(MP_QSTR_little) },
115#else
116 { MP_OBJ_NEW_QSTR(MP_QSTR_byteorder), MP_OBJ_NEW_QSTR(MP_QSTR_big) },
117#endif
Paul Sokolovsky4e0eeeb2014-07-03 16:50:11 +0300118#if MICROPY_PY_SYS_MAXSIZE
119 #if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE
120 // INT_MAX is not representable as small int, as we know that small int
121 // takes one bit for tag. So, we have little choice but to provide this
122 // value. Apps also should be careful to not try to compare sys.maxsize
123 // with some number (which may not fit in available int size), but instead
124 // count number of significant bits in sys.maxsize.
125 { MP_OBJ_NEW_QSTR(MP_QSTR_maxsize), MP_OBJ_NEW_SMALL_INT(INT_MAX >> 1) },
126 #else
127 { MP_OBJ_NEW_QSTR(MP_QSTR_maxsize), (mp_obj_t)&mp_maxsize_obj },
128 #endif
129#endif
130
Damien Georgeee3fd462014-05-24 23:03:12 +0100131#if MICROPY_PY_SYS_EXIT
Damien George30dd23a2014-08-10 17:50:28 +0100132 // documented per-port
Damien George89755ae2014-05-11 17:35:43 +0100133 { MP_OBJ_NEW_QSTR(MP_QSTR_exit), (mp_obj_t)&mp_sys_exit_obj },
134#endif
135
Damien Georgeee3fd462014-05-24 23:03:12 +0100136#if MICROPY_PY_SYS_STDFILES
Damien George30dd23a2014-08-10 17:50:28 +0100137 // documented per-port
Paul Sokolovsky5500cde2014-04-13 06:43:18 +0300138 { MP_OBJ_NEW_QSTR(MP_QSTR_stdin), (mp_obj_t)&mp_sys_stdin_obj },
139 { MP_OBJ_NEW_QSTR(MP_QSTR_stdout), (mp_obj_t)&mp_sys_stdout_obj },
140 { MP_OBJ_NEW_QSTR(MP_QSTR_stderr), (mp_obj_t)&mp_sys_stderr_obj },
Paul Sokolovsky4165cd12014-04-13 07:00:37 +0300141#endif
Paul Sokolovsky46c3ab22014-12-06 14:29:09 +0200142
143 /*
144 * Extensions to CPython
145 */
146
147 { MP_OBJ_NEW_QSTR(MP_QSTR_print_exception), (mp_obj_t)&mp_sys_print_exception_obj },
Paul Sokolovsky5500cde2014-04-13 06:43:18 +0300148};
149
Damien George3b603f22014-11-29 14:39:27 +0000150STATIC MP_DEFINE_CONST_DICT(mp_module_sys_globals, mp_module_sys_globals_table);
Paul Sokolovsky5500cde2014-04-13 06:43:18 +0300151
152const mp_obj_module_t mp_module_sys = {
153 .base = { &mp_type_module },
154 .name = MP_QSTR_sys,
155 .globals = (mp_obj_dict_t*)&mp_module_sys_globals,
156};
157
158#endif