Skip to content

Commit d4cd483

Browse files
committed
extmod/vfs_fat: Replace listdir() with implementation of ilistdir().
VfsFat no longer has the listdir() method. Rather, if listdir() functionality is needed then one should use uos.listdir() which will call VfsFat.ilistdir().
1 parent 87283c1 commit d4cd483

3 files changed

Lines changed: 48 additions & 35 deletions

File tree

extmod/vfs_fat.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(fat_vfs_mkfs_obj, MP_ROM_PTR(&fat_vfs_mk
9191

9292
STATIC MP_DEFINE_CONST_FUN_OBJ_3(fat_vfs_open_obj, fatfs_builtin_open_self);
9393

94-
STATIC mp_obj_t fat_vfs_listdir_func(size_t n_args, const mp_obj_t *args) {
94+
STATIC mp_obj_t fat_vfs_ilistdir_func(size_t n_args, const mp_obj_t *args) {
9595
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(args[0]);
9696
bool is_str_type = true;
9797
const char *path;
@@ -104,9 +104,9 @@ STATIC mp_obj_t fat_vfs_listdir_func(size_t n_args, const mp_obj_t *args) {
104104
path = "";
105105
}
106106

107-
return fat_vfs_listdir2(self, path, is_str_type);
107+
return fat_vfs_ilistdir2(self, path, is_str_type);
108108
}
109-
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fat_vfs_listdir_obj, 1, 2, fat_vfs_listdir_func);
109+
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fat_vfs_ilistdir_obj, 1, 2, fat_vfs_ilistdir_func);
110110

111111
STATIC mp_obj_t fat_vfs_remove_internal(mp_obj_t vfs_in, mp_obj_t path_in, mp_int_t attr) {
112112
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in);
@@ -321,7 +321,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_umount_obj, vfs_fat_umount);
321321
STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
322322
{ MP_ROM_QSTR(MP_QSTR_mkfs), MP_ROM_PTR(&fat_vfs_mkfs_obj) },
323323
{ MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&fat_vfs_open_obj) },
324-
{ MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&fat_vfs_listdir_obj) },
324+
{ MP_ROM_QSTR(MP_QSTR_ilistdir), MP_ROM_PTR(&fat_vfs_ilistdir_obj) },
325325
{ MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&fat_vfs_mkdir_obj) },
326326
{ MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&fat_vfs_rmdir_obj) },
327327
{ MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&fat_vfs_chdir_obj) },

extmod/vfs_fat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,4 @@ mp_import_stat_t fat_vfs_import_stat(struct _fs_user_mount_t *vfs, const char *p
5757
mp_obj_t fatfs_builtin_open_self(mp_obj_t self_in, mp_obj_t path, mp_obj_t mode);
5858
MP_DECLARE_CONST_FUN_OBJ_KW(mp_builtin_open_obj);
5959

60-
mp_obj_t fat_vfs_listdir2(struct _fs_user_mount_t *vfs, const char *path, bool is_str_type);
60+
mp_obj_t fat_vfs_ilistdir2(struct _fs_user_mount_t *vfs, const char *path, bool is_str_type);

extmod/vfs_fat_misc.c

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -34,51 +34,64 @@
3434
#include "extmod/vfs_fat.h"
3535
#include "py/lexer.h"
3636

37-
// TODO: actually, the core function should be ilistdir()
38-
39-
mp_obj_t fat_vfs_listdir2(fs_user_mount_t *vfs, const char *path, bool is_str_type) {
40-
FRESULT res;
41-
FILINFO fno;
37+
typedef struct _mp_vfs_fat_ilistdir_it_t {
38+
mp_obj_base_t base;
39+
mp_fun_1_t iternext;
40+
bool is_str;
4241
FF_DIR dir;
42+
} mp_vfs_fat_ilistdir_it_t;
4343

44-
res = f_opendir(&vfs->fatfs, &dir, path);
45-
if (res != FR_OK) {
46-
mp_raise_OSError(fresult_to_errno_table[res]);
47-
}
48-
49-
mp_obj_t dir_list = mp_obj_new_list(0, NULL);
44+
STATIC mp_obj_t mp_vfs_fat_ilistdir_it_iternext(mp_obj_t self_in) {
45+
mp_vfs_fat_ilistdir_it_t *self = MP_OBJ_TO_PTR(self_in);
5046

5147
for (;;) {
52-
res = f_readdir(&dir, &fno); /* Read a directory item */
53-
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
54-
if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */
55-
if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */
56-
48+
FILINFO fno;
49+
FRESULT res = f_readdir(&self->dir, &fno);
5750
char *fn = fno.fname;
51+
if (res != FR_OK || fn[0] == 0) {
52+
// stop on error or end of dir
53+
break;
54+
}
55+
if (fn[0] == '.' && (fn[1] == 0 || (fn[1] == '.' && fn[2] == 0))) {
56+
// skip . and ..
57+
continue;
58+
}
5859

59-
/*
60+
// make 3-tuple with info about this entry
61+
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL));
62+
if (self->is_str) {
63+
t->items[0] = mp_obj_new_str(fn, strlen(fn), false);
64+
} else {
65+
t->items[0] = mp_obj_new_bytes((const byte*)fn, strlen(fn));
66+
}
6067
if (fno.fattrib & AM_DIR) {
6168
// dir
69+
t->items[1] = MP_OBJ_NEW_SMALL_INT(MP_S_IFDIR);
6270
} else {
6371
// file
72+
t->items[1] = MP_OBJ_NEW_SMALL_INT(MP_S_IFREG);
6473
}
65-
*/
74+
t->items[2] = MP_OBJ_NEW_SMALL_INT(0); // no inode number
6675

67-
// make a string object for this entry
68-
mp_obj_t entry_o;
69-
if (is_str_type) {
70-
entry_o = mp_obj_new_str(fn, strlen(fn), false);
71-
} else {
72-
entry_o = mp_obj_new_bytes((const byte*)fn, strlen(fn));
73-
}
74-
75-
// add the entry to the list
76-
mp_obj_list_append(dir_list, entry_o);
76+
return MP_OBJ_FROM_PTR(t);
7777
}
7878

79-
f_closedir(&dir);
79+
// ignore error because we may be closing a second time
80+
f_closedir(&self->dir);
8081

81-
return dir_list;
82+
return MP_OBJ_STOP_ITERATION;
83+
}
84+
85+
mp_obj_t fat_vfs_ilistdir2(fs_user_mount_t *vfs, const char *path, bool is_str_type) {
86+
mp_vfs_fat_ilistdir_it_t *iter = m_new_obj(mp_vfs_fat_ilistdir_it_t);
87+
iter->base.type = &mp_type_polymorph_iter;
88+
iter->iternext = mp_vfs_fat_ilistdir_it_iternext;
89+
iter->is_str = is_str_type;
90+
FRESULT res = f_opendir(&vfs->fatfs, &iter->dir, path);
91+
if (res != FR_OK) {
92+
mp_raise_OSError(fresult_to_errno_table[res]);
93+
}
94+
return MP_OBJ_FROM_PTR(iter);
8295
}
8396

8497
mp_import_stat_t fat_vfs_import_stat(fs_user_mount_t *vfs, const char *path) {

0 commit comments

Comments
 (0)