@@ -261,7 +261,14 @@ void CardReader::selectByName(SdFile dir, const char * const match) {
261
261
}
262
262
263
263
//
264
- // Recursive method to list all files within a folder
264
+ // Recursive method to print all files within a folder in flat
265
+ // DOS 8.3 format. This style of listing is the most compatible
266
+ // with legacy hosts.
267
+ //
268
+ // This method recurses to unlimited depth and lists every
269
+ // G-code file within the given parent. If the hierarchy is
270
+ // very deep this can blow up the stack, so a 'depth' parameter
271
+ // (as with printListingJSON) would be a good addition.
265
272
//
266
273
void CardReader::printListing (SdFile parent, const char * const prepend/* =nullptr*/ ) {
267
274
dir_t p;
@@ -288,17 +295,17 @@ void CardReader::printListing(SdFile parent, const char * const prepend/*=nullpt
288
295
289
296
// Get a new directory object using the full path
290
297
// and dive recursively into it.
291
- SdFile child;
292
- if (!child.open (&parent, dosFilename, O_READ))
298
+ SdFile child; // child.close() in destructor
299
+ if (child.open (&parent, dosFilename, O_READ))
300
+ printListing (child, path);
301
+ else {
293
302
SERIAL_ECHO_MSG (STR_SD_CANT_OPEN_SUBDIR, dosFilename);
294
-
295
- printListing (child, path);
296
- // close() is done automatically by destructor of SdFile
303
+ return ;
304
+ }
297
305
}
298
306
else if (is_dir_or_gcode (p)) {
299
- createFilename (filename, p);
300
307
if (prepend) SERIAL_ECHO (prepend);
301
- SERIAL_ECHO (filename);
308
+ SERIAL_ECHO (createFilename ( filename, p) );
302
309
SERIAL_CHAR (' ' );
303
310
SERIAL_ECHOLN (p.fileSize );
304
311
}
@@ -342,7 +349,7 @@ void CardReader::ls() {
342
349
// Go to the next segment
343
350
while (path[++i]) { }
344
351
345
- // SERIAL_ECHOPGM ("Looking for segment: "); SERIAL_ECHOLN( segment);
352
+ // SERIAL_ECHOLNPAIR ("Looking for segment: ", segment);
346
353
347
354
// Find the item, setting the long filename
348
355
diveDir.rewind ();
@@ -720,14 +727,14 @@ void CardReader::removeFile(const char * const name) {
720
727
721
728
// abortFilePrintNow();
722
729
723
- SdFile *curDir ;
724
- const char * const fname = diveToFile (false , curDir , name);
730
+ SdFile *itsDirPtr ;
731
+ const char * const fname = diveToFile (false , itsDirPtr , name);
725
732
if (!fname) return ;
726
733
727
734
#if ENABLED(SDCARD_READONLY)
728
735
SERIAL_ECHOLNPAIR (" Deletion failed (read-only), File: " , fname, " ." );
729
736
#else
730
- if (file.remove (curDir , fname)) {
737
+ if (file.remove (itsDirPtr , fname)) {
731
738
SERIAL_ECHOLNPAIR (" File deleted:" , fname);
732
739
sdpos = 0 ;
733
740
TERN_ (SDCARD_SORT_ALPHA, presort ());
@@ -870,98 +877,101 @@ uint16_t CardReader::countFilesInWorkDir() {
870
877
* - If update_cwd was 'true' the workDir now points to the file's directory.
871
878
*
872
879
* Returns a pointer to the last segment (filename) of the given DOS 8.3 path.
880
+ * On exit, inDirPtr contains an SdFile reference to the file's directory.
873
881
*
874
882
* A nullptr result indicates an unrecoverable error.
883
+ *
884
+ * NOTE: End the path with a slash to dive to a folder. In this case the
885
+ * returned filename will be blank (points to the end of the path).
875
886
*/
876
- const char * CardReader::diveToFile (const bool update_cwd, SdFile* &diveDir , const char * const path, const bool echo/* =false*/ ) {
887
+ const char * CardReader::diveToFile (const bool update_cwd, SdFile* &inDirPtr , const char * const path, const bool echo/* =false*/ ) {
877
888
DEBUG_SECTION (est, " diveToFile" , true );
878
889
879
890
// Track both parent and subfolder
880
891
static SdFile newDir1, newDir2;
881
- SdFile *sub = &newDir1, *startDir ;
892
+ SdFile *sub = &newDir1, *startDirPtr ;
882
893
883
894
// Parsing the path string
884
- const char *item_name_adr = path;
895
+ const char *atom_ptr = path;
885
896
886
897
DEBUG_ECHOLNPAIR (" path = '" , path, " '" );
887
898
888
899
if (path[0 ] == ' /' ) { // Starting at the root directory?
889
- diveDir = &root;
890
- item_name_adr ++;
891
- DEBUG_ECHOLNPAIR (" CWD to root: " , hex_address ((void *)diveDir ));
900
+ inDirPtr = &root;
901
+ atom_ptr ++;
902
+ DEBUG_ECHOLNPAIR (" CWD to root: " , hex_address ((void *)inDirPtr ));
892
903
if (update_cwd) workDirDepth = 0 ; // The cwd can be updated for the benefit of sub-programs
893
904
}
894
905
else
895
- diveDir = &workDir; // Dive from workDir (as set by the UI)
906
+ inDirPtr = &workDir; // Dive from workDir (as set by the UI)
896
907
897
- startDir = diveDir ;
908
+ startDirPtr = inDirPtr ;
898
909
899
- DEBUG_ECHOLNPAIR (" startDir = " , hex_address ((void *)startDir ));
910
+ DEBUG_ECHOLNPAIR (" startDirPtr = " , hex_address ((void *)startDirPtr ));
900
911
901
- while (item_name_adr ) {
912
+ while (atom_ptr ) {
902
913
// Find next subdirectory delimiter
903
- char * const name_end = strchr (item_name_adr , ' /' );
914
+ char * const name_end = strchr (atom_ptr , ' /' );
904
915
905
916
// Last atom in the path? Item found.
906
- if (name_end <= item_name_adr ) break ;
917
+ if (name_end <= atom_ptr ) break ;
907
918
908
- // Set subDirName
909
- const uint8_t len = name_end - item_name_adr ;
919
+ // Isolate the next subitem name
920
+ const uint8_t len = name_end - atom_ptr ;
910
921
char dosSubdirname[len + 1 ];
911
- strncpy (dosSubdirname, item_name_adr , len);
922
+ strncpy (dosSubdirname, atom_ptr , len);
912
923
dosSubdirname[len] = 0 ;
913
924
914
925
if (echo) SERIAL_ECHOLN (dosSubdirname);
915
926
916
927
DEBUG_ECHOLNPAIR (" sub = " , hex_address ((void *)sub));
917
928
918
- // Open diveDir (closing first)
929
+ // Open inDirPtr (closing first)
919
930
sub->close ();
920
- if (!sub->open (diveDir , dosSubdirname, O_READ)) {
931
+ if (!sub->open (inDirPtr , dosSubdirname, O_READ)) {
921
932
openFailed (dosSubdirname);
922
- item_name_adr = nullptr ;
933
+ atom_ptr = nullptr ;
923
934
break ;
924
935
}
925
936
926
- // Close diveDir if not at starting-point
927
- if (diveDir != startDir ) {
928
- DEBUG_ECHOLNPAIR (" closing diveDir : " , hex_address ((void *)diveDir ));
929
- diveDir ->close ();
937
+ // Close inDirPtr if not at starting-point
938
+ if (inDirPtr != startDirPtr ) {
939
+ DEBUG_ECHOLNPAIR (" closing inDirPtr : " , hex_address ((void *)inDirPtr ));
940
+ inDirPtr ->close ();
930
941
}
931
942
932
- // diveDir now subDir
933
- diveDir = sub;
934
- DEBUG_ECHOLNPAIR (" diveDir = sub: " , hex_address ((void *)diveDir ));
943
+ // inDirPtr now subDir
944
+ inDirPtr = sub;
945
+ DEBUG_ECHOLNPAIR (" inDirPtr = sub: " , hex_address ((void *)inDirPtr ));
935
946
936
947
// Update workDirParents and workDirDepth
937
948
if (update_cwd) {
938
949
DEBUG_ECHOLNPAIR (" update_cwd" );
939
950
if (workDirDepth < MAX_DIR_DEPTH)
940
- workDirParents[workDirDepth++] = *diveDir ;
951
+ workDirParents[workDirDepth++] = *inDirPtr ;
941
952
}
942
953
943
954
// Point sub at the other scratch object
944
- sub = (diveDir != &newDir1) ? &newDir1 : &newDir2;
955
+ sub = (inDirPtr != &newDir1) ? &newDir1 : &newDir2;
945
956
DEBUG_ECHOLNPAIR (" swapping sub = " , hex_address ((void *)sub));
946
957
947
958
// Next path atom address
948
- item_name_adr = name_end + 1 ;
959
+ atom_ptr = name_end + 1 ;
949
960
}
950
961
951
962
if (update_cwd) {
952
- workDir = *diveDir ;
953
- DEBUG_ECHOLNPAIR (" final workDir = " , hex_address ((void *)diveDir ));
963
+ workDir = *inDirPtr ;
964
+ DEBUG_ECHOLNPAIR (" final workDir = " , hex_address ((void *)inDirPtr ));
954
965
flag.workDirIsRoot = (workDirDepth == 0 );
955
966
TERN_ (SDCARD_SORT_ALPHA, presort ());
956
967
}
957
968
958
- DEBUG_ECHOLNPAIR (" returning string " , item_name_adr ?: " nullptr" );
959
- return item_name_adr ;
969
+ DEBUG_ECHOLNPAIR (" returning string " , atom_ptr ?: " nullptr" );
970
+ return atom_ptr ;
960
971
}
961
972
962
973
void CardReader::cd (const char * relpath) {
963
- SdFile newDir;
964
- SdFile *parent = workDir.isOpen () ? &workDir : &root;
974
+ SdFile newDir, *parent = &getWorkDir ();
965
975
966
976
if (newDir.open (parent, relpath, O_READ)) {
967
977
workDir = newDir;
0 commit comments