@@ -1273,21 +1273,19 @@ static int32_t lfs_dir_get(lfs_t *lfs, lfs_mdir_t *dir,
1273
1273
}
1274
1274
1275
1275
static int32_t lfs_dir_lookup (lfs_t * lfs , lfs_mdir_t * dir , const char * * path ) {
1276
- lfs_block_t pair [ 2 ] = { lfs -> root [ 0 ], lfs -> root [ 1 ]};
1276
+ // we reduce path to a single name if we can find it
1277
1277
const char * name = * path ;
1278
- lfs_size_t namelen ;
1279
- int32_t tag ;
1278
+ * path = NULL ;
1279
+
1280
+ // default to root dir
1281
+ int32_t tag = LFS_MKTAG (LFS_TYPE_DIR , 0x3ff , 0 );
1282
+ lfs_block_t pair [2 ] = {lfs -> root [0 ], lfs -> root [1 ]};
1280
1283
1281
1284
while (true) {
1282
- nextname :
1285
+ nextname :
1283
1286
// skip slashes
1284
1287
name += strspn (name , "/" );
1285
- namelen = strcspn (name , "/" );
1286
-
1287
- if (name [0 ] == '\0' ) {
1288
- // special case for root dir
1289
- return LFS_MKTAG (LFS_TYPE_DIR , 0x3ff , 0 );
1290
- }
1288
+ lfs_size_t namelen = strcspn (name , "/" );
1291
1289
1292
1290
// skip '.' and root '..'
1293
1291
if ((namelen == 1 && memcmp (name , "." , 1 ) == 0 ) ||
@@ -1320,10 +1318,31 @@ static int32_t lfs_dir_lookup(lfs_t *lfs, lfs_mdir_t *dir, const char **path) {
1320
1318
suffix += sufflen ;
1321
1319
}
1322
1320
1323
- // update what we've found
1324
- * path = name ;
1321
+ // found path
1322
+ if (name [0 ] == '\0' ) {
1323
+ return tag ;
1324
+ }
1325
1325
1326
- // find path
1326
+ // update what we've found if path is only a name
1327
+ if (strchr (name , '/' ) == NULL ) {
1328
+ * path = name ;
1329
+ }
1330
+
1331
+ // only continue if we hit a directory
1332
+ if (lfs_tagtype (tag ) != LFS_TYPE_DIR ) {
1333
+ return LFS_ERR_NOTDIR ;
1334
+ }
1335
+
1336
+ // grab the entry data
1337
+ if (lfs_tagid (tag ) != 0x3ff ) {
1338
+ int32_t res = lfs_dir_get (lfs , dir , 0x7c3ff000 ,
1339
+ LFS_MKTAG (LFS_TYPE_STRUCT , lfs_tagid (tag ), 8 ), pair );
1340
+ if (res < 0 ) {
1341
+ return res ;
1342
+ }
1343
+ }
1344
+
1345
+ // find entry matching name
1327
1346
while (true) {
1328
1347
tag = lfs_dir_find (lfs , dir , pair , 0x7c000fff ,
1329
1348
LFS_MKTAG (LFS_TYPE_NAME , 0 , namelen ), name );
@@ -1337,33 +1356,16 @@ static int32_t lfs_dir_lookup(lfs_t *lfs, lfs_mdir_t *dir, const char **path) {
1337
1356
}
1338
1357
1339
1358
if (!dir -> split ) {
1359
+ // couldn't find it
1340
1360
return LFS_ERR_NOENT ;
1341
1361
}
1342
1362
1343
1363
pair [0 ] = dir -> tail [0 ];
1344
1364
pair [1 ] = dir -> tail [1 ];
1345
1365
}
1346
1366
1367
+ // to next name
1347
1368
name += namelen ;
1348
- name += strspn (name , "/" );
1349
- if (name [0 ] == '\0' ) {
1350
- return tag ;
1351
- }
1352
-
1353
- // don't continue on if we didn't hit a directory
1354
- // TODO update with what's on master?
1355
- if (lfs_tagtype (tag ) != LFS_TYPE_DIR ) {
1356
- return LFS_ERR_NOTDIR ;
1357
- }
1358
-
1359
- // TODO optimize grab for inline files and like?
1360
- // TODO would this mean more code?
1361
- // grab the entry data
1362
- int32_t res = lfs_dir_get (lfs , dir , 0x7c3ff000 ,
1363
- LFS_MKTAG (LFS_TYPE_STRUCT , lfs_tagid (tag ), 8 ), pair );
1364
- if (res < 0 ) {
1365
- return res ;
1366
- }
1367
1369
}
1368
1370
}
1369
1371
@@ -1408,11 +1410,8 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
1408
1410
1409
1411
lfs_mdir_t cwd ;
1410
1412
int32_t res = lfs_dir_lookup (lfs , & cwd , & path );
1411
- if (res != LFS_ERR_NOENT || strchr (path , '/' ) != NULL ) {
1412
- if (res >= 0 ) {
1413
- return LFS_ERR_EXIST ;
1414
- }
1415
- return res ;
1413
+ if (res != LFS_ERR_NOENT || !path ) {
1414
+ return (res < 0 ) ? res : LFS_ERR_EXIST ;
1416
1415
}
1417
1416
1418
1417
// check that name fits
@@ -1806,7 +1805,7 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
1806
1805
// allocate entry for file if it doesn't exist
1807
1806
lfs_mdir_t cwd ;
1808
1807
int32_t tag = lfs_dir_lookup (lfs , & cwd , & path );
1809
- if (tag < 0 && (tag != LFS_ERR_NOENT || strchr ( path , '/' ) != NULL )) {
1808
+ if (tag < 0 && (tag != LFS_ERR_NOENT || ! path )) {
1810
1809
return tag ;
1811
1810
}
1812
1811
0 commit comments