diff --git a/tests/test_paths.toml b/tests/test_paths.toml index 97a519ea..89fb89e9 100644 --- a/tests/test_paths.toml +++ b/tests/test_paths.toml @@ -1,237 +1,2207 @@ # simple path test -[cases.test_paths_normal] +[cases.test_paths_simple] +defines.DIR = [false, true] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; - lfs_mkdir(&lfs, "tea") => 0; - lfs_mkdir(&lfs, "tea/hottea") => 0; - lfs_mkdir(&lfs, "tea/warmtea") => 0; - lfs_mkdir(&lfs, "tea/coldtea") => 0; + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "coffee/drip") => 0; + lfs_mkdir(&lfs, "coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "coffee/turkish") => 0; + lfs_mkdir(&lfs, "coffee/tubruk") => 0; + lfs_mkdir(&lfs, "coffee/vietnamese") => 0; + lfs_mkdir(&lfs, "coffee/thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths struct lfs_info info; - lfs_stat(&lfs, "tea/hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "/tea/hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); + lfs_stat(&lfs, "coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "coffee/drip") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/coldbrew") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/turkish") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/tubruk") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/vietnamese") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/thai") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "coffee/drip") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/coldbrew") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/turkish") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/tubruk") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/vietnamese") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/thai") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + lfs_rename(&lfs, + "coffee/drip", + "espresso/espresso") => 0; + lfs_rename(&lfs, + "coffee/coldbrew", + "espresso/americano") => 0; + lfs_rename(&lfs, + "coffee/turkish", + "espresso/macchiato") => 0; + lfs_rename(&lfs, + "coffee/tubruk", + "espresso/latte") => 0; + lfs_rename(&lfs, + "coffee/vietnamese", + "espresso/cappuccino") => 0; + lfs_rename(&lfs, + "coffee/thai", + "espresso/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "espresso/espresso", &info) => 0; + assert(strcmp(info.name, "espresso") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "espresso/americano", &info) => 0; + assert(strcmp(info.name, "americano") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "espresso/macchiato", &info) => 0; + assert(strcmp(info.name, "macchiato") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "espresso/latte", &info) => 0; + assert(strcmp(info.name, "latte") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "espresso/cappuccino", &info) => 0; + assert(strcmp(info.name, "cappuccino") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "espresso/mocha", &info) => 0; + assert(strcmp(info.name, "mocha") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "coffee/drip", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/coldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/turkish", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/tubruk", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/vietnamese", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/thai", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "espresso/espresso") => 0; + lfs_remove(&lfs, "espresso/americano") => 0; + lfs_remove(&lfs, "espresso/macchiato") => 0; + lfs_remove(&lfs, "espresso/latte") => 0; + lfs_remove(&lfs, "espresso/cappuccino") => 0; + lfs_remove(&lfs, "espresso/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "espresso/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/mocha", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' + +# absolute path test +# +# littlefs does not provide cd, so these are the same as relative paths +[cases.test_paths_absolute] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "/coffee/drip") => 0; + lfs_mkdir(&lfs, "/coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "/coffee/turkish") => 0; + lfs_mkdir(&lfs, "/coffee/tubruk") => 0; + lfs_mkdir(&lfs, "/coffee/vietnamese") => 0; + lfs_mkdir(&lfs, "/coffee/thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "/coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/coldbrew", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/turkish", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/tubruk", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/vietnamese", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/thai", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/coldbrew", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/turkish", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/tubruk", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/vietnamese", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/thai", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/drip") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/coldbrew") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/turkish") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/tubruk") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/vietnamese") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/thai") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/drip") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/coldbrew") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/turkish") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/tubruk") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/vietnamese") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/thai") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + lfs_rename(&lfs, + "coffee/drip", + "/espresso/espresso") => 0; + lfs_rename(&lfs, + "coffee/coldbrew", + "/espresso/americano") => 0; + lfs_rename(&lfs, + "/coffee/turkish", + "espresso/macchiato") => 0; + lfs_rename(&lfs, + "/coffee/tubruk", + "espresso/latte") => 0; + lfs_rename(&lfs, + "/coffee/vietnamese", + "/espresso/cappuccino") => 0; + lfs_rename(&lfs, + "/coffee/thai", + "/espresso/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/espresso/espresso", &info) => 0; + assert(strcmp(info.name, "espresso") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "espresso/americano", &info) => 0; + assert(strcmp(info.name, "americano") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/macchiato", &info) => 0; + assert(strcmp(info.name, "macchiato") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "espresso/latte", &info) => 0; + assert(strcmp(info.name, "latte") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/cappuccino", &info) => 0; + assert(strcmp(info.name, "cappuccino") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "espresso/mocha", &info) => 0; + assert(strcmp(info.name, "mocha") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "/coffee/drip", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/coffee/coldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/coffee/turkish", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/coffee/tubruk", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/coffee/vietnamese", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/coffee/thai", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "/espresso/espresso") => 0; + lfs_remove(&lfs, "/espresso/americano") => 0; + lfs_remove(&lfs, "/espresso/macchiato") => 0; + lfs_remove(&lfs, "/espresso/latte") => 0; + lfs_remove(&lfs, "/espresso/cappuccino") => 0; + lfs_remove(&lfs, "/espresso/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/espresso/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/mocha", &info) => LFS_ERR_NOENT; - lfs_mkdir(&lfs, "/milk") => 0; - lfs_stat(&lfs, "/milk", &info) => 0; - assert(strcmp(info.name, "milk") == 0); - lfs_stat(&lfs, "milk", &info) => 0; - assert(strcmp(info.name, "milk") == 0); lfs_unmount(&lfs) => 0; ''' # redundant slashes [cases.test_paths_redundant_slashes] +defines.DIR = [false, true] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; - lfs_mkdir(&lfs, "tea") => 0; - lfs_mkdir(&lfs, "tea/hottea") => 0; - lfs_mkdir(&lfs, "tea/warmtea") => 0; - lfs_mkdir(&lfs, "tea/coldtea") => 0; - struct lfs_info info; - lfs_stat(&lfs, "/tea/hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "//tea//hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "///tea///hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - - lfs_mkdir(&lfs, "////milk") => 0; - lfs_stat(&lfs, "////milk", &info) => 0; - assert(strcmp(info.name, "milk") == 0); - lfs_stat(&lfs, "milk", &info) => 0; - assert(strcmp(info.name, "milk") == 0); - lfs_unmount(&lfs) => 0; -''' - -# dot path test -[cases.test_paths_dot] -code = ''' - lfs_t lfs; - lfs_format(&lfs, cfg) => 0; - lfs_mount(&lfs, cfg) => 0; - lfs_mkdir(&lfs, "tea") => 0; - lfs_mkdir(&lfs, "tea/hottea") => 0; - lfs_mkdir(&lfs, "tea/warmtea") => 0; - lfs_mkdir(&lfs, "tea/coldtea") => 0; - - struct lfs_info info; - lfs_stat(&lfs, "./tea/hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "/./tea/hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "/././tea/hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "/./tea/./hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - - lfs_mkdir(&lfs, "/./milk") => 0; - lfs_stat(&lfs, "/./milk", &info) => 0; - assert(strcmp(info.name, "milk") == 0); - lfs_stat(&lfs, "milk", &info) => 0; - assert(strcmp(info.name, "milk") == 0); - lfs_unmount(&lfs) => 0; -''' - -# dot dot path test -[cases.test_paths_dot_dot] -code = ''' - lfs_t lfs; - lfs_format(&lfs, cfg) => 0; - lfs_mount(&lfs, cfg) => 0; - lfs_mkdir(&lfs, "tea") => 0; - lfs_mkdir(&lfs, "tea/hottea") => 0; - lfs_mkdir(&lfs, "tea/warmtea") => 0; - lfs_mkdir(&lfs, "tea/coldtea") => 0; + // create paths lfs_mkdir(&lfs, "coffee") => 0; - lfs_mkdir(&lfs, "coffee/hotcoffee") => 0; - lfs_mkdir(&lfs, "coffee/warmcoffee") => 0; - lfs_mkdir(&lfs, "coffee/coldcoffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "/coffee/drip") => 0; + lfs_mkdir(&lfs, "//coffee//coldbrew") => 0; + lfs_mkdir(&lfs, "///coffee///turkish") => 0; + lfs_mkdir(&lfs, "////coffee////tubruk") => 0; + lfs_mkdir(&lfs, "/////coffee/////vietnamese") => 0; + lfs_mkdir(&lfs, "//////coffee//////thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "//coffee//coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "///coffee///turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "////coffee////tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/////coffee/////vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "//////coffee//////thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + // stat paths struct lfs_info info; - lfs_stat(&lfs, "coffee/../tea/hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "tea/coldtea/../hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "coffee/coldcoffee/../../tea/hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "coffee/../coffee/../tea/hottea", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); + lfs_stat(&lfs, "//////coffee//////drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/////coffee/////coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "////coffee////turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "///coffee///tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "//coffee//vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "//coffee//coldbrew", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "///coffee///turkish", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "////coffee////tubruk", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/////coffee/////vietnamese", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "//////coffee//////thai", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "//coffee//coldbrew", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "///coffee///turkish", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "////coffee////tubruk", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/////coffee/////vietnamese", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "//////coffee//////thai", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/drip") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "//coffee//coldbrew") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "///coffee///turkish") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "////coffee////tubruk") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/////coffee/////vietnamese") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "//////coffee//////thai") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/drip") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "//coffee//coldbrew") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "///coffee///turkish") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "////coffee////tubruk") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/////coffee/////vietnamese") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "//////coffee//////thai") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + lfs_rename(&lfs, + "//////coffee//////drip", + "/espresso/espresso") => 0; + lfs_rename(&lfs, + "/////coffee/////coldbrew", + "//espresso//americano") => 0; + lfs_rename(&lfs, + "////coffee////turkish", + "///espresso///macchiato") => 0; + lfs_rename(&lfs, + "///coffee///tubruk", + "////espresso////latte") => 0; + lfs_rename(&lfs, + "//coffee//vietnamese", + "/////espresso/////cappuccino") => 0; + lfs_rename(&lfs, + "/coffee/thai", + "//////espresso//////mocha") => 0; + + // stat paths + lfs_stat(&lfs, "//////espresso//////espresso", &info) => 0; + assert(strcmp(info.name, "espresso") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/////espresso/////americano", &info) => 0; + assert(strcmp(info.name, "americano") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "////espresso////macchiato", &info) => 0; + assert(strcmp(info.name, "macchiato") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "///espresso///latte", &info) => 0; + assert(strcmp(info.name, "latte") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "//espresso//cappuccino", &info) => 0; + assert(strcmp(info.name, "cappuccino") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/mocha", &info) => 0; + assert(strcmp(info.name, "mocha") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "//////coffee//////drip", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/////coffee/////coldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "////coffee////turkish", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "///coffee///tubruk", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "//coffee//vietnamese", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/coffee/thai", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "/espresso/espresso") => 0; + lfs_remove(&lfs, "//espresso//americano") => 0; + lfs_remove(&lfs, "///espresso///macchiato") => 0; + lfs_remove(&lfs, "////espresso////latte") => 0; + lfs_remove(&lfs, "/////espresso/////cappuccino") => 0; + lfs_remove(&lfs, "//////espresso//////mocha") => 0; + + // stat paths + lfs_stat(&lfs, "//////espresso//////espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/////espresso/////americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "////espresso////macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "///espresso///latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "//espresso//cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/mocha", &info) => LFS_ERR_NOENT; - lfs_mkdir(&lfs, "coffee/../milk") => 0; - lfs_stat(&lfs, "coffee/../milk", &info) => 0; - strcmp(info.name, "milk") => 0; - lfs_stat(&lfs, "milk", &info) => 0; - strcmp(info.name, "milk") => 0; lfs_unmount(&lfs) => 0; ''' -# trailing dot path test -[cases.test_paths_trailing_dot] +# TODO test trailing slashes + +# dot path tests +[cases.test_paths_dots] +defines.DIR = [false, true] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; - lfs_mkdir(&lfs, "tea") => 0; - lfs_mkdir(&lfs, "tea/hottea") => 0; - lfs_mkdir(&lfs, "tea/warmtea") => 0; - lfs_mkdir(&lfs, "tea/coldtea") => 0; + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "/coffee/drip") => 0; + lfs_mkdir(&lfs, "/./coffee/./coldbrew") => 0; + lfs_mkdir(&lfs, "/././coffee/././turkish") => 0; + lfs_mkdir(&lfs, "/./././coffee/./././tubruk") => 0; + lfs_mkdir(&lfs, "/././././coffee/././././vietnamese") => 0; + lfs_mkdir(&lfs, "/./././././coffee/./././././thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/./coffee/./coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/././coffee/././turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/./././coffee/./././tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/././././coffee/././././vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/./././././coffee/./././././thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths struct lfs_info info; - lfs_stat(&lfs, "tea/hottea/", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "tea/hottea/.", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "tea/hottea/./.", &info) => 0; - assert(strcmp(info.name, "hottea") == 0); - lfs_stat(&lfs, "tea/hottea/..", &info) => 0; - assert(strcmp(info.name, "tea") == 0); - lfs_stat(&lfs, "tea/hottea/../.", &info) => 0; - assert(strcmp(info.name, "tea") == 0); + lfs_stat(&lfs, "/./././././coffee/./././././drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/././././coffee/././././coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/./././coffee/./././turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/././coffee/././tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/./coffee/./vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/./coffee/./coldbrew", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/././coffee/././turkish", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/./././coffee/./././tubruk", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/././././coffee/././././vietnamese", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/./././././coffee/./././././thai", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/./coffee/./coldbrew", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/././coffee/././turkish", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/./././coffee/./././tubruk", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/././././coffee/././././vietnamese", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/./././././coffee/./././././thai", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/drip") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/./coffee/./coldbrew") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/././coffee/././turkish") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/./././coffee/./././tubruk") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/././././coffee/././././vietnamese") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/./././././coffee/./././././thai") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/drip") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/./coffee/./coldbrew") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/././coffee/././turkish") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/./././coffee/./././tubruk") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/././././coffee/././././vietnamese") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/./././././coffee/./././././thai") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + lfs_rename(&lfs, + "/./././././coffee/./././././drip", + "/espresso/espresso") => 0; + lfs_rename(&lfs, + "/././././coffee/././././coldbrew", + "/./espresso/./americano") => 0; + lfs_rename(&lfs, + "/./././coffee/./././turkish", + "/././espresso/././macchiato") => 0; + lfs_rename(&lfs, + "/././coffee/././tubruk", + "/./././espresso/./././latte") => 0; + lfs_rename(&lfs, + "/./coffee/./vietnamese", + "/././././espresso/././././cappuccino") => 0; + lfs_rename(&lfs, + "/coffee/thai", + "/./././././espresso/./././././mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/./././././espresso/./././././espresso", &info) => 0; + assert(strcmp(info.name, "espresso") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/././././espresso/././././americano", &info) => 0; + assert(strcmp(info.name, "americano") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/./././espresso/./././macchiato", &info) => 0; + assert(strcmp(info.name, "macchiato") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/././espresso/././latte", &info) => 0; + assert(strcmp(info.name, "latte") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/./espresso/./cappuccino", &info) => 0; + assert(strcmp(info.name, "cappuccino") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/mocha", &info) => 0; + assert(strcmp(info.name, "mocha") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "/./././././coffee/./././././drip", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/././././coffee/././././coldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/./././coffee/./././turkish", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/././coffee/././tubruk", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/./coffee/./vietnamese", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/coffee/thai", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "/espresso/espresso") => 0; + lfs_remove(&lfs, "/./espresso/./americano") => 0; + lfs_remove(&lfs, "/././espresso/././macchiato") => 0; + lfs_remove(&lfs, "/./././espresso/./././latte") => 0; + lfs_remove(&lfs, "/././././espresso/././././cappuccino") => 0; + lfs_remove(&lfs, "/./././././espresso/./././././mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/./././././espresso/./././././espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/././././espresso/././././americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/./././espresso/./././macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/././espresso/././latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/./espresso/./cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/mocha", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' + +# TODO test trailing dots + +# dot dot path tests +[cases.test_paths_dotdots] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "no") => 0; + lfs_mkdir(&lfs, "no/no") => 0; + lfs_mkdir(&lfs, "coffee") => 0; + lfs_mkdir(&lfs, "coffee/no") => 0; + if (DIR) { + lfs_mkdir(&lfs, "/coffee/drip") => 0; + lfs_mkdir(&lfs, "/no/../coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "/coffee/no/../turkish") => 0; + lfs_mkdir(&lfs, "/no/no/../../coffee/tubruk") => 0; + lfs_mkdir(&lfs, "/no/no/../../coffee/no/../vietnamese") => 0; + lfs_mkdir(&lfs, "/no/no/../../no/no/../../coffee/thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/../coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/no/../turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/../../coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/../../coffee/no/../vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/../../no/no/../../coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "/no/no/../../no/no/../../coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/no/../../coffee/no/../coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/no/../../coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/no/../tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/../coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/../coffee/coldbrew", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/no/../turkish", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/no/../../coffee/tubruk", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/no/../../coffee/no/../vietnamese", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/no/../../no/no/../../coffee/thai", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/drip", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/../coffee/coldbrew", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/no/../turkish", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/../../coffee/tubruk", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/../../coffee/no/../vietnamese", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/no/../../no/no/../../coffee/thai", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/drip") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/no/../coffee/coldbrew") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/no/../turkish") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/no/no/../../coffee/tubruk") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/no/no/../../coffee/no/../vietnamese") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/no/no/../../no/no/../../coffee/thai") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/drip") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/no/../coffee/coldbrew") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/no/../turkish") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/no/no/../../coffee/tubruk") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/no/no/../../coffee/no/../vietnamese") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/no/no/../../no/no/../../coffee/thai") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + lfs_rename(&lfs, + "/no/no/../../no/no/../../coffee/drip", + "/espresso/espresso") => 0; + lfs_rename(&lfs, + "/no/no/../../coffee/no/../coldbrew", + "/no/../espresso/americano") => 0; + lfs_rename(&lfs, + "/no/no/../../coffee/turkish", + "/espresso/no/../macchiato") => 0; + lfs_rename(&lfs, + "/coffee/no/../tubruk", + "/no/no/../../espresso/latte") => 0; + lfs_rename(&lfs, + "/no/../coffee/vietnamese", + "/no/no/../../espresso/no/../cappuccino") => 0; + lfs_rename(&lfs, + "/coffee/thai", + "/no/no/../../no/no/../../espresso/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/no/no/../../no/no/../../espresso/espresso", &info) => 0; + assert(strcmp(info.name, "espresso") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/no/../../espresso/no/../americano", &info) => 0; + assert(strcmp(info.name, "americano") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/no/../../espresso/macchiato", &info) => 0; + assert(strcmp(info.name, "macchiato") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/no/../latte", &info) => 0; + assert(strcmp(info.name, "latte") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/../espresso/cappuccino", &info) => 0; + assert(strcmp(info.name, "cappuccino") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/mocha", &info) => 0; + assert(strcmp(info.name, "mocha") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "/no/no/../../no/no/../../coffee/drip", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/no/../../coffee/no/../coldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/no/../../coffee/turkish", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/coffee/no/../tubruk", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/../coffee/vietnamese", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/coffee/thai", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "/espresso/espresso") => 0; + lfs_remove(&lfs, "/no/../espresso/americano") => 0; + lfs_remove(&lfs, "/espresso/no/../macchiato") => 0; + lfs_remove(&lfs, "/no/no/../../espresso/latte") => 0; + lfs_remove(&lfs, "/no/no/../../espresso/no/../cappuccino") => 0; + lfs_remove(&lfs, "/no/no/../../no/no/../../espresso/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/no/no/../../no/no/../../espresso/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/no/../../espresso/no/../americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/no/../../espresso/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/no/../latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/../espresso/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/mocha", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' + +# TODO test trailing dotdots + +# dot dot dot path tests +[cases.test_paths_dotdotdots] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + lfs_mkdir(&lfs, "coffee/...") => 0; + if (DIR) { + lfs_mkdir(&lfs, "/coffee/.../drip") => 0; + lfs_mkdir(&lfs, "/coffee/.../coldbrew") => 0; + lfs_mkdir(&lfs, "/coffee/.../turkish") => 0; + lfs_mkdir(&lfs, "/coffee/.../tubruk") => 0; + lfs_mkdir(&lfs, "/coffee/.../vietnamese") => 0; + lfs_mkdir(&lfs, "/coffee/.../thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/.../drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "/coffee/.../drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/.../coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/.../turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/.../tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/.../vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/.../thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/.../drip", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/.../coldbrew", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/.../turkish", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/.../tubruk", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/.../vietnamese", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/.../thai", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/.../drip", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../coldbrew", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../turkish", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../tubruk", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../vietnamese", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.../thai", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/.../drip") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/.../coldbrew") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/.../turkish") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/.../tubruk") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/.../vietnamese") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/.../thai") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/.../drip") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/.../coldbrew") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/.../turkish") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/.../tubruk") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/.../vietnamese") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/.../thai") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + lfs_mkdir(&lfs, "espresso/...") => 0; + lfs_rename(&lfs, + "/coffee/.../drip", + "/espresso/.../espresso") => 0; + lfs_rename(&lfs, + "/coffee/.../coldbrew", + "/espresso/.../americano") => 0; + lfs_rename(&lfs, + "/coffee/.../turkish", + "/espresso/.../macchiato") => 0; + lfs_rename(&lfs, + "/coffee/.../tubruk", + "/espresso/.../latte") => 0; + lfs_rename(&lfs, + "/coffee/.../vietnamese", + "/espresso/.../cappuccino") => 0; + lfs_rename(&lfs, + "/coffee/.../thai", + "/espresso/.../mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/espresso/.../espresso", &info) => 0; + assert(strcmp(info.name, "espresso") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/.../americano", &info) => 0; + assert(strcmp(info.name, "americano") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/.../macchiato", &info) => 0; + assert(strcmp(info.name, "macchiato") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/.../latte", &info) => 0; + assert(strcmp(info.name, "latte") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/.../cappuccino", &info) => 0; + assert(strcmp(info.name, "cappuccino") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/.../mocha", &info) => 0; + assert(strcmp(info.name, "mocha") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "coffee/.../drip", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/.../coldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/.../turkish", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/.../tubruk", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/.../vietnamese", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/.../thai", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "/espresso/.../espresso") => 0; + lfs_remove(&lfs, "/espresso/.../americano") => 0; + lfs_remove(&lfs, "/espresso/.../macchiato") => 0; + lfs_remove(&lfs, "/espresso/.../latte") => 0; + lfs_remove(&lfs, "/espresso/.../cappuccino") => 0; + lfs_remove(&lfs, "/espresso/.../mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/espresso/.../espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/.../americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/.../macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/.../latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/.../cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/.../mocha", &info) => LFS_ERR_NOENT; + lfs_unmount(&lfs) => 0; ''' # leading dot path test -[cases.test_paths_leading_dot] +[cases.test_paths_leading_dots] +defines.DIR = [false, true] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; - lfs_mkdir(&lfs, ".milk") => 0; + + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "/coffee/.drip") => 0; + lfs_mkdir(&lfs, "/coffee/..coldbrew") => 0; + lfs_mkdir(&lfs, "/coffee/...turkish") => 0; + lfs_mkdir(&lfs, "/coffee/....tubruk") => 0; + lfs_mkdir(&lfs, "/coffee/.....vietnamese") => 0; + lfs_mkdir(&lfs, "/coffee/......thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/.drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/..coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/...turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/....tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.....vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/......thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths struct lfs_info info; - lfs_stat(&lfs, ".milk", &info) => 0; - strcmp(info.name, ".milk") => 0; - lfs_stat(&lfs, "tea/.././.milk", &info) => 0; - strcmp(info.name, ".milk") => 0; + lfs_stat(&lfs, "/coffee/.drip", &info) => 0; + assert(strcmp(info.name, ".drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/..coldbrew", &info) => 0; + assert(strcmp(info.name, "..coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/...turkish", &info) => 0; + assert(strcmp(info.name, "...turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/....tubruk", &info) => 0; + assert(strcmp(info.name, "....tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/.....vietnamese", &info) => 0; + assert(strcmp(info.name, ".....vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/coffee/......thai", &info) => 0; + assert(strcmp(info.name, "......thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/.drip", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/..coldbrew", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/...turkish", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/....tubruk", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/.....vietnamese", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/coffee/......thai", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/coffee/.drip", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/..coldbrew", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/...turkish", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/....tubruk", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/.....vietnamese", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/coffee/......thai", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/.drip") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/..coldbrew") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/...turkish") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/....tubruk") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/.....vietnamese") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/coffee/......thai") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/coffee/.drip") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/..coldbrew") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/...turkish") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/....tubruk") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/.....vietnamese") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/coffee/......thai") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + lfs_rename(&lfs, + "/coffee/.drip", + "/espresso/.espresso") => 0; + lfs_rename(&lfs, + "/coffee/..coldbrew", + "/espresso/..americano") => 0; + lfs_rename(&lfs, + "/coffee/...turkish", + "/espresso/...macchiato") => 0; + lfs_rename(&lfs, + "/coffee/....tubruk", + "/espresso/....latte") => 0; + lfs_rename(&lfs, + "/coffee/.....vietnamese", + "/espresso/.....cappuccino") => 0; + lfs_rename(&lfs, + "/coffee/......thai", + "/espresso/......mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/espresso/.espresso", &info) => 0; + assert(strcmp(info.name, ".espresso") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/..americano", &info) => 0; + assert(strcmp(info.name, "..americano") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/...macchiato", &info) => 0; + assert(strcmp(info.name, "...macchiato") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/....latte", &info) => 0; + assert(strcmp(info.name, "....latte") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/.....cappuccino", &info) => 0; + assert(strcmp(info.name, ".....cappuccino") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/espresso/......mocha", &info) => 0; + assert(strcmp(info.name, "......mocha") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "coffee/.drip", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/..coldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/...turkish", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/....tubruk", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/.....vietnamese", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/......thai", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "/espresso/.espresso") => 0; + lfs_remove(&lfs, "/espresso/..americano") => 0; + lfs_remove(&lfs, "/espresso/...macchiato") => 0; + lfs_remove(&lfs, "/espresso/....latte") => 0; + lfs_remove(&lfs, "/espresso/.....cappuccino") => 0; + lfs_remove(&lfs, "/espresso/......mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/espresso/.espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/..americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/...macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/....latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/.....cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/espresso/......mocha", &info) => LFS_ERR_NOENT; + lfs_unmount(&lfs) => 0; ''' # root dot dot path test -[cases.test_paths_root_dot_dot] +[cases.test_paths_root_dotdots] +defines.DIR = [false, true] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; - lfs_mkdir(&lfs, "tea") => 0; - lfs_mkdir(&lfs, "tea/hottea") => 0; - lfs_mkdir(&lfs, "tea/warmtea") => 0; - lfs_mkdir(&lfs, "tea/coldtea") => 0; + + // create paths + lfs_mkdir(&lfs, "no") => 0; lfs_mkdir(&lfs, "coffee") => 0; - lfs_mkdir(&lfs, "coffee/hotcoffee") => 0; - lfs_mkdir(&lfs, "coffee/warmcoffee") => 0; - lfs_mkdir(&lfs, "coffee/coldcoffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "/../coffee/drip") => 0; + lfs_mkdir(&lfs, "/../../coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "/../../../coffee/turkish") => 0; + lfs_mkdir(&lfs, "/no/../../coffee/tubruk") => 0; + lfs_mkdir(&lfs, "/no/../../../coffee/vietnamese") => 0; + lfs_mkdir(&lfs, "/no/../../../../coffee/thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/../coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/../../coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/../../../coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/../../coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/../../../coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/../../../../coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + // stat paths struct lfs_info info; - lfs_stat(&lfs, "coffee/../../../../../../tea/hottea", &info) => 0; - strcmp(info.name, "hottea") => 0; + lfs_stat(&lfs, "/no/../../../../coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/../../../coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/../../coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/../../../coffee/tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/../../coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/../coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/../coffee/drip", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/../../coffee/coldbrew", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/../../../coffee/turkish", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/../../coffee/tubruk", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/../../../coffee/vietnamese", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/no/../../../../coffee/thai", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/../coffee/drip", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/../../coffee/coldbrew", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/../../../coffee/turkish", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/../../coffee/tubruk", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/../../../coffee/vietnamese", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "/no/../../../../coffee/thai", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/../coffee/drip") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/../../coffee/coldbrew") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/../../../coffee/turkish") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/no/../../coffee/tubruk") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/no/../../../coffee/vietnamese") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/no/../../../../coffee/thai") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/../coffee/drip") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/../../coffee/coldbrew") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/../../../coffee/turkish") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/no/../coffee/tubruk") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/no/../../coffee/vietnamese") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "/no/../../../coffee/thai") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + lfs_rename(&lfs, + "/no/../../../../coffee/drip", + "/../espresso/espresso") => 0; + lfs_rename(&lfs, + "/no/../../../coffee/coldbrew", + "/../../espresso/americano") => 0; + lfs_rename(&lfs, + "/no/../../coffee/turkish", + "/../../../espresso/macchiato") => 0; + lfs_rename(&lfs, + "/../../../coffee/tubruk", + "/no/../../espresso/latte") => 0; + lfs_rename(&lfs, + "/../../coffee/vietnamese", + "/no/../../../espresso/cappuccino") => 0; + lfs_rename(&lfs, + "/../coffee/thai", + "/no/../../../../espresso/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/no/../../../../espresso/espresso", &info) => 0; + assert(strcmp(info.name, "espresso") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/../../../espresso/americano", &info) => 0; + assert(strcmp(info.name, "americano") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/no/../../espresso/macchiato", &info) => 0; + assert(strcmp(info.name, "macchiato") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/../../../espresso/latte", &info) => 0; + assert(strcmp(info.name, "latte") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/../../espresso/cappuccino", &info) => 0; + assert(strcmp(info.name, "cappuccino") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "/../espresso/mocha", &info) => 0; + assert(strcmp(info.name, "mocha") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "/no/../../../../coffee/drip", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/../../../coffee/coldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/../../coffee/turkish", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/../../../coffee/tubruk", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/../../coffee/vietnamese", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/../coffee/thai", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "/../espresso/espresso") => 0; + lfs_remove(&lfs, "/../../espresso/americano") => 0; + lfs_remove(&lfs, "/../../../espresso/macchiato") => 0; + lfs_remove(&lfs, "/no/../../espresso/latte") => 0; + lfs_remove(&lfs, "/no/../../../espresso/cappuccino") => 0; + lfs_remove(&lfs, "/no/../../../../espresso/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "/no/../../../../espresso/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/../../../espresso/americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/no/../../espresso/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/../../../espresso/latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/../../espresso/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "/../espresso/mocha", &info) => LFS_ERR_NOENT; - lfs_mkdir(&lfs, "coffee/../../../../../../milk") => 0; - lfs_stat(&lfs, "coffee/../../../../../../milk", &info) => 0; - strcmp(info.name, "milk") => 0; - lfs_stat(&lfs, "milk", &info) => 0; - strcmp(info.name, "milk") => 0; lfs_unmount(&lfs) => 0; ''' -# invalid path tests -[cases.test_paths_invalid] +# trailing noent tests +[cases.test_paths_noent] +defines.DIR = [false, true] code = ''' lfs_t lfs; - lfs_format(&lfs, cfg); + lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "coffee/drip") => 0; + lfs_mkdir(&lfs, "coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "coffee/turkish") => 0; + lfs_mkdir(&lfs, "coffee/tubruk") => 0; + lfs_mkdir(&lfs, "coffee/vietnamese") => 0; + lfs_mkdir(&lfs, "coffee/thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths struct lfs_info info; - lfs_stat(&lfs, "dirt", &info) => LFS_ERR_NOENT; - lfs_stat(&lfs, "dirt/ground", &info) => LFS_ERR_NOENT; - lfs_stat(&lfs, "dirt/ground/earth", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/_rip", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/c_ldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/tu_kish", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/tub_uk", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/_vietnamese", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/thai_", &info) => LFS_ERR_NOENT; - lfs_remove(&lfs, "dirt") => LFS_ERR_NOENT; - lfs_remove(&lfs, "dirt/ground") => LFS_ERR_NOENT; - lfs_remove(&lfs, "dirt/ground/earth") => LFS_ERR_NOENT; - - lfs_mkdir(&lfs, "dirt/ground") => LFS_ERR_NOENT; + // file open paths, only works on files! lfs_file_t file; - lfs_file_open(&lfs, &file, "dirt/ground", LFS_O_WRONLY | LFS_O_CREAT) - => LFS_ERR_NOENT; - lfs_mkdir(&lfs, "dirt/ground/earth") => LFS_ERR_NOENT; - lfs_file_open(&lfs, &file, "dirt/ground/earth", LFS_O_WRONLY | LFS_O_CREAT) - => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/_rip", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/c_ldbrew", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/tu_kish", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/tub_uk", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/_vietnamese", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee/thai_", + LFS_O_RDONLY) => LFS_ERR_NOENT; + + // dir open paths, only works on dirs! + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "coffee/_rip") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee/c_ldbrew") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee/tu_kish") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee/tub_uk") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee/_vietnamese") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee/thai_") => LFS_ERR_NOENT; + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + lfs_rename(&lfs, + "coffee/_rip", + "espresso/espresso") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/c_ldbrew", + "espresso/americano") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tu_kish", + "espresso/macchiato") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tub_uk", + "espresso/latte") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/_vietnamese", + "espresso/cappuccino") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/thai_", + "espresso/mocha") => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "coffee/_rip") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee/c_ldbrew") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee/tu_kish") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee/tub_uk") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee/_vietnamese") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee/thai_") => LFS_ERR_NOENT; + + // stat paths + lfs_stat(&lfs, "espresso/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/mocha", &info) => LFS_ERR_NOENT; + + lfs_stat(&lfs, "coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_unmount(&lfs) => 0; +''' + +# parent noent tests +[cases.test_paths_noent_parent] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "_offee/drip") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "c_ffee/coldbrew") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "co_fee/turkish") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "cof_ee/tubruk") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "_coffee/vietnamese") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "coffee_/thai") => LFS_ERR_NOENT; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "_offee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "c_ffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "co_fee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "cof_ee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "_coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee_/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOENT; + } + + // ok, actually create paths + if (DIR) { + lfs_mkdir(&lfs, "coffee/drip") => 0; + lfs_mkdir(&lfs, "coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "coffee/turkish") => 0; + lfs_mkdir(&lfs, "coffee/tubruk") => 0; + lfs_mkdir(&lfs, "coffee/vietnamese") => 0; + lfs_mkdir(&lfs, "coffee/thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "_offee/drip", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "c_ffee/coldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "co_fee/turkish", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "cof_ee/tubruk", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "_coffee/vietnamese", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee_/thai", &info) => LFS_ERR_NOENT; + + // file open paths, only works on files! + lfs_file_t file; + lfs_file_open(&lfs, &file, "_offee/drip", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "c_ffee/coldbrew", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "co_fee/turkish", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "cof_ee/tubruk", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "_coffee/vietnamese", + LFS_O_RDONLY) => LFS_ERR_NOENT; + lfs_file_open(&lfs, &file, "coffee_/thai", + LFS_O_RDONLY) => LFS_ERR_NOENT; + + // dir open paths, only works on dirs! + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "_offee/drip") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "c_ffee/coldbrew") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "co_fee/turkish") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "cof_ee/tubruk") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "_coffee/vietnamese") => LFS_ERR_NOENT; + lfs_dir_open(&lfs, &dir, "coffee_/thai") => LFS_ERR_NOENT; + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + // bad source + lfs_rename(&lfs, + "_offee/drip", + "espresso/espresso") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "c_ffee/coldbrew", + "espresso/americano") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "co_fee/turkish", + "espresso/macchiato") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "cof_ee/tubruk", + "espresso/latte") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "_coffee/vietnamese", + "espresso/cappuccino") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee_/thai", + "espresso/mocha") => LFS_ERR_NOENT; + + // bad destination + lfs_rename(&lfs, + "coffee/drip", + "_spresso/espresso") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/coldbrew", + "e_presso/americano") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/turkish", + "es_resso/macchiato") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/tubruk", + "esp_esso/latte") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/vietnamese", + "_espresso/cappuccino") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee/thai", + "espresso_/mocha") => LFS_ERR_NOENT; + + // bad source and bad destination + lfs_rename(&lfs, + "_offee/drip", + "_spresso/espresso") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "c_ffee/coldbrew", + "e_presso/americano") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "co_fee/turkish", + "es_resso/macchiato") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "cof_ee/tubruk", + "esp_esso/latte") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "_coffee/vietnamese", + "_espresso/cappuccino") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee_/thai", + "espresso_/mocha") => LFS_ERR_NOENT; + + // here's a weird one, what happens if our rename is also a noop? + lfs_rename(&lfs, + "_offee/drip", + "_offee/drip") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "c_ffee/coldbrew", + "c_ffee/coldbrew") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "co_fee/turkish", + "co_fee/turkish") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "cof_ee/tubruk", + "cof_ee/tubruk") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "_coffee/vietnamese", + "_coffee/vietnamese") => LFS_ERR_NOENT; + lfs_rename(&lfs, + "coffee_/thai", + "coffee_/thai") => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "_offee/drip") => LFS_ERR_NOENT; + lfs_remove(&lfs, "c_ffee/coldbrew") => LFS_ERR_NOENT; + lfs_remove(&lfs, "co_fee/turkish") => LFS_ERR_NOENT; + lfs_remove(&lfs, "cof_ee/tubruk") => LFS_ERR_NOENT; + lfs_remove(&lfs, "_coffee/vietnamese") => LFS_ERR_NOENT; + lfs_remove(&lfs, "coffee_/thai") => LFS_ERR_NOENT; + + // stat paths + lfs_stat(&lfs, "espresso/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "espresso/mocha", &info) => LFS_ERR_NOENT; + + lfs_stat(&lfs, "coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_unmount(&lfs) => 0; +''' + +# parent notdir tests +[cases.test_paths_notdir_parent] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_file_t file; + lfs_file_open(&lfs, &file, "drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + + if (DIR) { + lfs_mkdir(&lfs, "drip/coffee") => LFS_ERR_NOTDIR; + lfs_mkdir(&lfs, "coldbrew/coffee") => LFS_ERR_NOTDIR; + lfs_mkdir(&lfs, "turkish/coffee") => LFS_ERR_NOTDIR; + lfs_mkdir(&lfs, "tubruk/coffee") => LFS_ERR_NOTDIR; + lfs_mkdir(&lfs, "vietnamese/coffee") => LFS_ERR_NOTDIR; + lfs_mkdir(&lfs, "thai/coffee") => LFS_ERR_NOTDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "drip/coffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coldbrew/coffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "turkish/coffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "tubruk/coffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "vietnamese/coffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "thai/coffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NOTDIR; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "drip/coffee", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "coldbrew/coffee", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "turkish/coffee", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "tubruk/coffee", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "vietnamese/coffee", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "thai/coffee", &info) => LFS_ERR_NOTDIR; + + // file open paths, only works on files! + lfs_file_open(&lfs, &file, "drip/coffee", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "coldbrew/coffee", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "turkish/coffee", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "tubruk/coffee", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "vietnamese/coffee", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + lfs_file_open(&lfs, &file, "thai/coffee", + LFS_O_RDONLY) => LFS_ERR_NOTDIR; + + // dir open paths, only works on dirs! + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "drip/coffee") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coldbrew/coffee") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "turkish/coffee") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "tubruk/coffee") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "vietnamese/coffee") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "thai/coffee") => LFS_ERR_NOTDIR; + + // make some normal paths so we have something to rename + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "coffee/drip") => 0; + lfs_mkdir(&lfs, "coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "coffee/turkish") => 0; + lfs_mkdir(&lfs, "coffee/tubruk") => 0; + lfs_mkdir(&lfs, "coffee/vietnamese") => 0; + lfs_mkdir(&lfs, "coffee/thai") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/turkish", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/tubruk", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/vietnamese", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/thai", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + // bad source + lfs_rename(&lfs, + "drip/coffee", + "espresso/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coldbrew/coffee", + "espresso/americano") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "turkish/coffee", + "espresso/macchiato") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "tubruk/coffee", + "espresso/latte") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "vietnamese/coffee", + "espresso/cappuccino") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "thai/coffee", + "espresso/mocha") => LFS_ERR_NOTDIR; + + // bad destination + lfs_rename(&lfs, + "coffee/drip", + "drip/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/coldbrew", + "coldbrew/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/turkish", + "turkish/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/tubruk", + "tubruk/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/vietnamese", + "vietnamese/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coffee/thai", + "thai/espresso") => LFS_ERR_NOTDIR; + + // bad source and bad destination + lfs_rename(&lfs, + "drip/coffee", + "drip/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coldbrew/coffee", + "coldbrew/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "turkish/coffee", + "turkish/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "tubruk/coffee", + "tubruk/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "vietnamese/coffee", + "vietnamese/espresso") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "thai/coffee", + "thai/espresso") => LFS_ERR_NOTDIR; + + // here's a weird one, what happens if our rename is also a noop? + lfs_rename(&lfs, + "drip/coffee", + "drip/coffee") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "coldbrew/coffee", + "coldbrew/coffee") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "turkish/coffee", + "turkish/coffee") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "tubruk/coffee", + "tubruk/coffee") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "vietnamese/coffee", + "vietnamese/coffee") => LFS_ERR_NOTDIR; + lfs_rename(&lfs, + "thai/coffee", + "thai/coffee") => LFS_ERR_NOTDIR; + + // remove paths + lfs_stat(&lfs, "drip/espresso", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "coldbrew/espresso", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "turkish/espresso", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "tubruk/espresso", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "vietnamese/espresso", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "thai/espresso", &info) => LFS_ERR_NOTDIR; + + // stat paths + lfs_stat(&lfs, "drip/espresso", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "coldbrew/espresso", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "turkish/espresso", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "tubruk/espresso", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "vietnamese/espresso", &info) => LFS_ERR_NOTDIR; + lfs_stat(&lfs, "thai/espresso", &info) => LFS_ERR_NOTDIR; + + lfs_stat(&lfs, "coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/turkish", &info) => 0; + assert(strcmp(info.name, "turkish") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/tubruk", &info) => 0; + assert(strcmp(info.name, "tubruk") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/vietnamese", &info) => 0; + assert(strcmp(info.name, "vietnamese") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/thai", &info) => 0; + assert(strcmp(info.name, "thai") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_unmount(&lfs) => 0; ''' # root operations [cases.test_paths_root] +defines.DIR = [false, true] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; struct lfs_info info; + + // create root, this should error + if (DIR) { + lfs_mkdir(&lfs, "/") => LFS_ERR_EXIST; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + } + + // stat root lfs_stat(&lfs, "/", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); - lfs_mkdir(&lfs, "/") => LFS_ERR_EXIST; + // file open root, only works on files! lfs_file_t file; - lfs_file_open(&lfs, &file, "/", LFS_O_WRONLY | LFS_O_CREAT) - => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + // dir open root, only works on dirs! + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/") => 0; + lfs_dir_close(&lfs, &dir) => 0; + + // rename root, this should error + lfs_rename(&lfs, "/", "coffee") => LFS_ERR_INVAL; + + lfs_mkdir(&lfs, "coffee") => 0; + lfs_rename(&lfs, "coffee", "/") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee") => 0; + + lfs_rename(&lfs, "/", "/") => LFS_ERR_INVAL; + + // stat root + lfs_stat(&lfs, "/", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + + // remove root, this should error lfs_remove(&lfs, "/") => LFS_ERR_INVAL; + + // stat root + lfs_stat(&lfs, "/", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_unmount(&lfs) => 0; ''' -# root representations -[cases.test_paths_root_reprs] +# other root representations +[cases.test_paths_root_aliases] +defines.DIR = [false, true] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; struct lfs_info info; + + // create root, this should error + if (DIR) { + lfs_mkdir(&lfs, "/") => LFS_ERR_EXIST; + lfs_mkdir(&lfs, "") => LFS_ERR_EXIST; + lfs_mkdir(&lfs, ".") => LFS_ERR_EXIST; + lfs_mkdir(&lfs, "..") => LFS_ERR_EXIST; + lfs_mkdir(&lfs, "./") => LFS_ERR_EXIST; + lfs_mkdir(&lfs, "/.") => LFS_ERR_EXIST; + lfs_mkdir(&lfs, "//") => LFS_ERR_EXIST; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "/", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, ".", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "..", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "./", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/.", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "//", + LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; + } + + // stat root lfs_stat(&lfs, "/", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); @@ -244,93 +2214,2127 @@ code = ''' lfs_stat(&lfs, "..", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "./", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "/.", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); lfs_stat(&lfs, "//", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); + + // file open root, only works on files! + lfs_file_t file; + lfs_file_open(&lfs, &file, "/", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, ".", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "..", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "./", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "/.", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "//", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + + // dir open root, only works on dirs! + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "/") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, ".") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "..") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "./") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "/.") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "//") => 0; + lfs_dir_close(&lfs, &dir) => 0; + + // rename root, this should error + lfs_rename(&lfs, "/", "coffee") => LFS_ERR_INVAL; + lfs_rename(&lfs, "", "coffee") => LFS_ERR_INVAL; + lfs_rename(&lfs, ".", "coffee") => LFS_ERR_INVAL; + lfs_rename(&lfs, "..", "coffee") => LFS_ERR_INVAL; + lfs_rename(&lfs, "./", "coffee") => LFS_ERR_INVAL; + lfs_rename(&lfs, "/.", "coffee") => LFS_ERR_INVAL; + lfs_rename(&lfs, "//", "coffee") => LFS_ERR_INVAL; + + lfs_mkdir(&lfs, "coffee") => 0; + lfs_rename(&lfs, "coffee", "/") => LFS_ERR_INVAL; + lfs_rename(&lfs, "coffee", "") => LFS_ERR_INVAL; + lfs_rename(&lfs, "coffee", ".") => LFS_ERR_INVAL; + lfs_rename(&lfs, "coffee", "..") => LFS_ERR_INVAL; + lfs_rename(&lfs, "coffee", "./") => LFS_ERR_INVAL; + lfs_rename(&lfs, "coffee", "/.") => LFS_ERR_INVAL; + lfs_rename(&lfs, "coffee", "//") => LFS_ERR_INVAL; + lfs_remove(&lfs, "coffee") => 0; + + lfs_rename(&lfs, "/", "/") => LFS_ERR_INVAL; + lfs_rename(&lfs, "", "") => LFS_ERR_INVAL; + lfs_rename(&lfs, ".", ".") => LFS_ERR_INVAL; + lfs_rename(&lfs, "..", "..") => LFS_ERR_INVAL; + lfs_rename(&lfs, "./", "./") => LFS_ERR_INVAL; + lfs_rename(&lfs, "/.", "/.") => LFS_ERR_INVAL; + lfs_rename(&lfs, "//", "//") => LFS_ERR_INVAL; + + // stat root + lfs_stat(&lfs, "/", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, ".", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "..", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); lfs_stat(&lfs, "./", &info) => 0; assert(strcmp(info.name, "/") == 0); assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "/.", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "//", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + + // remove root, this should error + lfs_remove(&lfs, "/") => LFS_ERR_INVAL; + lfs_remove(&lfs, "") => LFS_ERR_INVAL; + lfs_remove(&lfs, ".") => LFS_ERR_INVAL; + lfs_remove(&lfs, "..") => LFS_ERR_INVAL; + lfs_remove(&lfs, "./") => LFS_ERR_INVAL; + lfs_remove(&lfs, "/.") => LFS_ERR_INVAL; + lfs_remove(&lfs, "//") => LFS_ERR_INVAL; + + // stat root + lfs_stat(&lfs, "/", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, ".", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "..", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "./", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "/.", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_stat(&lfs, "//", &info) => 0; + assert(strcmp(info.name, "/") == 0); + assert(info.type == LFS_TYPE_DIR); + lfs_unmount(&lfs) => 0; ''' -# superblock conflict test -[cases.test_paths_superblock_conflict] +# superblock magic shouldn't appear as a file +[cases.test_paths_magic_noent] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; + + // stat littlefs, which shouldn't exist struct lfs_info info; lfs_stat(&lfs, "littlefs", &info) => LFS_ERR_NOENT; + + // dir open littlefs, which shouldn't exist + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "littlefs") => LFS_ERR_NOENT; + + // rename littlefs, which shouldn't exist + lfs_rename(&lfs, "littlefs", "coffee") => LFS_ERR_NOENT; + + // remove littlefs, which shouldn't exist lfs_remove(&lfs, "littlefs") => LFS_ERR_NOENT; - lfs_mkdir(&lfs, "littlefs") => 0; + // stat littlefs, which shouldn't exist + lfs_stat(&lfs, "coffee", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "littlefs", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' + +# superblock magic shouldn't conflict with files, that would be silly +[cases.test_paths_magic_conflict] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create littlefs + if (DIR) { + lfs_mkdir(&lfs, "littlefs") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "littlefs", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat littlefs + struct lfs_info info; lfs_stat(&lfs, "littlefs", &info) => 0; assert(strcmp(info.name, "littlefs") == 0); - assert(info.type == LFS_TYPE_DIR); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open littlefs, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "littlefs", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "littlefs", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open littlefs, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "littlefs") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "littlefs") => LFS_ERR_NOTDIR; + } + + // rename littlefs + lfs_rename(&lfs, "littlefs", "coffee") => 0; + lfs_rename(&lfs, "coffee", "littlefs") => 0; + + // stat littlefs + lfs_stat(&lfs, "littlefs", &info) => 0; + assert(strcmp(info.name, "littlefs") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "coffee", &info) => LFS_ERR_NOENT; + + // remove littlefs lfs_remove(&lfs, "littlefs") => 0; + + // stat littlefs lfs_stat(&lfs, "littlefs", &info) => LFS_ERR_NOENT; + lfs_unmount(&lfs) => 0; ''' -# max path test -[cases.test_paths_max] +# test name too long +[cases.test_paths_nametoolong] +defines.DIR = [false, true] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; - lfs_mkdir(&lfs, "coffee") => 0; - lfs_mkdir(&lfs, "coffee/hotcoffee") => 0; - lfs_mkdir(&lfs, "coffee/warmcoffee") => 0; - lfs_mkdir(&lfs, "coffee/coldcoffee") => 0; + char a_name[512]; + memset(a_name, 'a', LFS_NAME_MAX+1); + a_name[LFS_NAME_MAX+1] = '\0'; + + // create names that are too long, should error char path[1024]; - memset(path, 'w', LFS_NAME_MAX+1); - path[LFS_NAME_MAX+1] = '\0'; - lfs_mkdir(&lfs, path) => LFS_ERR_NAMETOOLONG; - lfs_file_t file; - lfs_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT) - => LFS_ERR_NAMETOOLONG; + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + sprintf(path, "coffee/%s", a_name); + lfs_mkdir(&lfs, path) => LFS_ERR_NAMETOOLONG; + } else { + lfs_file_t file; + sprintf(path, "coffee/%s", a_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_NAMETOOLONG; + } + + // stat paths + struct lfs_info info; + sprintf(path, "coffee/%s", a_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + + // file open paths, only works on files! + lfs_file_t file; + sprintf(path, "coffee/%s", a_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => LFS_ERR_NOENT; + + // dir open paths, only works on dirs! + lfs_dir_t dir; + sprintf(path, "coffee/%s", a_name); + lfs_dir_open(&lfs, &dir, path) => LFS_ERR_NOENT; + + // rename paths + lfs_mkdir(&lfs, "espresso") => 0; + sprintf(path, "coffee/%s", a_name); + lfs_rename(&lfs, path, "espresso/espresso") => LFS_ERR_NOENT; + + // renaming with too long a destination is tricky! + if (DIR) { + lfs_mkdir(&lfs, "coffee/drip") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/drip", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + sprintf(path, "espresso/%s", a_name); + lfs_rename(&lfs, "coffee/drip", path) => LFS_ERR_NAMETOOLONG; + + // stat paths + lfs_stat(&lfs, "coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + sprintf(path, "espresso/%s", a_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + + // remove paths + sprintf(path, "espresso/%s", a_name); + lfs_remove(&lfs, path) => LFS_ERR_NOENT; + + // stat paths + lfs_stat(&lfs, "coffee/drip", &info) => 0; + assert(strcmp(info.name, "drip") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + sprintf(path, "espresso/%s", a_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; - memcpy(path, "coffee/", strlen("coffee/")); - memset(path+strlen("coffee/"), 'w', LFS_NAME_MAX+1); - path[strlen("coffee/")+LFS_NAME_MAX+1] = '\0'; - lfs_mkdir(&lfs, path) => LFS_ERR_NAMETOOLONG; - lfs_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT) - => LFS_ERR_NAMETOOLONG; lfs_unmount(&lfs) => 0; ''' -# really big path test -[cases.test_paths_really_big] +# test name really long but not too long +[cases.test_paths_namejustlongenough] +defines.DIR = [false, true] code = ''' lfs_t lfs; lfs_format(&lfs, cfg) => 0; lfs_mount(&lfs, cfg) => 0; - lfs_mkdir(&lfs, "coffee") => 0; - lfs_mkdir(&lfs, "coffee/hotcoffee") => 0; - lfs_mkdir(&lfs, "coffee/warmcoffee") => 0; - lfs_mkdir(&lfs, "coffee/coldcoffee") => 0; + char a_name[512]; + memset(a_name, 'a', LFS_NAME_MAX); + a_name[LFS_NAME_MAX] = '\0'; + char b_name[512]; + memset(b_name, 'b', LFS_NAME_MAX); + b_name[LFS_NAME_MAX] = '\0'; + char c_name[512]; + memset(c_name, 'c', LFS_NAME_MAX); + c_name[LFS_NAME_MAX] = '\0'; + char d_name[512]; + memset(d_name, 'd', LFS_NAME_MAX); + d_name[LFS_NAME_MAX] = '\0'; + char e_name[512]; + memset(e_name, 'e', LFS_NAME_MAX); + e_name[LFS_NAME_MAX] = '\0'; + char f_name[512]; + memset(f_name, 'f', LFS_NAME_MAX); + f_name[LFS_NAME_MAX] = '\0'; + char g_name[512]; + memset(g_name, 'g', LFS_NAME_MAX); + g_name[LFS_NAME_MAX] = '\0'; + char h_name[512]; + memset(h_name, 'h', LFS_NAME_MAX); + h_name[LFS_NAME_MAX] = '\0'; + char i_name[512]; + memset(i_name, 'i', LFS_NAME_MAX); + i_name[LFS_NAME_MAX] = '\0'; + char j_name[512]; + memset(j_name, 'j', LFS_NAME_MAX); + j_name[LFS_NAME_MAX] = '\0'; + char k_name[512]; + memset(k_name, 'k', LFS_NAME_MAX); + k_name[LFS_NAME_MAX] = '\0'; + char l_name[512]; + memset(l_name, 'l', LFS_NAME_MAX); + l_name[LFS_NAME_MAX] = '\0'; + + // create names that aren't too long + lfs_mkdir(&lfs, c_name) => 0; char path[1024]; - memset(path, 'w', LFS_NAME_MAX); - path[LFS_NAME_MAX] = '\0'; - lfs_mkdir(&lfs, path) => 0; + if (DIR) { + sprintf(path, "%s/%s", c_name, a_name); + lfs_mkdir(&lfs, path) => 0; + sprintf(path, "%s/%s", c_name, b_name); + lfs_mkdir(&lfs, path) => 0; + sprintf(path, "%s/%s", c_name, c_name); + lfs_mkdir(&lfs, path) => 0; + sprintf(path, "%s/%s", c_name, d_name); + lfs_mkdir(&lfs, path) => 0; + sprintf(path, "%s/%s", c_name, e_name); + lfs_mkdir(&lfs, path) => 0; + sprintf(path, "%s/%s", c_name, f_name); + lfs_mkdir(&lfs, path) => 0; + } else { + lfs_file_t file; + sprintf(path, "%s/%s", c_name, a_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, b_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, c_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, d_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, e_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, f_name); + lfs_file_open(&lfs, &file, path, + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + sprintf(path, "%s/%s", c_name, a_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, a_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + sprintf(path, "%s/%s", c_name, b_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, b_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + sprintf(path, "%s/%s", c_name, c_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, c_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + sprintf(path, "%s/%s", c_name, d_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, d_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + sprintf(path, "%s/%s", c_name, e_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, e_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + sprintf(path, "%s/%s", c_name, f_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, f_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + sprintf(path, "%s/%s", c_name, a_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => LFS_ERR_ISDIR; + sprintf(path, "%s/%s", c_name, b_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => LFS_ERR_ISDIR; + sprintf(path, "%s/%s", c_name, c_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => LFS_ERR_ISDIR; + sprintf(path, "%s/%s", c_name, d_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => LFS_ERR_ISDIR; + sprintf(path, "%s/%s", c_name, e_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => LFS_ERR_ISDIR; + sprintf(path, "%s/%s", c_name, f_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + sprintf(path, "%s/%s", c_name, a_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, b_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, c_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, d_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, e_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", c_name, f_name); + lfs_file_open(&lfs, &file, path, + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + sprintf(path, "%s/%s", c_name, a_name); + lfs_dir_open(&lfs, &dir, path) => 0; + lfs_dir_close(&lfs, &dir) => 0; + sprintf(path, "%s/%s", c_name, b_name); + lfs_dir_open(&lfs, &dir, path) => 0; + lfs_dir_close(&lfs, &dir) => 0; + sprintf(path, "%s/%s", c_name, c_name); + lfs_dir_open(&lfs, &dir, path) => 0; + lfs_dir_close(&lfs, &dir) => 0; + sprintf(path, "%s/%s", c_name, d_name); + lfs_dir_open(&lfs, &dir, path) => 0; + lfs_dir_close(&lfs, &dir) => 0; + sprintf(path, "%s/%s", c_name, e_name); + lfs_dir_open(&lfs, &dir, path) => 0; + lfs_dir_close(&lfs, &dir) => 0; + sprintf(path, "%s/%s", c_name, f_name); + lfs_dir_open(&lfs, &dir, path) => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + sprintf(path, "%s/%s", c_name, a_name); + lfs_dir_open(&lfs, &dir, path) => LFS_ERR_NOTDIR; + sprintf(path, "%s/%s", c_name, b_name); + lfs_dir_open(&lfs, &dir, path) => LFS_ERR_NOTDIR; + sprintf(path, "%s/%s", c_name, c_name); + lfs_dir_open(&lfs, &dir, path) => LFS_ERR_NOTDIR; + sprintf(path, "%s/%s", c_name, d_name); + lfs_dir_open(&lfs, &dir, path) => LFS_ERR_NOTDIR; + sprintf(path, "%s/%s", c_name, e_name); + lfs_dir_open(&lfs, &dir, path) => LFS_ERR_NOTDIR; + sprintf(path, "%s/%s", c_name, f_name); + lfs_dir_open(&lfs, &dir, path) => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, e_name) => 0; + char path_[1024]; + sprintf(path, "%s/%s", c_name, a_name); + sprintf(path_, "%s/%s", e_name, g_name); + lfs_rename(&lfs, path, path_) => 0; + sprintf(path, "%s/%s", c_name, b_name); + sprintf(path_, "%s/%s", e_name, h_name); + lfs_rename(&lfs, path, path_) => 0; + sprintf(path, "%s/%s", c_name, c_name); + sprintf(path_, "%s/%s", e_name, i_name); + lfs_rename(&lfs, path, path_) => 0; + sprintf(path, "%s/%s", c_name, d_name); + sprintf(path_, "%s/%s", e_name, j_name); + lfs_rename(&lfs, path, path_) => 0; + sprintf(path, "%s/%s", c_name, e_name); + sprintf(path_, "%s/%s", e_name, k_name); + lfs_rename(&lfs, path, path_) => 0; + sprintf(path, "%s/%s", c_name, f_name); + sprintf(path_, "%s/%s", e_name, l_name); + lfs_rename(&lfs, path, path_) => 0; + + // stat paths + sprintf(path, "%s/%s", e_name, g_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, g_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + sprintf(path, "%s/%s", e_name, h_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, h_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + sprintf(path, "%s/%s", e_name, i_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, i_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + sprintf(path, "%s/%s", e_name, j_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, j_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + sprintf(path, "%s/%s", e_name, k_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, k_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + sprintf(path, "%s/%s", e_name, l_name); + lfs_stat(&lfs, path, &info) => 0; + assert(strcmp(info.name, l_name) == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + sprintf(path, "%s/%s", c_name, a_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + sprintf(path, "%s/%s", c_name, b_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + sprintf(path, "%s/%s", c_name, c_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + sprintf(path, "%s/%s", c_name, d_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + sprintf(path, "%s/%s", c_name, e_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + sprintf(path, "%s/%s", c_name, f_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + + // remove paths + sprintf(path, "%s/%s", e_name, g_name); lfs_remove(&lfs, path) => 0; - lfs_file_t file; - lfs_file_open(&lfs, &file, path, - LFS_O_WRONLY | LFS_O_CREAT) => 0; - lfs_file_close(&lfs, &file) => 0; + sprintf(path, "%s/%s", e_name, h_name); + lfs_remove(&lfs, path) => 0; + sprintf(path, "%s/%s", e_name, i_name); + lfs_remove(&lfs, path) => 0; + sprintf(path, "%s/%s", e_name, j_name); + lfs_remove(&lfs, path) => 0; + sprintf(path, "%s/%s", e_name, k_name); + lfs_remove(&lfs, path) => 0; + sprintf(path, "%s/%s", e_name, l_name); lfs_remove(&lfs, path) => 0; - memcpy(path, "coffee/", strlen("coffee/")); - memset(path+strlen("coffee/"), 'w', LFS_NAME_MAX); - path[strlen("coffee/")+LFS_NAME_MAX] = '\0'; - lfs_mkdir(&lfs, path) => 0; - lfs_remove(&lfs, path) => 0; - lfs_file_open(&lfs, &file, path, - LFS_O_WRONLY | LFS_O_CREAT) => 0; - lfs_file_close(&lfs, &file) => 0; - lfs_remove(&lfs, path) => 0; + // stat paths + sprintf(path, "%s/%s", e_name, g_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + sprintf(path, "%s/%s", e_name, h_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + sprintf(path, "%s/%s", e_name, i_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + sprintf(path, "%s/%s", e_name, j_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + sprintf(path, "%s/%s", e_name, k_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + sprintf(path, "%s/%s", e_name, l_name); + lfs_stat(&lfs, path, &info) => LFS_ERR_NOENT; + lfs_unmount(&lfs) => 0; ''' +# a quick utf8 test, though utf8 is easy to support +[cases.test_paths_utf8] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "coffee") => 0; + if (DIR) { + lfs_mkdir(&lfs, "coffee/dripcoffee") => 0; + lfs_mkdir(&lfs, "coffee/coldbrew") => 0; + lfs_mkdir(&lfs, "coffee/türkkahvesi") => 0; + lfs_mkdir(&lfs, "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀") => 0; + lfs_mkdir(&lfs, "coffee/càphêđá") => 0; + lfs_mkdir(&lfs, "coffee/โอเลี้ยง") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/dripcoffee", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/türkkahvesi", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/càphêđá", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/โอเลี้ยง", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "coffee/dripcoffee", &info) => 0; + assert(strcmp(info.name, "dripcoffee") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/coldbrew", &info) => 0; + assert(strcmp(info.name, "coldbrew") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/türkkahvesi", &info) => 0; + assert(strcmp(info.name, "türkkahvesi") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀", &info) => 0; + assert(strcmp(info.name, "ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/càphêđá", &info) => 0; + assert(strcmp(info.name, "càphêđá") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "coffee/โอเลี้ยง", &info) => 0; + assert(strcmp(info.name, "โอเลี้ยง") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/dripcoffee", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/türkkahvesi", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/càphêđá", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "coffee/โอเลี้ยง", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "coffee/dripcoffee", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/coldbrew", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/türkkahvesi", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/càphêđá", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "coffee/โอเลี้ยง", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "coffee/dripcoffee") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/coldbrew") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/türkkahvesi") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/càphêđá") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "coffee/โอเลี้ยง") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "coffee/dripcoffee") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/coldbrew") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/türkkahvesi") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/càphêđá") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "coffee/โอเลี้ยง") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "caffè") => 0; + lfs_rename(&lfs, + "coffee/dripcoffee", + "caffè/espresso") => 0; + lfs_rename(&lfs, + "coffee/coldbrew", + "caffè/americano") => 0; + lfs_rename(&lfs, + "coffee/türkkahvesi", + "caffè/macchiato") => 0; + lfs_rename(&lfs, + "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀", + "caffè/latte") => 0; + lfs_rename(&lfs, + "coffee/càphêđá", + "caffè/cappuccino") => 0; + lfs_rename(&lfs, + "coffee/โอเลี้ยง", + "caffè/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "caffè/espresso", &info) => 0; + assert(strcmp(info.name, "espresso") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "caffè/americano", &info) => 0; + assert(strcmp(info.name, "americano") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "caffè/macchiato", &info) => 0; + assert(strcmp(info.name, "macchiato") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "caffè/latte", &info) => 0; + assert(strcmp(info.name, "latte") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "caffè/cappuccino", &info) => 0; + assert(strcmp(info.name, "cappuccino") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "caffè/mocha", &info) => 0; + assert(strcmp(info.name, "mocha") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "coffee/dripcoffee", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/coldbrew", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/türkkahvesi", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/ꦏꦺꦴꦥꦶꦠꦸꦧꦿꦸꦏ꧀", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/càphêđá", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "coffee/โอเลี้ยง", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "caffè/espresso") => 0; + lfs_remove(&lfs, "caffè/americano") => 0; + lfs_remove(&lfs, "caffè/macchiato") => 0; + lfs_remove(&lfs, "caffè/latte") => 0; + lfs_remove(&lfs, "caffè/cappuccino") => 0; + lfs_remove(&lfs, "caffè/mocha") => 0; + + // stat paths + lfs_stat(&lfs, "caffè/espresso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "caffè/americano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "caffè/macchiato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "caffè/latte", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "caffè/cappuccino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "caffè/mocha", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' + +# more utf8 tests +[cases.test_paths_utf8_ipa] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "ˈkɔ.fi") => 0; + if (DIR) { + lfs_mkdir(&lfs, "ˈkɔ.fi/dɹɪpˈkɔ.fi") => 0; + lfs_mkdir(&lfs, "ˈkɔ.fi/koʊldbɹuː") => 0; + lfs_mkdir(&lfs, "ˈkɔ.fi/tyɾckɑhvɛˈsi") => 0; + lfs_mkdir(&lfs, "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚") => 0; + lfs_mkdir(&lfs, "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥") => 0; + lfs_mkdir(&lfs, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/dɹɪpˈkɔ.fi", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/koʊldbɹuː", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/tyɾckɑhvɛˈsi", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "ˈkɔ.fi/dɹɪpˈkɔ.fi", &info) => 0; + assert(strcmp(info.name, "dɹɪpˈkɔ.fi") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "ˈkɔ.fi/koʊldbɹuː", &info) => 0; + assert(strcmp(info.name, "koʊldbɹuː") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "ˈkɔ.fi/tyɾckɑhvɛˈsi", &info) => 0; + assert(strcmp(info.name, "tyɾckɑhvɛˈsi") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚", &info) => 0; + assert(strcmp(info.name, "ˈko.piˈt̪up̚.rʊk̚") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥", &info) => 0; + assert(strcmp(info.name, "kaː˨˩fe˧˧ɗaː˧˥") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥", &info) => 0; + assert(strcmp(info.name, "ʔoː˧.lia̯ŋ˦˥") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/dɹɪpˈkɔ.fi", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/koʊldbɹuː", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/tyɾckɑhvɛˈsi", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/dɹɪpˈkɔ.fi", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/koʊldbɹuː", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/tyɾckɑhvɛˈsi", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/dɹɪpˈkɔ.fi") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/koʊldbɹuː") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/tyɾckɑhvɛˈsi") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/dɹɪpˈkɔ.fi") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/koʊldbɹuː") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/tyɾckɑhvɛˈsi") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "kafˈfɛ") => 0; + lfs_rename(&lfs, + "ˈkɔ.fi/dɹɪpˈkɔ.fi", + "kafˈfɛ/eˈsprɛsso") => 0; + lfs_rename(&lfs, + "ˈkɔ.fi/koʊldbɹuː", + "kafˈfɛ/ameriˈkano") => 0; + lfs_rename(&lfs, + "ˈkɔ.fi/tyɾckɑhvɛˈsi", + "kafˈfɛ/makˈkjato") => 0; + lfs_rename(&lfs, + "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚", + "kafˈfɛ/ˈlat.te") => 0; + lfs_rename(&lfs, + "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥", + "kafˈfɛ/kapputˈt͡ʃino") => 0; + lfs_rename(&lfs, + "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥", + "kafˈfɛ/ˈmoʊkə") => 0; + + // stat paths + lfs_stat(&lfs, "kafˈfɛ/eˈsprɛsso", &info) => 0; + assert(strcmp(info.name, "eˈsprɛsso") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "kafˈfɛ/ameriˈkano", &info) => 0; + assert(strcmp(info.name, "ameriˈkano") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "kafˈfɛ/makˈkjato", &info) => 0; + assert(strcmp(info.name, "makˈkjato") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "kafˈfɛ/ˈlat.te", &info) => 0; + assert(strcmp(info.name, "ˈlat.te") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "kafˈfɛ/kapputˈt͡ʃino", &info) => 0; + assert(strcmp(info.name, "kapputˈt͡ʃino") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "kafˈfɛ/ˈmoʊkə", &info) => 0; + assert(strcmp(info.name, "ˈmoʊkə") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "ˈkɔ.fi/dɹɪpˈkɔ.fi", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "ˈkɔ.fi/koʊldbɹuː", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "ˈkɔ.fi/tyɾckɑhvɛˈsi", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "ˈkɔ.fi/ˈko.piˈt̪up̚.rʊk̚", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "ˈkɔ.fi/kaː˨˩fe˧˧ɗaː˧˥", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "ˈkɔ.fi/ʔoː˧.lia̯ŋ˦˥", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "kafˈfɛ/eˈsprɛsso") => 0; + lfs_remove(&lfs, "kafˈfɛ/ameriˈkano") => 0; + lfs_remove(&lfs, "kafˈfɛ/makˈkjato") => 0; + lfs_remove(&lfs, "kafˈfɛ/ˈlat.te") => 0; + lfs_remove(&lfs, "kafˈfɛ/kapputˈt͡ʃino") => 0; + lfs_remove(&lfs, "kafˈfɛ/ˈmoʊkə") => 0; + + // stat paths + lfs_stat(&lfs, "kafˈfɛ/eˈsprɛsso", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "kafˈfɛ/ameriˈkano", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "kafˈfɛ/makˈkjato", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "kafˈfɛ/ˈlat.te", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "kafˈfɛ/kapputˈt͡ʃino", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "kafˈfɛ/ˈmoʊkə", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' + +# test spaces have no problems +[cases.test_paths_spaces] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "c o f f e e") => 0; + if (DIR) { + lfs_mkdir(&lfs, "c o f f e e/d r i p") => 0; + lfs_mkdir(&lfs, "c o f f e e/c o l d b r e w") => 0; + lfs_mkdir(&lfs, "c o f f e e/t u r k i s h") => 0; + lfs_mkdir(&lfs, "c o f f e e/t u b r u k") => 0; + lfs_mkdir(&lfs, "c o f f e e/v i e t n a m e s e") => 0; + lfs_mkdir(&lfs, "c o f f e e/t h a i") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "c o f f e e/d r i p", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/c o l d b r e w", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/t u r k i s h", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/t u b r u k", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/v i e t n a m e s e", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/t h a i", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "c o f f e e/d r i p", &info) => 0; + assert(strcmp(info.name, "d r i p") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "c o f f e e/c o l d b r e w", &info) => 0; + assert(strcmp(info.name, "c o l d b r e w") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "c o f f e e/t u r k i s h", &info) => 0; + assert(strcmp(info.name, "t u r k i s h") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "c o f f e e/t u b r u k", &info) => 0; + assert(strcmp(info.name, "t u b r u k") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "c o f f e e/v i e t n a m e s e", &info) => 0; + assert(strcmp(info.name, "v i e t n a m e s e") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "c o f f e e/t h a i", &info) => 0; + assert(strcmp(info.name, "t h a i") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "c o f f e e/d r i p", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "c o f f e e/c o l d b r e w", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "c o f f e e/t u r k i s h", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "c o f f e e/t u b r u k", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "c o f f e e/v i e t n a m e s e", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "c o f f e e/t h a i", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "c o f f e e/d r i p", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/c o l d b r e w", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/t u r k i s h", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/t u b r u k", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/v i e t n a m e s e", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "c o f f e e/t h a i", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "c o f f e e/d r i p") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "c o f f e e/c o l d b r e w") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "c o f f e e/t u r k i s h") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "c o f f e e/t u b r u k") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "c o f f e e/v i e t n a m e s e") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "c o f f e e/t h a i") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "c o f f e e/d r i p") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "c o f f e e/c o l d b r e w") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "c o f f e e/t u r k i s h") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "c o f f e e/t u b r u k") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "c o f f e e/v i e t n a m e s e") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "c o f f e e/t h a i") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "e s p r e s s o") => 0; + lfs_rename(&lfs, + "c o f f e e/d r i p", + "e s p r e s s o/e s p r e s s o") => 0; + lfs_rename(&lfs, + "c o f f e e/c o l d b r e w", + "e s p r e s s o/a m e r i c a n o") => 0; + lfs_rename(&lfs, + "c o f f e e/t u r k i s h", + "e s p r e s s o/m a c c h i a t o") => 0; + lfs_rename(&lfs, + "c o f f e e/t u b r u k", + "e s p r e s s o/l a t t e") => 0; + lfs_rename(&lfs, + "c o f f e e/v i e t n a m e s e", + "e s p r e s s o/c a p p u c c i n o") => 0; + lfs_rename(&lfs, + "c o f f e e/t h a i", + "e s p r e s s o/m o c h a") => 0; + + // stat paths + lfs_stat(&lfs, "e s p r e s s o/e s p r e s s o", &info) => 0; + assert(strcmp(info.name, "e s p r e s s o") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "e s p r e s s o/a m e r i c a n o", &info) => 0; + assert(strcmp(info.name, "a m e r i c a n o") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "e s p r e s s o/m a c c h i a t o", &info) => 0; + assert(strcmp(info.name, "m a c c h i a t o") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "e s p r e s s o/l a t t e", &info) => 0; + assert(strcmp(info.name, "l a t t e") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "e s p r e s s o/c a p p u c c i n o", &info) => 0; + assert(strcmp(info.name, "c a p p u c c i n o") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "e s p r e s s o/m o c h a", &info) => 0; + assert(strcmp(info.name, "m o c h a") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "c o f f e e/d r i p", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "c o f f e e/c o l d b r e w", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "c o f f e e/t u r k i s h", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "c o f f e e/t u b r u k", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "c o f f e e/v i e t n a m e s e", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "c o f f e e/t h a i", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "e s p r e s s o/e s p r e s s o") => 0; + lfs_remove(&lfs, "e s p r e s s o/a m e r i c a n o") => 0; + lfs_remove(&lfs, "e s p r e s s o/m a c c h i a t o") => 0; + lfs_remove(&lfs, "e s p r e s s o/l a t t e") => 0; + lfs_remove(&lfs, "e s p r e s s o/c a p p u c c i n o") => 0; + lfs_remove(&lfs, "e s p r e s s o/m o c h a") => 0; + + // stat paths + lfs_stat(&lfs, "e s p r e s s o/e s p r e s s o", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "e s p r e s s o/a m e r i c a n o", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "e s p r e s s o/m a c c h i a t o", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "e s p r e s s o/l a t t e", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "e s p r e s s o/c a p p u c c i n o", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "e s p r e s s o/m o c h a", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' + +# test with only spaces +# +# please don't do this +[cases.test_paths_oopsallspaces] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, " ") => 0; + if (DIR) { + lfs_mkdir(&lfs, " / ") => 0; + lfs_mkdir(&lfs, " / ") => 0; + lfs_mkdir(&lfs, " / ") => 0; + lfs_mkdir(&lfs, " / ") => 0; + lfs_mkdir(&lfs, " / ") => 0; + lfs_mkdir(&lfs, " / ") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, " / ", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, " / ") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, " / ") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, " / ") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, " / ") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, " / ") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, " / ") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, " / ") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, " / ") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, " / ") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, " / ") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, " / ") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, " / ") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, " ") => 0; + lfs_rename(&lfs, + " / ", + " / ") => 0; + lfs_rename(&lfs, + " / ", + " / ") => 0; + lfs_rename(&lfs, + " / ", + " / ") => 0; + lfs_rename(&lfs, + " / ", + " / ") => 0; + lfs_rename(&lfs, + " / ", + " / ") => 0; + lfs_rename(&lfs, + " / ", + " / ") => 0; + + // stat paths + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, " / ", &info) => 0; + assert(strcmp(info.name, " ") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, " / ") => 0; + lfs_remove(&lfs, " / ") => 0; + lfs_remove(&lfs, " / ") => 0; + lfs_remove(&lfs, " / ") => 0; + lfs_remove(&lfs, " / ") => 0; + lfs_remove(&lfs, " / ") => 0; + + // stat paths + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, " / ", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' + +# test with only ascii control characters +# +# littlefs only cares about "./" and NULL +[cases.test_paths_nonprintable] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "\x0c") => 0; + if (DIR) { + lfs_mkdir(&lfs, "\x0c/\x01") => 0; + lfs_mkdir(&lfs, "\x0c/\x02") => 0; + lfs_mkdir(&lfs, "\x0c/\x03") => 0; + lfs_mkdir(&lfs, "\x0c/\x04") => 0; + lfs_mkdir(&lfs, "\x0c/\x05") => 0; + lfs_mkdir(&lfs, "\x0c/\x06") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\x0c/\x01", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x02", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x03", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x04", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x05", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x06", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "\x0c/\x01", &info) => 0; + assert(strcmp(info.name, "\x01") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x0c/\x02", &info) => 0; + assert(strcmp(info.name, "\x02") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x0c/\x03", &info) => 0; + assert(strcmp(info.name, "\x03") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x0c/\x04", &info) => 0; + assert(strcmp(info.name, "\x04") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x0c/\x05", &info) => 0; + assert(strcmp(info.name, "\x05") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x0c/\x06", &info) => 0; + assert(strcmp(info.name, "\x06") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\x0c/\x01", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x0c/\x02", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x0c/\x03", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x0c/\x04", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x0c/\x05", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x0c/\x06", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\x0c/\x01", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x02", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x03", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x04", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x05", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x0c/\x06", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "\x0c/\x01") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\x0c/\x02") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\x0c/\x03") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\x0c/\x04") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\x0c/\x05") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\x0c/\x06") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "\x0c/\x01") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\x0c/\x02") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\x0c/\x03") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\x0c/\x04") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\x0c/\x05") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\x0c/\x06") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "\x0e") => 0; + lfs_rename(&lfs, + "\x0c/\x01", + "\x0e/\x1a") => 0; + lfs_rename(&lfs, + "\x0c/\x02", + "\x0e/\x1b") => 0; + lfs_rename(&lfs, + "\x0c/\x03", + "\x0e/\x1c") => 0; + lfs_rename(&lfs, + "\x0c/\x04", + "\x0e/\x1d") => 0; + lfs_rename(&lfs, + "\x0c/\x05", + "\x0e/\x1e") => 0; + lfs_rename(&lfs, + "\x0c/\x06", + "\x0e/\x1f") => 0; + + // stat paths + lfs_stat(&lfs, "\x0e/\x1a", &info) => 0; + assert(strcmp(info.name, "\x1a") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x0e/\x1b", &info) => 0; + assert(strcmp(info.name, "\x1b") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x0e/\x1c", &info) => 0; + assert(strcmp(info.name, "\x1c") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x0e/\x1d", &info) => 0; + assert(strcmp(info.name, "\x1d") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x0e/\x1e", &info) => 0; + assert(strcmp(info.name, "\x1e") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x0e/\x1f", &info) => 0; + assert(strcmp(info.name, "\x1f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "\x0c/\x01", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x0c/\x02", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x0c/\x03", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x0c/\x04", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x0c/\x05", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x0c/\x06", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "\x0e/\x1a") => 0; + lfs_remove(&lfs, "\x0e/\x1b") => 0; + lfs_remove(&lfs, "\x0e/\x1c") => 0; + lfs_remove(&lfs, "\x0e/\x1d") => 0; + lfs_remove(&lfs, "\x0e/\x1e") => 0; + lfs_remove(&lfs, "\x0e/\x1f") => 0; + + // stat paths + lfs_stat(&lfs, "\x0e/\x1a", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x0e/\x1b", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x0e/\x1c", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x0e/\x1d", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x0e/\x1e", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x0e/\x1f", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' + +# test with only ascii DELs +# +# I don't know why you'd do this +[cases.test_paths_oopsalldels] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "\x7f") => 0; + if (DIR) { + lfs_mkdir(&lfs, "\x7f/\x7f") => 0; + lfs_mkdir(&lfs, "\x7f/\x7f\x7f") => 0; + lfs_mkdir(&lfs, "\x7f/\x7f\x7f\x7f") => 0; + lfs_mkdir(&lfs, "\x7f/\x7f\x7f\x7f\x7f") => 0; + lfs_mkdir(&lfs, "\x7f/\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_mkdir(&lfs, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\x7f/\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "\x7f/\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x7f/\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x7f/\x7f\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x7f/\x7f\x7f\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x7f/\x7f\x7f\x7f\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f\x7f\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f\x7f\x7f\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\x7f/\x7f", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\x7f/\x7f", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f\x7f") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f\x7f\x7f") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f\x7f\x7f\x7f") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f\x7f") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f\x7f\x7f") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f\x7f\x7f\x7f") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f\x7f\x7f\x7f\x7f") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "\x7f\x7f") => 0; + lfs_rename(&lfs, + "\x7f/\x7f", + "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_rename(&lfs, + "\x7f/\x7f\x7f", + "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_rename(&lfs, + "\x7f/\x7f\x7f\x7f", + "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_rename(&lfs, + "\x7f/\x7f\x7f\x7f\x7f", + "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_rename(&lfs, + "\x7f/\x7f\x7f\x7f\x7f\x7f", + "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_rename(&lfs, + "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", + "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + + // stat paths + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f\x7f\x7f\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f\x7f\x7f\x7f\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f", &info) => 0; + assert(strcmp(info.name, "\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "\x7f/\x7f", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x7f/\x7f\x7f", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x7f/\x7f\x7f\x7f", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x7f/\x7f\x7f\x7f\x7f", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x7f/\x7f\x7f\x7f\x7f\x7f", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_remove(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_remove(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_remove(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_remove(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + lfs_remove(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f") => 0; + + // stat paths + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\x7f\x7f/\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' + +# test with invalid utf8 sequences +# +# Don't do this! These filenames are not utf8 and will probably break +# external tools. +# +[cases.test_paths_nonutf8] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "\xc0") => 0; + if (DIR) { + lfs_mkdir(&lfs, "\xc0/\xa0") => 0; + lfs_mkdir(&lfs, "\xc0/\xb0") => 0; + lfs_mkdir(&lfs, "\xc0/\xc0") => 0; + lfs_mkdir(&lfs, "\xc0/\xd0") => 0; + lfs_mkdir(&lfs, "\xc0/\xe0") => 0; + lfs_mkdir(&lfs, "\xc0/\xf0") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\xc0/\xa0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xb0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xc0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xd0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xe0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xf0", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "\xc0/\xa0", &info) => 0; + assert(strcmp(info.name, "\xa0") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xc0/\xb0", &info) => 0; + assert(strcmp(info.name, "\xb0") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xc0/\xc0", &info) => 0; + assert(strcmp(info.name, "\xc0") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xc0/\xd0", &info) => 0; + assert(strcmp(info.name, "\xd0") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xc0/\xe0", &info) => 0; + assert(strcmp(info.name, "\xe0") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xc0/\xf0", &info) => 0; + assert(strcmp(info.name, "\xf0") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\xc0/\xa0", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xc0/\xb0", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xc0/\xc0", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xc0/\xd0", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xc0/\xe0", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xc0/\xf0", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\xc0/\xa0", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xb0", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xc0", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xd0", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xe0", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xc0/\xf0", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "\xc0/\xa0") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\xc0/\xb0") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\xc0/\xc0") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\xc0/\xd0") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\xc0/\xe0") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\xc0/\xf0") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "\xc0/\xa0") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\xc0/\xb0") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\xc0/\xc0") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\xc0/\xd0") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\xc0/\xe0") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\xc0/\xf0") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "\xe0") => 0; + lfs_rename(&lfs, + "\xc0/\xa0", + "\xe0/\xaf") => 0; + lfs_rename(&lfs, + "\xc0/\xb0", + "\xe0/\xbf") => 0; + lfs_rename(&lfs, + "\xc0/\xc0", + "\xe0/\xcf") => 0; + lfs_rename(&lfs, + "\xc0/\xd0", + "\xe0/\xdf") => 0; + lfs_rename(&lfs, + "\xc0/\xe0", + "\xe0/\xef") => 0; + lfs_rename(&lfs, + "\xc0/\xf0", + "\xe0/\xff") => 0; + + // stat paths + lfs_stat(&lfs, "\xe0/\xaf", &info) => 0; + assert(strcmp(info.name, "\xaf") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xe0/\xbf", &info) => 0; + assert(strcmp(info.name, "\xbf") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xe0/\xcf", &info) => 0; + assert(strcmp(info.name, "\xcf") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xe0/\xdf", &info) => 0; + assert(strcmp(info.name, "\xdf") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xe0/\xef", &info) => 0; + assert(strcmp(info.name, "\xef") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xe0/\xff", &info) => 0; + assert(strcmp(info.name, "\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "\xc0/\xa0", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xc0/\xb0", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xc0/\xc0", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xc0/\xd0", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xc0/\xe0", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xc0/\xf0", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "\xe0/\xaf") => 0; + lfs_remove(&lfs, "\xe0/\xbf") => 0; + lfs_remove(&lfs, "\xe0/\xcf") => 0; + lfs_remove(&lfs, "\xe0/\xdf") => 0; + lfs_remove(&lfs, "\xe0/\xef") => 0; + lfs_remove(&lfs, "\xe0/\xff") => 0; + + // stat paths + lfs_stat(&lfs, "\xe0/\xaf", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xe0/\xbf", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xe0/\xcf", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xe0/\xdf", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xe0/\xef", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xe0/\xff", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +''' + +# test with only "\xff" characters +# +# Don't do this! These filenames are not utf8 and will probably break +# external tools. +# +[cases.test_paths_oopsallffs] +defines.DIR = [false, true] +code = ''' + lfs_t lfs; + lfs_format(&lfs, cfg) => 0; + lfs_mount(&lfs, cfg) => 0; + + // create paths + lfs_mkdir(&lfs, "\xff") => 0; + if (DIR) { + lfs_mkdir(&lfs, "\xff/\xff") => 0; + lfs_mkdir(&lfs, "\xff/\xff\xff") => 0; + lfs_mkdir(&lfs, "\xff/\xff\xff\xff") => 0; + lfs_mkdir(&lfs, "\xff/\xff\xff\xff\xff") => 0; + lfs_mkdir(&lfs, "\xff/\xff\xff\xff\xff\xff") => 0; + lfs_mkdir(&lfs, "\xff/\xff\xff\xff\xff\xff\xff") => 0; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\xff/\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff\xff", + LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // stat paths + struct lfs_info info; + lfs_stat(&lfs, "\xff/\xff", &info) => 0; + assert(strcmp(info.name, "\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xff/\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xff/\xff\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xff/\xff\xff\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xff/\xff\xff\xff\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff\xff\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xff/\xff\xff\xff\xff\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff\xff\xff\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + // file open paths, only works on files! + if (DIR) { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\xff/\xff", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xff/\xff\xff", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff\xff", + LFS_O_RDONLY) => LFS_ERR_ISDIR; + } else { + lfs_file_t file; + lfs_file_open(&lfs, &file, "\xff/\xff", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + lfs_file_open(&lfs, &file, "\xff/\xff\xff\xff\xff\xff\xff", + LFS_O_RDONLY) => 0; + lfs_file_close(&lfs, &file) => 0; + } + + // dir open paths, only works on dirs! + if (DIR) { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "\xff/\xff") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\xff/\xff\xff") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\xff/\xff\xff\xff") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\xff/\xff\xff\xff\xff") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\xff/\xff\xff\xff\xff\xff") => 0; + lfs_dir_close(&lfs, &dir) => 0; + lfs_dir_open(&lfs, &dir, "\xff/\xff\xff\xff\xff\xff\xff") => 0; + lfs_dir_close(&lfs, &dir) => 0; + } else { + lfs_dir_t dir; + lfs_dir_open(&lfs, &dir, "\xff/\xff") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\xff/\xff\xff") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\xff/\xff\xff\xff") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\xff/\xff\xff\xff\xff") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\xff/\xff\xff\xff\xff\xff") => LFS_ERR_NOTDIR; + lfs_dir_open(&lfs, &dir, "\xff/\xff\xff\xff\xff\xff\xff") => LFS_ERR_NOTDIR; + } + + // rename paths + lfs_mkdir(&lfs, "\xff\xff") => 0; + lfs_rename(&lfs, + "\xff/\xff", + "\xff\xff/\xff\xff\xff\xff\xff\xff") => 0; + lfs_rename(&lfs, + "\xff/\xff\xff", + "\xff\xff/\xff\xff\xff\xff\xff\xff\xff") => 0; + lfs_rename(&lfs, + "\xff/\xff\xff\xff", + "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff") => 0; + lfs_rename(&lfs, + "\xff/\xff\xff\xff\xff", + "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff") => 0; + lfs_rename(&lfs, + "\xff/\xff\xff\xff\xff\xff", + "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff") => 0; + lfs_rename(&lfs, + "\xff/\xff\xff\xff\xff\xff\xff", + "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff") => 0; + + // stat paths + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff\xff\xff\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff\xff\xff\xff\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff\xff\xff\xff\xff\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff\xff\xff\xff\xff\xff\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", &info) => 0; + assert(strcmp(info.name, "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff") == 0); + assert(info.type == ((DIR) ? LFS_TYPE_DIR : LFS_TYPE_REG)); + + lfs_stat(&lfs, "\xff/\xff", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xff/\xff\xff", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xff/\xff\xff\xff", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xff/\xff\xff\xff\xff", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xff/\xff\xff\xff\xff\xff", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xff/\xff\xff\xff\xff\xff\xff", &info) => LFS_ERR_NOENT; + + // remove paths + lfs_remove(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff") => 0; + lfs_remove(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff") => 0; + lfs_remove(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff") => 0; + lfs_remove(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff") => 0; + lfs_remove(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff") => 0; + lfs_remove(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff") => 0; + + // stat paths + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", &info) => LFS_ERR_NOENT; + lfs_stat(&lfs, "\xff\xff/\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", &info) => LFS_ERR_NOENT; + + lfs_unmount(&lfs) => 0; +'''