1 | /* |
2 | * This file is part of the MicroPython project, http://micropython.org/ |
3 | * |
4 | * The MIT License (MIT) |
5 | * |
6 | * Copyright (c) 2015 Paul Sokolovsky |
7 | * Copyright (c) 2016 Damien P. George |
8 | * |
9 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
10 | * of this software and associated documentation files (the "Software"), to deal |
11 | * in the Software without restriction, including without limitation the rights |
12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
13 | * copies of the Software, and to permit persons to whom the Software is |
14 | * furnished to do so, subject to the following conditions: |
15 | * |
16 | * The above copyright notice and this permission notice shall be included in |
17 | * all copies or substantial portions of the Software. |
18 | * |
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
25 | * THE SOFTWARE. |
26 | */ |
27 | |
28 | #include <string.h> |
29 | #include <stdint.h> |
30 | |
31 | #include "py/lexer.h" |
32 | #include "py/frozenmod.h" |
33 | |
34 | #if MICROPY_MODULE_FROZEN_STR |
35 | |
36 | #ifndef MICROPY_MODULE_FROZEN_LEXER |
37 | #define MICROPY_MODULE_FROZEN_LEXER mp_lexer_new_from_str_len |
38 | #else |
39 | mp_lexer_t *MICROPY_MODULE_FROZEN_LEXER(qstr src_name, const char *str, mp_uint_t len, mp_uint_t free_len); |
40 | #endif |
41 | |
42 | extern const char mp_frozen_str_names[]; |
43 | extern const uint32_t mp_frozen_str_sizes[]; |
44 | extern const char mp_frozen_str_content[]; |
45 | |
46 | // On input, *len contains size of name, on output - size of content |
47 | const char *mp_find_frozen_str(const char *str, size_t *len) { |
48 | const char *name = mp_frozen_str_names; |
49 | |
50 | size_t offset = 0; |
51 | for (int i = 0; *name != 0; i++) { |
52 | size_t l = strlen(name); |
53 | if (l == *len && !memcmp(str, name, l)) { |
54 | *len = mp_frozen_str_sizes[i]; |
55 | return mp_frozen_str_content + offset; |
56 | } |
57 | name += l + 1; |
58 | offset += mp_frozen_str_sizes[i] + 1; |
59 | } |
60 | return NULL; |
61 | } |
62 | |
63 | STATIC mp_lexer_t *mp_lexer_frozen_str(const char *str, size_t len) { |
64 | size_t name_len = len; |
65 | const char *content = mp_find_frozen_str(str, &len); |
66 | |
67 | if (content == NULL) { |
68 | return NULL; |
69 | } |
70 | |
71 | qstr source = qstr_from_strn(str, name_len); |
72 | mp_lexer_t *lex = MICROPY_MODULE_FROZEN_LEXER(source, content, len, 0); |
73 | return lex; |
74 | } |
75 | |
76 | #endif |
77 | |
78 | #if MICROPY_MODULE_FROZEN_MPY |
79 | |
80 | #include "py/emitglue.h" |
81 | |
82 | extern const char mp_frozen_mpy_names[]; |
83 | extern const mp_raw_code_t *const mp_frozen_mpy_content[]; |
84 | |
85 | STATIC const mp_raw_code_t *mp_find_frozen_mpy(const char *str, size_t len) { |
86 | const char *name = mp_frozen_mpy_names; |
87 | for (size_t i = 0; *name != 0; i++) { |
88 | size_t l = strlen(name); |
89 | if (l == len && !memcmp(str, name, l)) { |
90 | return mp_frozen_mpy_content[i]; |
91 | } |
92 | name += l + 1; |
93 | } |
94 | return NULL; |
95 | } |
96 | |
97 | #endif |
98 | |
99 | #if MICROPY_MODULE_FROZEN |
100 | |
101 | STATIC mp_import_stat_t mp_frozen_stat_helper(const char *name, const char *str) { |
102 | size_t len = strlen(str); |
103 | |
104 | for (int i = 0; *name != 0; i++) { |
105 | size_t l = strlen(name); |
106 | if (l >= len && !memcmp(str, name, len)) { |
107 | if (name[len] == 0) { |
108 | return MP_IMPORT_STAT_FILE; |
109 | } else if (name[len] == '/') { |
110 | return MP_IMPORT_STAT_DIR; |
111 | } |
112 | } |
113 | name += l + 1; |
114 | } |
115 | return MP_IMPORT_STAT_NO_EXIST; |
116 | } |
117 | |
118 | mp_import_stat_t mp_frozen_stat(const char *str) { |
119 | mp_import_stat_t stat; |
120 | |
121 | #if MICROPY_MODULE_FROZEN_STR |
122 | stat = mp_frozen_stat_helper(mp_frozen_str_names, str); |
123 | if (stat != MP_IMPORT_STAT_NO_EXIST) { |
124 | return stat; |
125 | } |
126 | #endif |
127 | |
128 | #if MICROPY_MODULE_FROZEN_MPY |
129 | stat = mp_frozen_stat_helper(mp_frozen_mpy_names, str); |
130 | if (stat != MP_IMPORT_STAT_NO_EXIST) { |
131 | return stat; |
132 | } |
133 | #endif |
134 | |
135 | return MP_IMPORT_STAT_NO_EXIST; |
136 | } |
137 | |
138 | int mp_find_frozen_module(const char *str, size_t len, void **data) { |
139 | #if MICROPY_MODULE_FROZEN_STR |
140 | mp_lexer_t *lex = mp_lexer_frozen_str(str, len); |
141 | if (lex != NULL) { |
142 | *data = lex; |
143 | return MP_FROZEN_STR; |
144 | } |
145 | #endif |
146 | #if MICROPY_MODULE_FROZEN_MPY |
147 | const mp_raw_code_t *rc = mp_find_frozen_mpy(str, len); |
148 | if (rc != NULL) { |
149 | *data = (void *)rc; |
150 | return MP_FROZEN_MPY; |
151 | } |
152 | #endif |
153 | return MP_FROZEN_NONE; |
154 | } |
155 | |
156 | #endif |
157 | |