23
23
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
24
* THE SOFTWARE.
25
25
*/
26
+ #include <string.h>
27
+
26
28
#include "py/obj.h"
27
29
#include "py/runtime.h"
28
30
#include "py/reload.h"
31
+ #include "py/objstr.h"
29
32
30
33
#include "lib/utils/interrupt_char.h"
31
34
#include "supervisor/shared/autoreload.h"
@@ -109,6 +112,87 @@ STATIC mp_obj_t supervisor_set_next_stack_limit(mp_obj_t size_obj) {
109
112
}
110
113
MP_DEFINE_CONST_FUN_OBJ_1 (supervisor_set_next_stack_limit_obj , supervisor_set_next_stack_limit );
111
114
115
+ //| def set_next_code_file(filename: Optional[str], *, reload_on_success : bool = False, reload_on_error: bool = False, sticky_on_success: bool = False, sticky_on_error: bool = False, sticky_on_reload: bool = False) -> None:
116
+ //| """Set what file to run on the next vm run.
117
+ //|
118
+ //| When not ``None``, the given ``filename`` is inserted at the front of the usual ['code.py',
119
+ //| 'main.py'] search sequence.
120
+ //|
121
+ //| The optional keyword arguments specify what happens after the specified file has run:
122
+ //|
123
+ //| ``sticky_on_…`` determine whether the newly set filename and options stay in effect: If
124
+ //| True, further runs will continue to run that file (unless it says otherwise by calling
125
+ //| ``set_next_code_filename()`` itself). If False, the settings will only affect one run and
126
+ //| revert to the standard code.py/main.py afterwards.
127
+ //|
128
+ //| ``reload_on_…`` determine how to continue: If False, wait in the usual "Code done running.
129
+ //| Waiting for reload. / Press any key to enter the REPL. Use CTRL-D to reload." state. If
130
+ //| True, reload immediately as if CTRL-D was pressed.
131
+ //|
132
+ //| ``…_on_success`` take effect when the program runs to completion or calls ``sys.exit()``.
133
+ //|
134
+ //| ``…_on_error`` take effect when the program exits with an exception, including the
135
+ //| KeyboardInterrupt caused by CTRL-C.
136
+ //|
137
+ //| ``…_on_reload`` take effect when the program is interrupted by files being written to the USB
138
+ //| drive (auto-reload) or when it calls ``supervisor.reload()``.
139
+ //|
140
+ //| These settings are stored in RAM, not in persistent memory, and will therefore only affect
141
+ //| soft reloads. Powering off or resetting the device will always revert to standard settings.
142
+ //|
143
+ //| When called multiple times in the same run, only the last call takes effect, replacing any
144
+ //| settings made by previous ones. This is the main use of passing ``None`` as a filename: to
145
+ //| reset to the standard search sequence."""
146
+ //| ...
147
+ //|
148
+ STATIC mp_obj_t supervisor_set_next_code_file (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
149
+ static const mp_arg_t allowed_args [] = {
150
+ { MP_QSTR_filename , MP_ARG_REQUIRED | MP_ARG_OBJ , {.u_rom_obj = mp_const_none } },
151
+ { MP_QSTR_reload_on_success , MP_ARG_KW_ONLY | MP_ARG_BOOL , {.u_bool = false} },
152
+ { MP_QSTR_reload_on_error , MP_ARG_KW_ONLY | MP_ARG_BOOL , {.u_bool = false} },
153
+ { MP_QSTR_sticky_on_success , MP_ARG_KW_ONLY | MP_ARG_BOOL , {.u_bool = false} },
154
+ { MP_QSTR_sticky_on_error , MP_ARG_KW_ONLY | MP_ARG_BOOL , {.u_bool = false} },
155
+ { MP_QSTR_sticky_on_reload , MP_ARG_KW_ONLY | MP_ARG_BOOL , {.u_bool = false} },
156
+ };
157
+ struct {
158
+ mp_arg_val_t filename ;
159
+ mp_arg_val_t reload_on_success ;
160
+ mp_arg_val_t reload_on_error ;
161
+ mp_arg_val_t sticky_on_success ;
162
+ mp_arg_val_t sticky_on_error ;
163
+ mp_arg_val_t sticky_on_reload ;
164
+ } args ;
165
+ mp_arg_parse_all (n_args , pos_args , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , (mp_arg_val_t * )& args );
166
+ if (!MP_OBJ_IS_STR_OR_BYTES (args .filename .u_obj ) && args .filename .u_obj != mp_const_none ) {
167
+ mp_raise_TypeError (translate ("argument has wrong type" ));
168
+ }
169
+ if (args .filename .u_obj == mp_const_none ) args .filename .u_obj = mp_const_empty_bytes ;
170
+ uint8_t options = 0 ;
171
+ if (args .reload_on_success .u_bool ) options |= SUPERVISOR_NEXT_CODE_OPT_RELOAD_ON_SUCCESS ;
172
+ if (args .reload_on_error .u_bool ) options |= SUPERVISOR_NEXT_CODE_OPT_RELOAD_ON_ERROR ;
173
+ if (args .sticky_on_success .u_bool ) options |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_SUCCESS ;
174
+ if (args .sticky_on_error .u_bool ) options |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_ERROR ;
175
+ if (args .sticky_on_reload .u_bool ) options |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_RELOAD ;
176
+ size_t len ;
177
+ const char * filename = mp_obj_str_get_data (args .filename .u_obj , & len );
178
+ free_memory (next_code_allocation );
179
+ if (options != 0 || len != 0 ) {
180
+ next_code_allocation = allocate_memory (align32_size (sizeof (next_code_info_t ) + len + 1 ), false, true);
181
+ if (next_code_allocation == NULL ) {
182
+ m_malloc_fail (sizeof (next_code_info_t ) + len + 1 );
183
+ }
184
+ next_code_info_t * next_code = (next_code_info_t * )next_code_allocation -> ptr ;
185
+ next_code -> options = options | SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET ;
186
+ memcpy (& next_code -> filename , filename , len );
187
+ next_code -> filename [len ] = '\0' ;
188
+ }
189
+ else {
190
+ next_code_allocation = NULL ;
191
+ }
192
+ return mp_const_none ;
193
+ }
194
+ MP_DEFINE_CONST_FUN_OBJ_KW (supervisor_set_next_code_file_obj , 0 , supervisor_set_next_code_file );
195
+
112
196
STATIC const mp_rom_map_elem_t supervisor_module_globals_table [] = {
113
197
{ MP_ROM_QSTR (MP_QSTR___name__ ), MP_ROM_QSTR (MP_QSTR_supervisor ) },
114
198
{ MP_OBJ_NEW_QSTR (MP_QSTR_enable_autoreload ), MP_ROM_PTR (& supervisor_enable_autoreload_obj ) },
@@ -117,7 +201,7 @@ STATIC const mp_rom_map_elem_t supervisor_module_globals_table[] = {
117
201
{ MP_ROM_QSTR (MP_QSTR_runtime ), MP_ROM_PTR (& common_hal_supervisor_runtime_obj ) },
118
202
{ MP_ROM_QSTR (MP_QSTR_reload ), MP_ROM_PTR (& supervisor_reload_obj ) },
119
203
{ MP_ROM_QSTR (MP_QSTR_set_next_stack_limit ), MP_ROM_PTR (& supervisor_set_next_stack_limit_obj ) },
120
-
204
+ { MP_ROM_QSTR ( MP_QSTR_set_next_code_file ), MP_ROM_PTR ( & supervisor_set_next_code_file_obj ) },
121
205
};
122
206
123
207
STATIC MP_DEFINE_CONST_DICT (supervisor_module_globals , supervisor_module_globals_table );
0 commit comments