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 
mp_errno_to_str(mp_obj_t errno_val)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