blob: 51e10dae54eff0743d1e64866e478a301a7fcd4d [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 Georgecd342072015-01-12 22:30:49 +000040// defined per port; type of these is irrelevant, just need pointer
41extern mp_uint_t mp_sys_stdin_obj;
42extern mp_uint_t mp_sys_stdout_obj;
43extern mp_uint_t mp_sys_stderr_obj;
44
Damien Georgeb92cbe62014-09-15 15:53:09 +010045// These two lists must be initialised per port (after the call to mp_init).
Damien George4ef26c12014-08-10 17:53:43 +010046// TODO document these properly, they aren't constants or functions...
47/// \constant path - a mutable list of directories to search for imported modules
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030048mp_obj_list_t mp_sys_path_obj;
Damien George4ef26c12014-08-10 17:53:43 +010049/// \constant argv - a mutable list of arguments this program started with
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030050mp_obj_list_t mp_sys_argv_obj;
Damien George30dd23a2014-08-10 17:50:28 +010051
52/// \constant version - Python language version that this implementation conforms to, as a string
53STATIC const MP_DEFINE_STR_OBJ(version_obj, "3.4.0");
54
Damien George4ef26c12014-08-10 17:53:43 +010055/// \constant version_info - Python language version that this implementation conforms to, as a tuple of ints
Paul Sokolovskybaaaf652014-04-13 09:46:58 +030056#define I(n) MP_OBJ_NEW_SMALL_INT(n)
57// TODO: CPython is now at 5-element array, but save 2 els so far...
Paul Sokolovskybbae42d2014-04-14 01:46:45 +030058STATIC 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 +030059#undef I
Damien George30dd23a2014-08-10 17:50:28 +010060
Paul Sokolovskyb9b93542014-06-07 23:40:04 +030061#ifdef MICROPY_PY_SYS_PLATFORM
Damien George30dd23a2014-08-10 17:50:28 +010062/// \constant platform - the platform that Micro Python is running on
Paul Sokolovskyb9b93542014-06-07 23:40:04 +030063STATIC const MP_DEFINE_STR_OBJ(platform_obj, MICROPY_PY_SYS_PLATFORM);
64#endif
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030065
Damien Georgeb92cbe62014-09-15 15:53:09 +010066/// \function exit([retval])
67/// Raise a `SystemExit` exception. If an argument is given, it is the
68/// value given to `SystemExit`.
69STATIC mp_obj_t mp_sys_exit(mp_uint_t n_args, const mp_obj_t *args) {
70 mp_obj_t exc;
71 if (n_args == 0) {
72 exc = mp_obj_new_exception(&mp_type_SystemExit);
73 } else {
74 exc = mp_obj_new_exception_arg1(&mp_type_SystemExit, args[0]);
75 }
76 nlr_raise(exc);
77}
78MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_exit_obj, 0, 1, mp_sys_exit);
79
Paul Sokolovsky46c3ab22014-12-06 14:29:09 +020080STATIC mp_obj_t mp_sys_print_exception(mp_uint_t n_args, const mp_obj_t *args) {
81 #if MICROPY_PY_IO
82 mp_obj_t stream_obj = &mp_sys_stdout_obj;
83 if (n_args > 1) {
84 stream_obj = args[1];
85 }
86
87 pfenv_t pfenv;
88 pfenv.data = stream_obj;
89 pfenv.print_strn = (void (*)(void *, const char *, mp_uint_t))mp_stream_write;
90 mp_obj_print_exception((void (*)(void *env, const char *fmt, ...))pfenv_printf, &pfenv, args[0]);
91 #else
92 mp_obj_print_exception(printf_wrapper, NULL, args[0]);
93 #endif
94
95 return mp_const_none;
96}
97MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_print_exception_obj, 1, 2, mp_sys_print_exception);
98
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030099STATIC const mp_map_elem_t mp_module_sys_globals_table[] = {
100 { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_sys) },
Paul Sokolovskyd99e9082014-05-10 16:50:45 +0300101
Paul Sokolovsky5500cde2014-04-13 06:43:18 +0300102 { MP_OBJ_NEW_QSTR(MP_QSTR_path), (mp_obj_t)&mp_sys_path_obj },
103 { MP_OBJ_NEW_QSTR(MP_QSTR_argv), (mp_obj_t)&mp_sys_argv_obj },
Paul Sokolovskybbae42d2014-04-14 01:46:45 +0300104 { MP_OBJ_NEW_QSTR(MP_QSTR_version), (mp_obj_t)&version_obj },
Paul Sokolovskybaaaf652014-04-13 09:46:58 +0300105 { MP_OBJ_NEW_QSTR(MP_QSTR_version_info), (mp_obj_t)&mp_sys_version_info_obj },
Paul Sokolovskyb9b93542014-06-07 23:40:04 +0300106#ifdef MICROPY_PY_SYS_PLATFORM
107 { MP_OBJ_NEW_QSTR(MP_QSTR_platform), (mp_obj_t)&platform_obj },
108#endif
Damien George30dd23a2014-08-10 17:50:28 +0100109 /// \constant byteorder - the byte order of the system ("little" or "big")
Paul Sokolovsky978d2c02014-04-13 09:53:52 +0300110#if MP_ENDIANNESS_LITTLE
111 { MP_OBJ_NEW_QSTR(MP_QSTR_byteorder), MP_OBJ_NEW_QSTR(MP_QSTR_little) },
112#else
113 { MP_OBJ_NEW_QSTR(MP_QSTR_byteorder), MP_OBJ_NEW_QSTR(MP_QSTR_big) },
114#endif
Paul Sokolovsky4e0eeeb2014-07-03 16:50:11 +0300115#if MICROPY_PY_SYS_MAXSIZE
116 #if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE
117 // INT_MAX is not representable as small int, as we know that small int
118 // takes one bit for tag. So, we have little choice but to provide this
119 // value. Apps also should be careful to not try to compare sys.maxsize
120 // with some number (which may not fit in available int size), but instead
121 // count number of significant bits in sys.maxsize.
122 { MP_OBJ_NEW_QSTR(MP_QSTR_maxsize), MP_OBJ_NEW_SMALL_INT(INT_MAX >> 1) },
123 #else
124 { MP_OBJ_NEW_QSTR(MP_QSTR_maxsize), (mp_obj_t)&mp_maxsize_obj },
125 #endif
126#endif
127
Damien Georgeee3fd462014-05-24 23:03:12 +0100128#if MICROPY_PY_SYS_EXIT
Damien George30dd23a2014-08-10 17:50:28 +0100129 // documented per-port
Damien George89755ae2014-05-11 17:35:43 +0100130 { MP_OBJ_NEW_QSTR(MP_QSTR_exit), (mp_obj_t)&mp_sys_exit_obj },
131#endif
132
Damien Georgeee3fd462014-05-24 23:03:12 +0100133#if MICROPY_PY_SYS_STDFILES
Damien George30dd23a2014-08-10 17:50:28 +0100134 // documented per-port
Paul Sokolovsky5500cde2014-04-13 06:43:18 +0300135 { MP_OBJ_NEW_QSTR(MP_QSTR_stdin), (mp_obj_t)&mp_sys_stdin_obj },
136 { MP_OBJ_NEW_QSTR(MP_QSTR_stdout), (mp_obj_t)&mp_sys_stdout_obj },
137 { MP_OBJ_NEW_QSTR(MP_QSTR_stderr), (mp_obj_t)&mp_sys_stderr_obj },
Paul Sokolovsky4165cd12014-04-13 07:00:37 +0300138#endif
Paul Sokolovsky46c3ab22014-12-06 14:29:09 +0200139
140 /*
141 * Extensions to CPython
142 */
143
144 { MP_OBJ_NEW_QSTR(MP_QSTR_print_exception), (mp_obj_t)&mp_sys_print_exception_obj },
Paul Sokolovsky5500cde2014-04-13 06:43:18 +0300145};
146
Damien George3b603f22014-11-29 14:39:27 +0000147STATIC MP_DEFINE_CONST_DICT(mp_module_sys_globals, mp_module_sys_globals_table);
Paul Sokolovsky5500cde2014-04-13 06:43:18 +0300148
149const mp_obj_module_t mp_module_sys = {
150 .base = { &mp_type_module },
151 .name = MP_QSTR_sys,
152 .globals = (mp_obj_dict_t*)&mp_module_sys_globals,
153};
154
155#endif