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