Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 1 | /* |
| 2 | * This file is part of the MicroPython project, http://micropython.org/ |
| 3 | * |
| 4 | * The MIT License (MIT) |
| 5 | * |
Damien George | 2acc087 | 2020-07-29 01:01:48 +1000 | [diff] [blame] | 6 | * Copyright (c) 2019-2020 Damien P. George |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 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 | |
Damien George | a513558 | 2022-11-11 15:43:55 +1100 | [diff] [blame] | 27 | // This file should be compiled when included from vfs_lfs.c. |
| 28 | #if defined(LFS_BUILD_VERSION) |
| 29 | |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 30 | #include <stdio.h> |
| 31 | #include <string.h> |
| 32 | |
| 33 | #include "py/runtime.h" |
| 34 | #include "py/stream.h" |
| 35 | #include "py/binary.h" |
| 36 | #include "py/objarray.h" |
Damien George | 7dffbfd | 2020-05-14 21:37:59 +1000 | [diff] [blame] | 37 | #include "py/objstr.h" |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 38 | #include "py/mperrno.h" |
| 39 | #include "extmod/vfs.h" |
Damien George | 136369d | 2021-07-09 14:19:15 +1000 | [diff] [blame] | 40 | #include "shared/timeutils/timeutils.h" |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 41 | |
Andrew Leech | 4e0964b | 2022-09-09 09:48:01 +1000 | [diff] [blame] | 42 | #if !MICROPY_ENABLE_FINALISER |
| 43 | #error "MICROPY_VFS_LFS requires MICROPY_ENABLE_FINALISER" |
| 44 | #endif |
| 45 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 46 | static int MP_VFS_LFSx(dev_ioctl)(const struct LFSx_API (config) * c, int cmd, int arg, bool must_return_int) { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 47 | mp_obj_t ret = mp_vfs_blockdev_ioctl(c->context, cmd, arg); |
| 48 | int ret_i = 0; |
| 49 | if (must_return_int || ret != mp_const_none) { |
| 50 | ret_i = mp_obj_get_int(ret); |
| 51 | } |
| 52 | return ret_i; |
| 53 | } |
| 54 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 55 | static int MP_VFS_LFSx(dev_read)(const struct LFSx_API (config) * c, LFSx_API(block_t) block, LFSx_API(off_t) off, void *buffer, LFSx_API(size_t) size) { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 56 | return mp_vfs_blockdev_read_ext(c->context, block, off, size, buffer); |
| 57 | } |
| 58 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 59 | static int MP_VFS_LFSx(dev_prog)(const struct LFSx_API (config) * c, LFSx_API(block_t) block, LFSx_API(off_t) off, const void *buffer, LFSx_API(size_t) size) { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 60 | return mp_vfs_blockdev_write_ext(c->context, block, off, size, buffer); |
| 61 | } |
| 62 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 63 | static int MP_VFS_LFSx(dev_erase)(const struct LFSx_API (config) * c, LFSx_API(block_t) block) { |
Damien George | 4cf054a | 2019-10-29 12:29:56 +1100 | [diff] [blame] | 64 | return MP_VFS_LFSx(dev_ioctl)(c, MP_BLOCKDEV_IOCTL_BLOCK_ERASE, block, true); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 65 | } |
| 66 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 67 | static int MP_VFS_LFSx(dev_sync)(const struct LFSx_API (config) * c) { |
Damien George | cfe1c5a | 2019-10-29 12:25:30 +1100 | [diff] [blame] | 68 | return MP_VFS_LFSx(dev_ioctl)(c, MP_BLOCKDEV_IOCTL_SYNC, 0, false); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 69 | } |
| 70 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 71 | static void MP_VFS_LFSx(init_config)(MP_OBJ_VFS_LFSx * self, mp_obj_t bdev, size_t read_size, size_t prog_size, size_t lookahead) { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 72 | self->blockdev.flags = MP_BLOCKDEV_FLAG_FREE_OBJ; |
| 73 | mp_vfs_blockdev_init(&self->blockdev, bdev); |
| 74 | |
Damien George | 69661f3 | 2020-02-27 15:36:53 +1100 | [diff] [blame] | 75 | struct LFSx_API (config) * config = &self->config; |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 76 | memset(config, 0, sizeof(*config)); |
| 77 | |
| 78 | config->context = &self->blockdev; |
| 79 | |
| 80 | config->read = MP_VFS_LFSx(dev_read); |
| 81 | config->prog = MP_VFS_LFSx(dev_prog); |
| 82 | config->erase = MP_VFS_LFSx(dev_erase); |
| 83 | config->sync = MP_VFS_LFSx(dev_sync); |
| 84 | |
Damien George | 5634a31 | 2019-11-14 16:30:10 +1100 | [diff] [blame] | 85 | MP_VFS_LFSx(dev_ioctl)(config, MP_BLOCKDEV_IOCTL_INIT, 1, false); // initialise block device |
Damien George | cfe1c5a | 2019-10-29 12:25:30 +1100 | [diff] [blame] | 86 | int bs = MP_VFS_LFSx(dev_ioctl)(config, MP_BLOCKDEV_IOCTL_BLOCK_SIZE, 0, true); // get block size |
| 87 | int bc = MP_VFS_LFSx(dev_ioctl)(config, MP_BLOCKDEV_IOCTL_BLOCK_COUNT, 0, true); // get block count |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 88 | self->blockdev.block_size = bs; |
| 89 | |
| 90 | config->read_size = read_size; |
| 91 | config->prog_size = prog_size; |
| 92 | config->block_size = bs; |
| 93 | config->block_count = bc; |
| 94 | |
| 95 | #if LFS_BUILD_VERSION == 1 |
| 96 | config->lookahead = lookahead; |
| 97 | config->read_buffer = m_new(uint8_t, config->read_size); |
| 98 | config->prog_buffer = m_new(uint8_t, config->prog_size); |
| 99 | config->lookahead_buffer = m_new(uint8_t, config->lookahead / 8); |
| 100 | #else |
| 101 | config->block_cycles = 100; |
Peter Züger | ce42c9e | 2023-12-21 00:17:15 +0100 | [diff] [blame] | 102 | config->cache_size = MIN(config->block_size, (4 * MAX(read_size, prog_size))); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 103 | config->lookahead_size = lookahead; |
| 104 | config->read_buffer = m_new(uint8_t, config->cache_size); |
| 105 | config->prog_buffer = m_new(uint8_t, config->cache_size); |
| 106 | config->lookahead_buffer = m_new(uint8_t, config->lookahead_size); |
Andrew Leech | 6515cd0 | 2025-06-26 14:58:06 +1000 | [diff] [blame] | 107 | #ifdef LFS2_MULTIVERSION |
| 108 | // This can be set to override the on-disk lfs version. |
| 109 | // eg. for compat with lfs2 < v2.6 add the following to make: |
| 110 | // CFLAGS += '-DLFS2_MULTIVERSION=0x00020000' |
| 111 | config->disk_version = LFS2_MULTIVERSION; |
| 112 | #endif |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 113 | #endif |
| 114 | } |
| 115 | |
Damien George | 69661f3 | 2020-02-27 15:36:53 +1100 | [diff] [blame] | 116 | const char *MP_VFS_LFSx(make_path)(MP_OBJ_VFS_LFSx * self, mp_obj_t path_in) { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 117 | const char *path = mp_obj_str_get_str(path_in); |
| 118 | if (path[0] != '/') { |
| 119 | size_t l = vstr_len(&self->cur_dir); |
| 120 | if (l > 0) { |
| 121 | vstr_add_str(&self->cur_dir, path); |
| 122 | path = vstr_null_terminated_str(&self->cur_dir); |
| 123 | self->cur_dir.len = l; |
| 124 | } |
| 125 | } |
| 126 | return path; |
| 127 | } |
| 128 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 129 | static mp_obj_t MP_VFS_LFSx(make_new)(const mp_obj_type_t * type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 130 | mp_arg_val_t args[MP_ARRAY_SIZE(lfs_make_allowed_args)]; |
| 131 | mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(lfs_make_allowed_args), lfs_make_allowed_args, args); |
| 132 | |
| 133 | MP_OBJ_VFS_LFSx *self = m_new0(MP_OBJ_VFS_LFSx, 1); |
| 134 | self->base.type = type; |
| 135 | vstr_init(&self->cur_dir, 16); |
| 136 | vstr_add_byte(&self->cur_dir, '/'); |
Damien George | 2acc087 | 2020-07-29 01:01:48 +1000 | [diff] [blame] | 137 | #if LFS_BUILD_VERSION == 2 |
| 138 | self->enable_mtime = args[LFS_MAKE_ARG_mtime].u_bool; |
| 139 | #endif |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 140 | MP_VFS_LFSx(init_config)(self, args[LFS_MAKE_ARG_bdev].u_obj, |
| 141 | args[LFS_MAKE_ARG_readsize].u_int, args[LFS_MAKE_ARG_progsize].u_int, args[LFS_MAKE_ARG_lookahead].u_int); |
| 142 | int ret = LFSx_API(mount)(&self->lfs, &self->config); |
| 143 | if (ret < 0) { |
| 144 | mp_raise_OSError(-ret); |
| 145 | } |
| 146 | return MP_OBJ_FROM_PTR(self); |
| 147 | } |
| 148 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 149 | static mp_obj_t MP_VFS_LFSx(mkfs)(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 150 | mp_arg_val_t args[MP_ARRAY_SIZE(lfs_make_allowed_args)]; |
| 151 | mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(lfs_make_allowed_args), lfs_make_allowed_args, args); |
| 152 | |
| 153 | MP_OBJ_VFS_LFSx self; |
| 154 | MP_VFS_LFSx(init_config)(&self, args[LFS_MAKE_ARG_bdev].u_obj, |
| 155 | args[LFS_MAKE_ARG_readsize].u_int, args[LFS_MAKE_ARG_progsize].u_int, args[LFS_MAKE_ARG_lookahead].u_int); |
| 156 | int ret = LFSx_API(format)(&self.lfs, &self.config); |
| 157 | if (ret < 0) { |
| 158 | mp_raise_OSError(-ret); |
| 159 | } |
| 160 | return mp_const_none; |
| 161 | } |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 162 | static MP_DEFINE_CONST_FUN_OBJ_KW(MP_VFS_LFSx(mkfs_fun_obj), 0, MP_VFS_LFSx(mkfs)); |
| 163 | static MP_DEFINE_CONST_STATICMETHOD_OBJ(MP_VFS_LFSx(mkfs_obj), MP_ROM_PTR(&MP_VFS_LFSx(mkfs_fun_obj))); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 164 | |
| 165 | // Implementation of mp_vfs_lfs_file_open is provided in vfs_lfsx_file.c |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 166 | static MP_DEFINE_CONST_FUN_OBJ_3(MP_VFS_LFSx(open_obj), MP_VFS_LFSx(file_open)); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 167 | |
Damien George | 69661f3 | 2020-02-27 15:36:53 +1100 | [diff] [blame] | 168 | typedef struct MP_VFS_LFSx (_ilistdir_it_t) { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 169 | mp_obj_base_t base; |
| 170 | mp_fun_1_t iternext; |
Andrew Leech | 4e0964b | 2022-09-09 09:48:01 +1000 | [diff] [blame] | 171 | mp_fun_1_t finaliser; |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 172 | bool is_str; |
| 173 | MP_OBJ_VFS_LFSx *vfs; |
| 174 | LFSx_API(dir_t) dir; |
| 175 | } MP_VFS_LFSx(ilistdir_it_t); |
| 176 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 177 | static mp_obj_t MP_VFS_LFSx(ilistdir_it_iternext)(mp_obj_t self_in) { |
Damien George | 69661f3 | 2020-02-27 15:36:53 +1100 | [diff] [blame] | 178 | MP_VFS_LFSx(ilistdir_it_t) * self = MP_OBJ_TO_PTR(self_in); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 179 | |
Andrew Leech | 4e0964b | 2022-09-09 09:48:01 +1000 | [diff] [blame] | 180 | if (self->vfs == NULL) { |
| 181 | return MP_OBJ_STOP_ITERATION; |
| 182 | } |
| 183 | |
Damien George | 69661f3 | 2020-02-27 15:36:53 +1100 | [diff] [blame] | 184 | struct LFSx_API (info) info; |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 185 | for (;;) { |
| 186 | int ret = LFSx_API(dir_read)(&self->vfs->lfs, &self->dir, &info); |
| 187 | if (ret == 0) { |
| 188 | LFSx_API(dir_close)(&self->vfs->lfs, &self->dir); |
Andrew Leech | 4e0964b | 2022-09-09 09:48:01 +1000 | [diff] [blame] | 189 | self->vfs = NULL; |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 190 | return MP_OBJ_STOP_ITERATION; |
| 191 | } |
| 192 | if (!(info.name[0] == '.' && (info.name[1] == '\0' |
Damien George | 69661f3 | 2020-02-27 15:36:53 +1100 | [diff] [blame] | 193 | || (info.name[1] == '.' && info.name[2] == '\0')))) { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 194 | break; |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | // make 4-tuple with info about this entry |
| 199 | mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(4, NULL)); |
| 200 | if (self->is_str) { |
Jon Foster | 92484d8 | 2024-04-01 19:23:49 +0100 | [diff] [blame] | 201 | t->items[0] = mp_obj_new_str_from_cstr(info.name); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 202 | } else { |
Damien George | 69661f3 | 2020-02-27 15:36:53 +1100 | [diff] [blame] | 203 | t->items[0] = mp_obj_new_bytes((const byte *)info.name, strlen(info.name)); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 204 | } |
| 205 | t->items[1] = MP_OBJ_NEW_SMALL_INT(info.type == LFSx_MACRO(_TYPE_REG) ? MP_S_IFREG : MP_S_IFDIR); |
| 206 | t->items[2] = MP_OBJ_NEW_SMALL_INT(0); // no inode number |
| 207 | t->items[3] = MP_OBJ_NEW_SMALL_INT(info.size); |
| 208 | |
| 209 | return MP_OBJ_FROM_PTR(t); |
| 210 | } |
| 211 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 212 | static mp_obj_t MP_VFS_LFSx(ilistdir_it_del)(mp_obj_t self_in) { |
Andrew Leech | 4e0964b | 2022-09-09 09:48:01 +1000 | [diff] [blame] | 213 | MP_VFS_LFSx(ilistdir_it_t) * self = MP_OBJ_TO_PTR(self_in); |
| 214 | if (self->vfs != NULL) { |
| 215 | LFSx_API(dir_close)(&self->vfs->lfs, &self->dir); |
| 216 | } |
| 217 | return mp_const_none; |
| 218 | } |
| 219 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 220 | static mp_obj_t MP_VFS_LFSx(ilistdir_func)(size_t n_args, const mp_obj_t *args) { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 221 | MP_OBJ_VFS_LFSx *self = MP_OBJ_TO_PTR(args[0]); |
| 222 | bool is_str_type = true; |
| 223 | const char *path; |
| 224 | if (n_args == 2) { |
| 225 | if (mp_obj_get_type(args[1]) == &mp_type_bytes) { |
| 226 | is_str_type = false; |
| 227 | } |
| 228 | path = MP_VFS_LFSx(make_path)(self, args[1]); |
| 229 | } else { |
| 230 | path = vstr_null_terminated_str(&self->cur_dir); |
| 231 | } |
| 232 | |
Damien George | cae690d | 2024-02-16 11:02:58 +1100 | [diff] [blame] | 233 | MP_VFS_LFSx(ilistdir_it_t) * iter = mp_obj_malloc_with_finaliser(MP_VFS_LFSx(ilistdir_it_t), &mp_type_polymorph_iter_with_finaliser); |
Andrew Leech | 4e0964b | 2022-09-09 09:48:01 +1000 | [diff] [blame] | 234 | |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 235 | iter->iternext = MP_VFS_LFSx(ilistdir_it_iternext); |
Andrew Leech | 4e0964b | 2022-09-09 09:48:01 +1000 | [diff] [blame] | 236 | iter->finaliser = MP_VFS_LFSx(ilistdir_it_del); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 237 | iter->is_str = is_str_type; |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 238 | int ret = LFSx_API(dir_open)(&self->lfs, &iter->dir, path); |
| 239 | if (ret < 0) { |
| 240 | mp_raise_OSError(-ret); |
| 241 | } |
Andrew Leech | 4e0964b | 2022-09-09 09:48:01 +1000 | [diff] [blame] | 242 | iter->vfs = self; |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 243 | return MP_OBJ_FROM_PTR(iter); |
| 244 | } |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 245 | static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(MP_VFS_LFSx(ilistdir_obj), 1, 2, MP_VFS_LFSx(ilistdir_func)); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 246 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 247 | static mp_obj_t MP_VFS_LFSx(remove)(mp_obj_t self_in, mp_obj_t path_in) { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 248 | MP_OBJ_VFS_LFSx *self = MP_OBJ_TO_PTR(self_in); |
| 249 | const char *path = MP_VFS_LFSx(make_path)(self, path_in); |
| 250 | int ret = LFSx_API(remove)(&self->lfs, path); |
| 251 | if (ret < 0) { |
| 252 | mp_raise_OSError(-ret); |
| 253 | } |
| 254 | return mp_const_none; |
| 255 | } |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 256 | static MP_DEFINE_CONST_FUN_OBJ_2(MP_VFS_LFSx(remove_obj), MP_VFS_LFSx(remove)); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 257 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 258 | static mp_obj_t MP_VFS_LFSx(rmdir)(mp_obj_t self_in, mp_obj_t path_in) { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 259 | MP_OBJ_VFS_LFSx *self = MP_OBJ_TO_PTR(self_in); |
| 260 | const char *path = MP_VFS_LFSx(make_path)(self, path_in); |
| 261 | int ret = LFSx_API(remove)(&self->lfs, path); |
| 262 | if (ret < 0) { |
| 263 | mp_raise_OSError(-ret); |
| 264 | } |
| 265 | return mp_const_none; |
| 266 | } |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 267 | static MP_DEFINE_CONST_FUN_OBJ_2(MP_VFS_LFSx(rmdir_obj), MP_VFS_LFSx(rmdir)); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 268 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 269 | static mp_obj_t MP_VFS_LFSx(rename)(mp_obj_t self_in, mp_obj_t path_old_in, mp_obj_t path_new_in) { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 270 | MP_OBJ_VFS_LFSx *self = MP_OBJ_TO_PTR(self_in); |
| 271 | const char *path_old = MP_VFS_LFSx(make_path)(self, path_old_in); |
robert | 0f83ef3 | 2020-05-04 15:34:12 +0200 | [diff] [blame] | 272 | const char *path = mp_obj_str_get_str(path_new_in); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 273 | vstr_t path_new; |
| 274 | vstr_init(&path_new, vstr_len(&self->cur_dir)); |
robert | 0f83ef3 | 2020-05-04 15:34:12 +0200 | [diff] [blame] | 275 | if (path[0] != '/') { |
| 276 | vstr_add_strn(&path_new, vstr_str(&self->cur_dir), vstr_len(&self->cur_dir)); |
| 277 | } |
| 278 | vstr_add_str(&path_new, path); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 279 | int ret = LFSx_API(rename)(&self->lfs, path_old, vstr_null_terminated_str(&path_new)); |
| 280 | vstr_clear(&path_new); |
| 281 | if (ret < 0) { |
| 282 | mp_raise_OSError(-ret); |
| 283 | } |
| 284 | return mp_const_none; |
| 285 | } |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 286 | static MP_DEFINE_CONST_FUN_OBJ_3(MP_VFS_LFSx(rename_obj), MP_VFS_LFSx(rename)); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 287 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 288 | static mp_obj_t MP_VFS_LFSx(mkdir)(mp_obj_t self_in, mp_obj_t path_o) { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 289 | MP_OBJ_VFS_LFSx *self = MP_OBJ_TO_PTR(self_in); |
| 290 | const char *path = MP_VFS_LFSx(make_path)(self, path_o); |
| 291 | int ret = LFSx_API(mkdir)(&self->lfs, path); |
| 292 | if (ret < 0) { |
| 293 | mp_raise_OSError(-ret); |
| 294 | } |
| 295 | return mp_const_none; |
| 296 | } |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 297 | static MP_DEFINE_CONST_FUN_OBJ_2(MP_VFS_LFSx(mkdir_obj), MP_VFS_LFSx(mkdir)); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 298 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 299 | static mp_obj_t MP_VFS_LFSx(chdir)(mp_obj_t self_in, mp_obj_t path_in) { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 300 | MP_OBJ_VFS_LFSx *self = MP_OBJ_TO_PTR(self_in); |
| 301 | |
| 302 | // Check path exists |
| 303 | const char *path = MP_VFS_LFSx(make_path)(self, path_in); |
| 304 | if (path[1] != '\0') { |
| 305 | // Not at root, check it exists |
Damien George | 69661f3 | 2020-02-27 15:36:53 +1100 | [diff] [blame] | 306 | struct LFSx_API (info) info; |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 307 | int ret = LFSx_API(stat)(&self->lfs, path, &info); |
| 308 | if (ret < 0 || info.type != LFSx_MACRO(_TYPE_DIR)) { |
Damien George | 62d26bf | 2025-05-13 12:54:47 +1000 | [diff] [blame] | 309 | mp_raise_OSError(MP_ENOENT); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 310 | } |
| 311 | } |
| 312 | |
| 313 | // Update cur_dir with new path |
| 314 | if (path == vstr_str(&self->cur_dir)) { |
| 315 | self->cur_dir.len = strlen(path); |
| 316 | } else { |
| 317 | vstr_reset(&self->cur_dir); |
| 318 | vstr_add_str(&self->cur_dir, path); |
| 319 | } |
| 320 | |
| 321 | // If not at root add trailing / to make it easy to build paths |
robert | d3ea28d | 2020-05-03 21:05:08 +0200 | [diff] [blame] | 322 | // and then normalise the path |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 323 | if (vstr_len(&self->cur_dir) != 1) { |
| 324 | vstr_add_byte(&self->cur_dir, '/'); |
robert | d3ea28d | 2020-05-03 21:05:08 +0200 | [diff] [blame] | 325 | |
| 326 | #define CWD_LEN (vstr_len(&self->cur_dir)) |
| 327 | size_t to = 1; |
| 328 | size_t from = 1; |
| 329 | char *cwd = vstr_str(&self->cur_dir); |
| 330 | while (from < CWD_LEN) { |
Mingjie Shen | a9fc034 | 2023-04-20 18:20:37 -0400 | [diff] [blame] | 331 | for (; from < CWD_LEN && cwd[from] == '/'; ++from) { |
robert | d3ea28d | 2020-05-03 21:05:08 +0200 | [diff] [blame] | 332 | // Scan for the start |
| 333 | } |
| 334 | if (from > to) { |
| 335 | // Found excessive slash chars, squeeze them out |
| 336 | vstr_cut_out_bytes(&self->cur_dir, to, from - to); |
| 337 | from = to; |
| 338 | } |
Mingjie Shen | a9fc034 | 2023-04-20 18:20:37 -0400 | [diff] [blame] | 339 | for (; from < CWD_LEN && cwd[from] != '/'; ++from) { |
robert | d3ea28d | 2020-05-03 21:05:08 +0200 | [diff] [blame] | 340 | // Scan for the next / |
| 341 | } |
| 342 | if ((from - to) == 1 && cwd[to] == '.') { |
| 343 | // './', ignore |
| 344 | vstr_cut_out_bytes(&self->cur_dir, to, ++from - to); |
| 345 | from = to; |
| 346 | } else if ((from - to) == 2 && cwd[to] == '.' && cwd[to + 1] == '.') { |
| 347 | // '../', skip back |
| 348 | if (to > 1) { |
| 349 | // Only skip back if not at the tip |
| 350 | for (--to; to > 1 && cwd[to - 1] != '/'; --to) { |
| 351 | // Skip back |
| 352 | } |
| 353 | } |
| 354 | vstr_cut_out_bytes(&self->cur_dir, to, ++from - to); |
| 355 | from = to; |
| 356 | } else { |
| 357 | // Normal element, keep it and just move the offset |
| 358 | to = ++from; |
| 359 | } |
| 360 | } |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 361 | } |
| 362 | |
| 363 | return mp_const_none; |
| 364 | } |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 365 | static MP_DEFINE_CONST_FUN_OBJ_2(MP_VFS_LFSx(chdir_obj), MP_VFS_LFSx(chdir)); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 366 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 367 | static mp_obj_t MP_VFS_LFSx(getcwd)(mp_obj_t self_in) { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 368 | MP_OBJ_VFS_LFSx *self = MP_OBJ_TO_PTR(self_in); |
| 369 | if (vstr_len(&self->cur_dir) == 1) { |
| 370 | return MP_OBJ_NEW_QSTR(MP_QSTR__slash_); |
| 371 | } else { |
| 372 | // don't include trailing / |
| 373 | return mp_obj_new_str(self->cur_dir.buf, self->cur_dir.len - 1); |
| 374 | } |
| 375 | } |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 376 | static MP_DEFINE_CONST_FUN_OBJ_1(MP_VFS_LFSx(getcwd_obj), MP_VFS_LFSx(getcwd)); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 377 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 378 | static mp_obj_t MP_VFS_LFSx(stat)(mp_obj_t self_in, mp_obj_t path_in) { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 379 | MP_OBJ_VFS_LFSx *self = MP_OBJ_TO_PTR(self_in); |
robert | a5ea4b9 | 2020-04-29 18:13:22 +0200 | [diff] [blame] | 380 | const char *path = MP_VFS_LFSx(make_path)(self, path_in); |
Damien George | 69661f3 | 2020-02-27 15:36:53 +1100 | [diff] [blame] | 381 | struct LFSx_API (info) info; |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 382 | int ret = LFSx_API(stat)(&self->lfs, path, &info); |
| 383 | if (ret < 0) { |
| 384 | mp_raise_OSError(-ret); |
| 385 | } |
| 386 | |
Yoctopuce dev | df05cae | 2025-07-01 13:16:20 +0200 | [diff] [blame] | 387 | mp_timestamp_t mtime = 0; |
Damien George | 2acc087 | 2020-07-29 01:01:48 +1000 | [diff] [blame] | 388 | #if LFS_BUILD_VERSION == 2 |
| 389 | uint8_t mtime_buf[8]; |
| 390 | lfs2_ssize_t sz = lfs2_getattr(&self->lfs, path, LFS_ATTR_MTIME, &mtime_buf, sizeof(mtime_buf)); |
| 391 | if (sz == sizeof(mtime_buf)) { |
| 392 | uint64_t ns = 0; |
| 393 | for (size_t i = sizeof(mtime_buf); i > 0; --i) { |
| 394 | ns = ns << 8 | mtime_buf[i - 1]; |
| 395 | } |
Damien George | 8f20cdc | 2020-09-14 12:15:03 +1000 | [diff] [blame] | 396 | // On-disk storage of timestamps uses 1970 as the Epoch, so convert to host's Epoch. |
| 397 | mtime = timeutils_seconds_since_epoch_from_nanoseconds_since_1970(ns); |
Damien George | 2acc087 | 2020-07-29 01:01:48 +1000 | [diff] [blame] | 398 | } |
| 399 | #endif |
| 400 | |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 401 | mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL)); |
| 402 | t->items[0] = MP_OBJ_NEW_SMALL_INT(info.type == LFSx_MACRO(_TYPE_REG) ? MP_S_IFREG : MP_S_IFDIR); // st_mode |
| 403 | t->items[1] = MP_OBJ_NEW_SMALL_INT(0); // st_ino |
| 404 | t->items[2] = MP_OBJ_NEW_SMALL_INT(0); // st_dev |
| 405 | t->items[3] = MP_OBJ_NEW_SMALL_INT(0); // st_nlink |
| 406 | t->items[4] = MP_OBJ_NEW_SMALL_INT(0); // st_uid |
| 407 | t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // st_gid |
| 408 | t->items[6] = mp_obj_new_int_from_uint(info.size); // st_size |
Yoctopuce dev | df05cae | 2025-07-01 13:16:20 +0200 | [diff] [blame] | 409 | t->items[7] = timeutils_obj_from_timestamp(mtime); // st_atime |
| 410 | t->items[8] = timeutils_obj_from_timestamp(mtime); // st_mtime |
| 411 | t->items[9] = timeutils_obj_from_timestamp(mtime); // st_ctime |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 412 | |
| 413 | return MP_OBJ_FROM_PTR(t); |
| 414 | } |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 415 | static MP_DEFINE_CONST_FUN_OBJ_2(MP_VFS_LFSx(stat_obj), MP_VFS_LFSx(stat)); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 416 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 417 | static int LFSx_API(traverse_cb)(void *data, LFSx_API(block_t) bl) { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 418 | (void)bl; |
Damien George | 69661f3 | 2020-02-27 15:36:53 +1100 | [diff] [blame] | 419 | uint32_t *n = (uint32_t *)data; |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 420 | *n += 1; |
| 421 | return LFSx_MACRO(_ERR_OK); |
| 422 | } |
| 423 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 424 | static mp_obj_t MP_VFS_LFSx(statvfs)(mp_obj_t self_in, mp_obj_t path_in) { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 425 | (void)path_in; |
| 426 | MP_OBJ_VFS_LFSx *self = MP_OBJ_TO_PTR(self_in); |
| 427 | uint32_t n_used_blocks = 0; |
| 428 | #if LFS_BUILD_VERSION == 1 |
| 429 | int ret = LFSx_API(traverse)(&self->lfs, LFSx_API(traverse_cb), &n_used_blocks); |
| 430 | #else |
| 431 | int ret = LFSx_API(fs_traverse)(&self->lfs, LFSx_API(traverse_cb), &n_used_blocks); |
| 432 | #endif |
| 433 | if (ret < 0) { |
| 434 | mp_raise_OSError(-ret); |
| 435 | } |
| 436 | |
| 437 | mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL)); |
| 438 | t->items[0] = MP_OBJ_NEW_SMALL_INT(self->lfs.cfg->block_size); // f_bsize |
| 439 | t->items[1] = t->items[0]; // f_frsize |
| 440 | t->items[2] = MP_OBJ_NEW_SMALL_INT(self->lfs.cfg->block_count); // f_blocks |
| 441 | t->items[3] = MP_OBJ_NEW_SMALL_INT(self->lfs.cfg->block_count - n_used_blocks); // f_bfree |
| 442 | t->items[4] = t->items[3]; // f_bavail |
| 443 | t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // f_files |
| 444 | t->items[6] = MP_OBJ_NEW_SMALL_INT(0); // f_ffree |
| 445 | t->items[7] = MP_OBJ_NEW_SMALL_INT(0); // f_favail |
| 446 | t->items[8] = MP_OBJ_NEW_SMALL_INT(0); // f_flags |
| 447 | t->items[9] = MP_OBJ_NEW_SMALL_INT(LFSx_MACRO(_NAME_MAX)); // f_namemax |
| 448 | |
| 449 | return MP_OBJ_FROM_PTR(t); |
| 450 | } |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 451 | static MP_DEFINE_CONST_FUN_OBJ_2(MP_VFS_LFSx(statvfs_obj), MP_VFS_LFSx(statvfs)); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 452 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 453 | static mp_obj_t MP_VFS_LFSx(mount)(mp_obj_t self_in, mp_obj_t readonly, mp_obj_t mkfs) { |
Damien George | 03a1f94 | 2020-10-29 11:31:53 +1100 | [diff] [blame] | 454 | MP_OBJ_VFS_LFSx *self = MP_OBJ_TO_PTR(self_in); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 455 | (void)mkfs; |
Damien George | 03a1f94 | 2020-10-29 11:31:53 +1100 | [diff] [blame] | 456 | |
| 457 | // Make block device read-only if requested. |
| 458 | if (mp_obj_is_true(readonly)) { |
| 459 | self->blockdev.writeblocks[0] = MP_OBJ_NULL; |
| 460 | } |
| 461 | |
| 462 | // Already called LFSx_API(mount) in MP_VFS_LFSx(make_new) so the filesystem is ready. |
| 463 | |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 464 | return mp_const_none; |
| 465 | } |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 466 | static MP_DEFINE_CONST_FUN_OBJ_3(MP_VFS_LFSx(mount_obj), MP_VFS_LFSx(mount)); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 467 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 468 | static mp_obj_t MP_VFS_LFSx(umount)(mp_obj_t self_in) { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 469 | MP_OBJ_VFS_LFSx *self = MP_OBJ_TO_PTR(self_in); |
| 470 | // LFS unmount never fails |
| 471 | LFSx_API(unmount)(&self->lfs); |
| 472 | return mp_const_none; |
| 473 | } |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 474 | static MP_DEFINE_CONST_FUN_OBJ_1(MP_VFS_LFSx(umount_obj), MP_VFS_LFSx(umount)); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 475 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 476 | static const mp_rom_map_elem_t MP_VFS_LFSx(locals_dict_table)[] = { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 477 | { MP_ROM_QSTR(MP_QSTR_mkfs), MP_ROM_PTR(&MP_VFS_LFSx(mkfs_obj)) }, |
| 478 | { MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&MP_VFS_LFSx(open_obj)) }, |
| 479 | { MP_ROM_QSTR(MP_QSTR_ilistdir), MP_ROM_PTR(&MP_VFS_LFSx(ilistdir_obj)) }, |
| 480 | { MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&MP_VFS_LFSx(mkdir_obj)) }, |
| 481 | { MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&MP_VFS_LFSx(rmdir_obj)) }, |
| 482 | { MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&MP_VFS_LFSx(chdir_obj)) }, |
| 483 | { MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&MP_VFS_LFSx(getcwd_obj)) }, |
| 484 | { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&MP_VFS_LFSx(remove_obj)) }, |
| 485 | { MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&MP_VFS_LFSx(rename_obj)) }, |
| 486 | { MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&MP_VFS_LFSx(stat_obj)) }, |
| 487 | { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&MP_VFS_LFSx(statvfs_obj)) }, |
| 488 | { MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&MP_VFS_LFSx(mount_obj)) }, |
| 489 | { MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&MP_VFS_LFSx(umount_obj)) }, |
| 490 | }; |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 491 | static MP_DEFINE_CONST_DICT(MP_VFS_LFSx(locals_dict), MP_VFS_LFSx(locals_dict_table)); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 492 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 493 | static mp_import_stat_t MP_VFS_LFSx(import_stat)(void *self_in, const char *path) { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 494 | MP_OBJ_VFS_LFSx *self = self_in; |
Damien George | 69661f3 | 2020-02-27 15:36:53 +1100 | [diff] [blame] | 495 | struct LFSx_API (info) info; |
Damien George | 7dffbfd | 2020-05-14 21:37:59 +1000 | [diff] [blame] | 496 | mp_obj_str_t path_obj = { { &mp_type_str }, 0, 0, (const byte *)path }; |
Damien George | 0c77668 | 2020-06-25 16:31:33 +1000 | [diff] [blame] | 497 | path = MP_VFS_LFSx(make_path)(self, MP_OBJ_FROM_PTR(&path_obj)); |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 498 | int ret = LFSx_API(stat)(&self->lfs, path, &info); |
| 499 | if (ret == 0) { |
| 500 | if (info.type == LFSx_MACRO(_TYPE_REG)) { |
| 501 | return MP_IMPORT_STAT_FILE; |
| 502 | } else { |
| 503 | return MP_IMPORT_STAT_DIR; |
| 504 | } |
| 505 | } |
| 506 | return MP_IMPORT_STAT_NO_EXIST; |
| 507 | } |
| 508 | |
Angus Gratton | decf8e6 | 2024-02-27 15:32:29 +1100 | [diff] [blame] | 509 | static const mp_vfs_proto_t MP_VFS_LFSx(proto) = { |
Damien George | a099505 | 2019-10-18 17:25:08 +1100 | [diff] [blame] | 510 | .import_stat = MP_VFS_LFSx(import_stat), |
| 511 | }; |
| 512 | |
Jim Mussared | b7d6ee9 | 2022-06-24 16:22:38 +1000 | [diff] [blame] | 513 | #if LFS_BUILD_VERSION == 1 |
| 514 | #define VFS_LFSx_QSTR MP_QSTR_VfsLfs1 |
| 515 | #else |
| 516 | #define VFS_LFSx_QSTR MP_QSTR_VfsLfs2 |
| 517 | #endif |
| 518 | |
Jim Mussared | 662b976 | 2021-07-14 14:38:38 +1000 | [diff] [blame] | 519 | MP_DEFINE_CONST_OBJ_TYPE( |
| 520 | MP_TYPE_VFS_LFSx, |
Jim Mussared | b7d6ee9 | 2022-06-24 16:22:38 +1000 | [diff] [blame] | 521 | VFS_LFSx_QSTR, |
Jim Mussared | 662b976 | 2021-07-14 14:38:38 +1000 | [diff] [blame] | 522 | MP_TYPE_FLAG_NONE, |
Jim Mussared | 94beeab | 2022-09-17 00:31:23 +1000 | [diff] [blame] | 523 | make_new, MP_VFS_LFSx(make_new), |
Jim Mussared | 662b976 | 2021-07-14 14:38:38 +1000 | [diff] [blame] | 524 | protocol, &MP_VFS_LFSx(proto), |
Jim Mussared | 9dce827 | 2022-06-24 16:27:46 +1000 | [diff] [blame] | 525 | locals_dict, &MP_VFS_LFSx(locals_dict) |
Jim Mussared | 662b976 | 2021-07-14 14:38:38 +1000 | [diff] [blame] | 526 | ); |
Jim Mussared | b7d6ee9 | 2022-06-24 16:22:38 +1000 | [diff] [blame] | 527 | |
| 528 | #undef VFS_LFSx_QSTR |
Damien George | a513558 | 2022-11-11 15:43:55 +1100 | [diff] [blame] | 529 | |
| 530 | #endif // defined(LFS_BUILD_VERSION) |