blob: 5051e729518e3d5b51019d54abf7957a447dd055 [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 Georgee1e359f2015-02-07 17:24:10 +000027#include "py/mpstate.h"
Damien George51dfcb42015-01-01 20:27:54 +000028#include "py/nlr.h"
29#include "py/builtin.h"
30#include "py/objlist.h"
31#include "py/objtuple.h"
32#include "py/objstr.h"
33#include "py/objint.h"
34#include "py/pfenv.h"
35#include "py/stream.h"
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030036
Damien Georgeee3fd462014-05-24 23:03:12 +010037#if MICROPY_PY_SYS
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030038
Damien George30dd23a2014-08-10 17:50:28 +010039/// \module sys - system specific functions
40
Damien Georgecd342072015-01-12 22:30:49 +000041// defined per port; type of these is irrelevant, just need pointer
stijne50cff62015-04-09 12:27:15 +020042extern struct _mp_dummy_t mp_sys_stdin_obj;
43extern struct _mp_dummy_t mp_sys_stdout_obj;
44extern struct _mp_dummy_t mp_sys_stderr_obj;
Damien Georgecd342072015-01-12 22:30:49 +000045
Damien George30dd23a2014-08-10 17:50:28 +010046/// \constant version - Python language version that this implementation conforms to, as a string
47STATIC const MP_DEFINE_STR_OBJ(version_obj, "3.4.0");
48
Damien George4ef26c12014-08-10 17:53:43 +010049/// \constant version_info - Python language version that this implementation conforms to, as a tuple of ints
Paul Sokolovskybaaaf652014-04-13 09:46:58 +030050#define I(n) MP_OBJ_NEW_SMALL_INT(n)
51// TODO: CPython is now at 5-element array, but save 2 els so far...
Paul Sokolovskybbae42d2014-04-14 01:46:45 +030052STATIC 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 +030053#undef I
Damien George30dd23a2014-08-10 17:50:28 +010054
Paul Sokolovskyb9b93542014-06-07 23:40:04 +030055#ifdef MICROPY_PY_SYS_PLATFORM
Damien George30dd23a2014-08-10 17:50:28 +010056/// \constant platform - the platform that Micro Python is running on
Paul Sokolovskyb9b93542014-06-07 23:40:04 +030057STATIC const MP_DEFINE_STR_OBJ(platform_obj, MICROPY_PY_SYS_PLATFORM);
58#endif
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030059
Damien Georgeb92cbe62014-09-15 15:53:09 +010060/// \function exit([retval])
61/// Raise a `SystemExit` exception. If an argument is given, it is the
62/// value given to `SystemExit`.
63STATIC mp_obj_t mp_sys_exit(mp_uint_t n_args, const mp_obj_t *args) {
64 mp_obj_t exc;
65 if (n_args == 0) {
66 exc = mp_obj_new_exception(&mp_type_SystemExit);
67 } else {
68 exc = mp_obj_new_exception_arg1(&mp_type_SystemExit, args[0]);
69 }
70 nlr_raise(exc);
71}
72MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_exit_obj, 0, 1, mp_sys_exit);
73
Paul Sokolovsky46c3ab22014-12-06 14:29:09 +020074STATIC mp_obj_t mp_sys_print_exception(mp_uint_t n_args, const mp_obj_t *args) {
75 #if MICROPY_PY_IO
76 mp_obj_t stream_obj = &mp_sys_stdout_obj;
77 if (n_args > 1) {
78 stream_obj = args[1];
79 }
80
81 pfenv_t pfenv;
82 pfenv.data = stream_obj;
83 pfenv.print_strn = (void (*)(void *, const char *, mp_uint_t))mp_stream_write;
84 mp_obj_print_exception((void (*)(void *env, const char *fmt, ...))pfenv_printf, &pfenv, args[0]);
85 #else
86 mp_obj_print_exception(printf_wrapper, NULL, args[0]);
87 #endif
88
89 return mp_const_none;
90}
91MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_print_exception_obj, 1, 2, mp_sys_print_exception);
92
Paul Sokolovsky5500cde2014-04-13 06:43:18 +030093STATIC const mp_map_elem_t mp_module_sys_globals_table[] = {
94 { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_sys) },
Paul Sokolovskyd99e9082014-05-10 16:50:45 +030095
Damien Georgee1e359f2015-02-07 17:24:10 +000096 { MP_OBJ_NEW_QSTR(MP_QSTR_path), (mp_obj_t)&MP_STATE_VM(mp_sys_path_obj) },
97 { MP_OBJ_NEW_QSTR(MP_QSTR_argv), (mp_obj_t)&MP_STATE_VM(mp_sys_argv_obj) },
Paul Sokolovskybbae42d2014-04-14 01:46:45 +030098 { MP_OBJ_NEW_QSTR(MP_QSTR_version), (mp_obj_t)&version_obj },
Paul Sokolovskybaaaf652014-04-13 09:46:58 +030099 { MP_OBJ_NEW_QSTR(MP_QSTR_version_info), (mp_obj_t)&mp_sys_version_info_obj },
Paul Sokolovskyb9b93542014-06-07 23:40:04 +0300100#ifdef MICROPY_PY_SYS_PLATFORM
101 { MP_OBJ_NEW_QSTR(MP_QSTR_platform), (mp_obj_t)&platform_obj },
102#endif
Damien George30dd23a2014-08-10 17:50:28 +0100103 /// \constant byteorder - the byte order of the system ("little" or "big")
Paul Sokolovsky978d2c02014-04-13 09:53:52 +0300104#if MP_ENDIANNESS_LITTLE
105 { MP_OBJ_NEW_QSTR(MP_QSTR_byteorder), MP_OBJ_NEW_QSTR(MP_QSTR_little) },
106#else
107 { MP_OBJ_NEW_QSTR(MP_QSTR_byteorder), MP_OBJ_NEW_QSTR(MP_QSTR_big) },
108#endif
Paul Sokolovsky4e0eeeb2014-07-03 16:50:11 +0300109#if MICROPY_PY_SYS_MAXSIZE
110 #if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE
111 // INT_MAX is not representable as small int, as we know that small int
112 // takes one bit for tag. So, we have little choice but to provide this
113 // value. Apps also should be careful to not try to compare sys.maxsize
114 // with some number (which may not fit in available int size), but instead
115 // count number of significant bits in sys.maxsize.
116 { MP_OBJ_NEW_QSTR(MP_QSTR_maxsize), MP_OBJ_NEW_SMALL_INT(INT_MAX >> 1) },
117 #else
118 { MP_OBJ_NEW_QSTR(MP_QSTR_maxsize), (mp_obj_t)&mp_maxsize_obj },
119 #endif
120#endif
121
Damien Georgeee3fd462014-05-24 23:03:12 +0100122#if MICROPY_PY_SYS_EXIT
Damien George30dd23a2014-08-10 17:50:28 +0100123 // documented per-port
Damien George89755ae2014-05-11 17:35:43 +0100124 { MP_OBJ_NEW_QSTR(MP_QSTR_exit), (mp_obj_t)&mp_sys_exit_obj },
125#endif
126
Damien Georgeee3fd462014-05-24 23:03:12 +0100127#if MICROPY_PY_SYS_STDFILES
Damien George30dd23a2014-08-10 17:50:28 +0100128 // documented per-port
Paul Sokolovsky5500cde2014-04-13 06:43:18 +0300129 { MP_OBJ_NEW_QSTR(MP_QSTR_stdin), (mp_obj_t)&mp_sys_stdin_obj },
130 { MP_OBJ_NEW_QSTR(MP_QSTR_stdout), (mp_obj_t)&mp_sys_stdout_obj },
131 { MP_OBJ_NEW_QSTR(MP_QSTR_stderr), (mp_obj_t)&mp_sys_stderr_obj },
Paul Sokolovsky4165cd12014-04-13 07:00:37 +0300132#endif
Paul Sokolovsky46c3ab22014-12-06 14:29:09 +0200133
134 /*
135 * Extensions to CPython
136 */
137
138 { MP_OBJ_NEW_QSTR(MP_QSTR_print_exception), (mp_obj_t)&mp_sys_print_exception_obj },
Paul Sokolovsky5500cde2014-04-13 06:43:18 +0300139};
140
Damien George3b603f22014-11-29 14:39:27 +0000141STATIC MP_DEFINE_CONST_DICT(mp_module_sys_globals, mp_module_sys_globals_table);
Paul Sokolovsky5500cde2014-04-13 06:43:18 +0300142
143const mp_obj_module_t mp_module_sys = {
144 .base = { &mp_type_module },
145 .name = MP_QSTR_sys,
146 .globals = (mp_obj_dict_t*)&mp_module_sys_globals,
147};
148
149#endif