1 | /* |
2 | * This file is part of the MicroPython project, http://micropython.org/ |
3 | * |
4 | * The MIT License (MIT) |
5 | * |
6 | * Copyright (c) 2016 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 | |
27 | #include <assert.h> |
28 | #include <string.h> |
29 | |
30 | #include "py/obj.h" |
31 | #include "py/mperrno.h" |
32 | |
33 | #if MICROPY_PY_UERRNO |
34 | |
35 | // This list can be defined per port in mpconfigport.h to tailor it to a |
36 | // specific port's needs. If it's not defined then we provide a default. |
37 | #ifndef MICROPY_PY_UERRNO_LIST |
38 | #define MICROPY_PY_UERRNO_LIST \ |
39 | X(EPERM) \ |
40 | X(ENOENT) \ |
41 | X(EIO) \ |
42 | X(EBADF) \ |
43 | X(EAGAIN) \ |
44 | X(ENOMEM) \ |
45 | X(EACCES) \ |
46 | X(EEXIST) \ |
47 | X(ENODEV) \ |
48 | X(EISDIR) \ |
49 | X(EINVAL) \ |
50 | X(EOPNOTSUPP) \ |
51 | X(EADDRINUSE) \ |
52 | X(ECONNABORTED) \ |
53 | X(ECONNRESET) \ |
54 | X(ENOBUFS) \ |
55 | X(ENOTCONN) \ |
56 | X(ETIMEDOUT) \ |
57 | X(ECONNREFUSED) \ |
58 | X(EHOSTUNREACH) \ |
59 | X(EALREADY) \ |
60 | X(EINPROGRESS) \ |
61 | |
62 | #endif |
63 | |
64 | #if MICROPY_PY_UERRNO_ERRORCODE |
65 | STATIC const mp_rom_map_elem_t errorcode_table[] = { |
66 | #define X(e) { MP_ROM_INT(MP_##e), MP_ROM_QSTR(MP_QSTR_##e) }, |
67 | MICROPY_PY_UERRNO_LIST |
68 | #undef X |
69 | }; |
70 | |
71 | STATIC const mp_obj_dict_t errorcode_dict = { |
72 | .base = {&mp_type_dict}, |
73 | .map = { |
74 | .all_keys_are_qstrs = 0, // keys are integers |
75 | .is_fixed = 1, |
76 | .is_ordered = 1, |
77 | .used = MP_ARRAY_SIZE(errorcode_table), |
78 | .alloc = MP_ARRAY_SIZE(errorcode_table), |
79 | .table = (mp_map_elem_t *)(mp_rom_map_elem_t *)errorcode_table, |
80 | }, |
81 | }; |
82 | #endif |
83 | |
84 | STATIC const mp_rom_map_elem_t mp_module_uerrno_globals_table[] = { |
85 | { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uerrno) }, |
86 | #if MICROPY_PY_UERRNO_ERRORCODE |
87 | { MP_ROM_QSTR(MP_QSTR_errorcode), MP_ROM_PTR(&errorcode_dict) }, |
88 | #endif |
89 | |
90 | #define X(e) { MP_ROM_QSTR(MP_QSTR_##e), MP_ROM_INT(MP_##e) }, |
91 | MICROPY_PY_UERRNO_LIST |
92 | #undef X |
93 | }; |
94 | |
95 | STATIC MP_DEFINE_CONST_DICT(mp_module_uerrno_globals, mp_module_uerrno_globals_table); |
96 | |
97 | const mp_obj_module_t mp_module_uerrno = { |
98 | .base = { &mp_type_module }, |
99 | .globals = (mp_obj_dict_t *)&mp_module_uerrno_globals, |
100 | }; |
101 | |
102 | qstr mp_errno_to_str(mp_obj_t errno_val) { |
103 | #if MICROPY_PY_UERRNO_ERRORCODE |
104 | // We have the errorcode dict so can do a lookup using the hash map |
105 | mp_map_elem_t *elem = mp_map_lookup((mp_map_t *)&errorcode_dict.map, errno_val, MP_MAP_LOOKUP); |
106 | if (elem == NULL) { |
107 | return MP_QSTRnull; |
108 | } else { |
109 | return MP_OBJ_QSTR_VALUE(elem->value); |
110 | } |
111 | #else |
112 | // We don't have the errorcode dict so do a simple search in the modules dict |
113 | for (size_t i = 0; i < MP_ARRAY_SIZE(mp_module_uerrno_globals_table); ++i) { |
114 | if (errno_val == mp_module_uerrno_globals_table[i].value) { |
115 | return MP_OBJ_QSTR_VALUE(mp_module_uerrno_globals_table[i].key); |
116 | } |
117 | } |
118 | return MP_QSTRnull; |
119 | #endif |
120 | } |
121 | |
122 | #endif // MICROPY_PY_UERRNO |
123 | |