From 4eaa2001137be1944e57ac265756da828daadc12 Mon Sep 17 00:00:00 2001 From: RFBomb Date: Sun, 1 Nov 2020 00:35:40 -0400 Subject: [PATCH 1/7] Expanded Long_FileName Support Updated files for expanded Long_FileName support - /src/gcode/sd/M20.cpp - Added L and S arguments. - Added ability to specify preference if no L / S argument specified. - /src/gcode/sd/M33.cpp - Modified command that requests the feedback to work with the reworked routine. - /Configuration_adv.h - Added two new defines to trigger the defaults for M20 rework - /src/sd/cardreader.h - Changes necessary to work with reworked cardreadper.cpp file - /src/sd/cardreader.cpp - Expanded functionality for Long FileNames - Modified SelectByName routine to be able to return the file if a long name was specified instead of the 8.3 name - Modified Card.LS function to work with new M20 functionality - Modified PrintListing function to work with new M20 Functionality - If requesting long filenames back, this calls the 'printLongPath' function to retrieve said filenames - Modified printLongPath function to be compatible with new PrintListing routine functionality - Modified diveToFile routine to be able to support Long FileNames - This routine is what most others use to pick and choose files on the card for reading and writing. - Adding support in this routine automatically brought the rest up to par. - Routine works with both DOS8.3 names and long names now. #Known Issues: - When uploading a file to SD with octoprint, it was uploaded using the 8.3 format (expected). - Calling M33 to read the long filename of this file resulted in the first file with a long filename to show up instead. For me it was firmware.bin that was being displayed instead of 'PLA_LI~1.GCO' - After inspecting the SD card itself, I don't know if theres a workaround for this yet. - I have put in a string comparison check in order to prevent this issue from occuring though. The workaround will display the 8.3 filename if the first 3 characters of the long filename don't match up with the DOS name. - Writing to the SD card using M28/M29 still requires use of the 8.3 filename. (The rest of the path should work in long form though, as long as the folder path exists. - This is due to how SdBaseFile.cpp is written. - This module is expecting the 8.3 format, and if it isn't give then filename in that format it rejects the operation. - I'm fairly confident it has to do with this command line in the ' ::open( ' routine: if (!make83Name(path, dname, &path)) return false; --- Marlin/Configuration_adv.h | 9 ++ Marlin/src/gcode/sd/M20.cpp | 33 ++++- Marlin/src/gcode/sd/M33.cpp | 2 +- Marlin/src/sd/cardreader.cpp | 225 ++++++++++++++++++++++++++++++----- Marlin/src/sd/cardreader.h | 11 +- 5 files changed, 240 insertions(+), 40 deletions(-) diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index b39e9e1722..eb54053199 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -1256,6 +1256,15 @@ // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT + //M20 Configuration + //#define M20_Reports_Directory_Names // Enable this to report each directory on the SD card in addition to any GCODE files + #if ENABLED(LONG_FILENAME_HOST_SUPPORT) + //LONG_FILENAME_HOST_SUPPORT allows M20 to return LONG or DOS8.3 filenames to the host. Default setting can be setup here. -> If both are disabled, M20 defaults to the DOS names + //If both are enabled, then M20 will report back this format for each item: [DOS8.3 Name] --> [Long_FileName] [Size in bytes] + #define M20_Reports_DOS_FileNames + //#define M20_Reports_LONG_FileNames + #endif + // Enable this option to scroll long filenames in the SD card menu //#define SCROLL_LONG_FILENAMES diff --git a/Marlin/src/gcode/sd/M20.cpp b/Marlin/src/gcode/sd/M20.cpp index 7ac4affdae..fb218fed5f 100644 --- a/Marlin/src/gcode/sd/M20.cpp +++ b/Marlin/src/gcode/sd/M20.cpp @@ -32,9 +32,36 @@ */ void GcodeSuite::M20() { if (card.flag.mounted) { - SERIAL_ECHOLNPGM(STR_BEGIN_FILE_LIST); - card.ls(); - SERIAL_ECHOLNPGM(STR_END_FILE_LIST); + if ( parser.seen('S' ) and parser.seen('L' ) ) { + card.ls(TRUE,TRUE); + + } else if ( parser.seen('S' ) ) { + card.ls(TRUE,FALSE); // Request Short (default DSoc 8,3) filenames if user used 'M20 S' + + } else if ( parser.seen('L' ) ) { + #if ENABLED(LONG_FILENAME_HOST_SUPPORT) + card.ls(FALSE,TRUE); // Request Short (default DSoc 8,3) filenames if user used 'M20 S' + #else + SERIAL_ECHOLNPGM("ERROR: Long_FileName_Host_Support Not Enabled!"); + #endif + + } else { + #if ENABLED(LONG_FILENAME_HOST_SUPPORT) + + #if ( ENABLED(M20_Reports_LONG_FileNames) and ENABLED(M20_Reports_DOS_FileNames) ) + card.ls(TRUE,TRUE); + + #elif ENABLED(M20_Reports_LONG_FileNames) + card.ls(FALSE,TRUE); + + #elif ENABLED(M20_Reports_DOS_FileNames) + card.ls(TRUE,FALSE); + #endif + + #else + card.ls(TRUE,FALSE); + #endif + } } else SERIAL_ECHO_MSG(STR_NO_MEDIA); diff --git a/Marlin/src/gcode/sd/M33.cpp b/Marlin/src/gcode/sd/M33.cpp index b611c8bc08..deb0047ce7 100644 --- a/Marlin/src/gcode/sd/M33.cpp +++ b/Marlin/src/gcode/sd/M33.cpp @@ -41,7 +41,7 @@ */ void GcodeSuite::M33() { - card.printLongPath(parser.string_arg); + card.printLongPath(parser.string_arg, true); } diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index a633440ff6..5dae729097 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -57,6 +57,8 @@ #include "../core/debug_out.h" #include "../libs/hex_print.h" +#include //Required for strcasecmp command to compile without warnings in VS_Code + // public: card_flags_t CardReader::flag; @@ -154,6 +156,7 @@ CardReader::CardReader() { // // Get a DOS 8.3 filename in its useful form +// Requires a file specified // char *createFilename(char * const buffer, const dir_t &p) { char *pos = buffer; @@ -222,20 +225,113 @@ void CardReader::selectByIndex(SdFile dir, const uint8_t index) { // // Get file/folder info for an item by name // -void CardReader::selectByName(SdFile dir, const char * const match) { +void CardReader::selectByName(SdFile dir, const char * const match, boolean debug/*=false*/) { dir_t p; for (uint8_t cnt = 0; dir.readDir(&p, longFilename) > 0; cnt++) { if (is_dir_or_gcode(p)) { createFilename(filename, p); - if (strcasecmp(match, filename) == 0) return; + #if ENABLED(LONG_FILENAME_HOST_SUPPORT) + // Check for match using Long_File_Name or short filename + if ( (strcasecmp(match, longFilename) == 0) or (strcasecmp(match, filename) == 0) ) { + #if ENABLED(DEBUG_CARDREADER) + //debug = true; + if (debug) { + DEBUG_ECHOLN(" "); + DEBUG_ECHO(" DEBUG -SelectByName- LONG FileName: "); + DEBUG_ECHO(longFilename); + DEBUG_ECHO("-- Created FileName: "); + DEBUG_ECHO(filename); + DEBUG_ECHO(" -- Search Term: "); + DEBUG_ECHO(match); + DEBUG_ECHOLN(" -- Match Success: TRUE"); + } + #endif + + //This is a workaround if the filename IS the actual longfilename. This avoids reporting incorrect filenames such as "CURVE_~1.GCO" turning into "firmware.bin" + if ( ! (strncasecmp(filename, longFilename,3) == 0) ) { + #if ENABLED(DEBUG_CARDREADER) + //debug = true; + if ( debug) DEBUG_ECHOLNPAIR("DEBUG: MisMatch Found! Returning LongFileName as FileName"); + if ( debug) DEBUG_ECHOLNPAIR("DEBUG: filename = ", filename); + if ( debug) DEBUG_ECHOLNPAIR("DEBUG: longFilename = ", longFilename); + #endif + strcpy(longFilename, filename); + } + return; + + } else { + //Match Not Found -> Wipe out the filenames to avoid returning a path to a different file + //if ( debug) DEBUG_ECHOLN("FALSE"); + strcpy(filename, ""); + strcpy(longFilename, ""); + } + #else + if (strcasecmp(match, filename) == 0) { + if ( debug) DEBUG_ECHOLN(" DEBUG SelectByName - MatchFound"); + return; + } else { + if ( debug) DEBUG_ECHOLN("FALSE"); + } + #endif } } } +#if ENABLED(M20_Reports_Directory_Names) + // + // Recursive method to list all directories within a folder + // + void CardReader::printDirListing(SdFile parent, boolean ReturnDOSFileNames, boolean ReturnLongFileNames, const char * const prepend/*=nullptr*/) { + dir_t p; + while (parent.readDir(&p, longFilename) > 0) { + if (DIR_IS_SUBDIR(&p)) { + + // Get the short name for the item, which we know is a folder + char dosFilename[FILENAME_LENGTH]; + createFilename(dosFilename, p); + + // Allocate enough stack space to do the work ( full path to a folder, trailing slash, and nul ) + const bool prepend_is_empty = (!prepend || prepend[0] == '\0'); + const int lenPrePend = (prepend_is_empty ? 1 : strlen(prepend)) ; + const int len = lenPrePend + strlen(dosFilename) + 1 + 1; + char path[len]; + + // Append the FOLDERNAME12/ to the passed string. + // It contains the full path to the "parent" argument. + // We now have the full path to the item in this folder. + strcpy(path, prepend_is_empty ? "/" : prepend); // root slash if prepend is empty + strcat(path, dosFilename); // FILENAME_LENGTH characters maximum + strcat(path, "/"); // 1 character + + #if DISABLED(LONG_FILENAME_HOST_SUPPORT) + SERIAL_ECHOLN( path ); // All this work is already done! + #else + const int plen = lenPrePend + strlen(longFilename) + 2; + // Generate the name of the file path then display + char Fpath[plen]; + strcpy(Fpath, prepend_is_empty ? "/" : prepend); // root slash if prepend is empty + strcat(Fpath, longFilename) ; + strcat(Fpath, "/"); + SERIAL_ECHOLN( Fpath ); // Echo Result + #endif + + // Get a new directory object using the full path + // and dive recursively into it. + SdFile child; + if (!child.open(&parent, dosFilename, O_READ)) { + SERIAL_ECHO_START(); + SERIAL_ECHOLNPAIR(STR_SD_CANT_OPEN_SUBDIR, dosFilename); + } + printDirListing(child, ReturnDOSFileNames, ReturnLongFileNames, path); + } + } + } +#endif + // // Recursive method to list all files within a folder // -void CardReader::printListing(SdFile parent, const char * const prepend/*=nullptr*/) { +void CardReader::printListing(SdFile parent, boolean ReturnDOSFileNames, boolean ReturnLongFileNames, const char * const prepend/*=nullptr*/) { dir_t p; while (parent.readDir(&p, longFilename) > 0) { if (DIR_IS_SUBDIR(&p)) { @@ -265,26 +361,49 @@ void CardReader::printListing(SdFile parent, const char * const prepend/*=nullpt SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR(STR_SD_CANT_OPEN_SUBDIR, dosFilename); } - printListing(child, path); + printListing(child, ReturnDOSFileNames, ReturnLongFileNames, path); // close() is done automatically by destructor of SdFile } else if (is_dir_or_gcode(p)) { - createFilename(filename, p); - if (prepend) SERIAL_ECHO(prepend); - SERIAL_ECHO(filename); - SERIAL_CHAR(' '); - SERIAL_ECHOLN(p.fileSize); - } - } -} + createFilename(filename, p); //Parse the string and retrieve a DOS 8.3 FileName+ -// -// List all files on the SD card -// -void CardReader::ls() { - if (flag.mounted) { - root.rewind(); - printListing(root); + #if ENABLED(LONG_FILENAME_HOST_SUPPORT) + + if (ReturnDOSFileNames) {//Print the DOS FileName & Path + if (prepend) { SERIAL_ECHO(prepend); } + SERIAL_ECHO(filename); + } + + if (ReturnLongFileNames) {// Print the Long FileName + if (ReturnDOSFileNames) SERIAL_ECHO(" --> "); + if (prepend) { + //Allocate memory to concat everything before passing it into the PrintLongPath Routine + const int len = strlen(prepend) + strlen(filename) + 3; + char Fpath[len]; + // Generate the name of the file path then display + strcpy(Fpath, prepend) ; + strcat(Fpath, filename) ; + printLongPath (Fpath, false); + }else { + //File exists on root + const int len = strlen(filename) + 3; + char Fpath[len]; + strcpy(Fpath, "/") ; + strcat(Fpath, filename) ; + printLongPath(Fpath, false) ; + } + } + #else + //If Long_FileName_Host_Support is disabled -> Print the DOS8.3 filenames + if (prepend) { SERIAL_ECHO(prepend); } + SERIAL_ECHO(filename); + #endif + + //Print the FileSize + SERIAL_CHAR(' '); + SERIAL_ECHO( p.fileSize ); + SERIAL_ECHOLN(" bytes"); + } } } @@ -293,7 +412,7 @@ void CardReader::ls() { // // Get a long pretty path based on a DOS 8.3 path // - void CardReader::printLongPath(char * const path) { + void CardReader::printLongPath(char * const path, boolean PrintLineReturn) { int i, pathLen = strlen(path); @@ -344,11 +463,32 @@ void CardReader::ls() { } // while irewind(); selectByName(*diveDir, fname); @@ -651,7 +791,7 @@ void CardReader::removeFile(const char * const name) { //endFilePrint(); SdFile *curDir; - const char * const fname = diveToFile(false, curDir, name); + const char * const fname = diveToFile(false, curDir, name, false); if (!fname) return; #if ENABLED(SDCARD_READONLY) @@ -684,7 +824,7 @@ void CardReader::write_command(char * const buf) { char* end = buf + strlen(buf) - 1; file.writeError = false; - if ((npos = strchr(buf, 'N'))) { + if ((npos = strchr(buf, 'N')) != nullptr) { begin = strchr(npos, ' ') + 1; end = strchr(npos, '*') - 1; } @@ -795,7 +935,7 @@ uint16_t CardReader::countFilesInWorkDir() { * * A nullptr result indicates an unrecoverable error. */ -const char* CardReader::diveToFile(const bool update_cwd, SdFile*& diveDir, const char * const path, const bool echo/*=false*/) { +const char* CardReader::diveToFile(const bool update_cwd, SdFile*& diveDir, const char * const path, const bool NewFile/*=false*/) { // Track both parent and subfolder static SdFile newDir1, newDir2; SdFile *sub = &newDir1, *startDir; @@ -806,12 +946,15 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile*& diveDir, cons DEBUG_ECHOLNPAIR("diveToFile: path = '", path, "'"); if (path[0] == '/') { // Starting at the root directory? + DEBUG_ECHOLN("Starting from ROOT"); + root.rewind(); diveDir = &root; item_name_adr++; DEBUG_ECHOLNPAIR("diveToFile: CWD to root: ", hex_address((void*)diveDir)); if (update_cwd) workDirDepth = 0; // The cwd can be updated for the benefit of sub-programs } else + DEBUG_ECHOLN("Starting from WorkingDirectory"); diveDir = &workDir; // Dive from workDir (as set by the UI) startDir = diveDir; @@ -831,12 +974,16 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile*& diveDir, cons strncpy(dosSubdirname, item_name_adr, len); dosSubdirname[len] = 0; - if (echo) SERIAL_ECHOLN(dosSubdirname); - DEBUG_ECHOLNPAIR("diveToFile: sub = ", hex_address((void*)sub)); // Open diveDir (closing first) sub->close(); + #if ENABLED(LONG_FILENAME_HOST_SUPPORT) + // Select the folder by name and ensure the DOS8.3 name is used + DEBUG_ECHOLNPAIR("Search for folder: ", dosSubdirname); + selectByName(*diveDir,dosSubdirname, false) ; + if (strlen(filename) > 0 ) strcpy(dosSubdirname,filename); + #endif if (!sub->open(diveDir, dosSubdirname, O_READ)) { openFailed(dosSubdirname); item_name_adr = nullptr; @@ -866,7 +1013,7 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile*& diveDir, cons // Next path atom address item_name_adr = name_end + 1; - } + } // end while loop if (update_cwd) { workDir = *diveDir; @@ -875,7 +1022,23 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile*& diveDir, cons TERN_(SDCARD_SORT_ALPHA, presort()); } - return item_name_adr; + #if ENABLED(LONG_FILENAME_HOST_SUPPORT) + // Select the file by name and ensure the DOS8.3 name is returned + if (NewFile) { + return item_name_adr; // Expecting the start location of a new file. Nothing else to do here. + }else { + // Expecting a file that already exists - Search and select + diveDir->rewind(); + DEBUG_ECHOLNPAIR("Search for file: ", item_name_adr); + selectByName(*diveDir, item_name_adr, false) ; + DEBUG_ECHOLNPAIR("diveToFile: Return String = ", filename); + return filename; + } + #else + DEBUG_ECHOLNPAIR("diveToFile: Return String = ", item_name_adr); + return item_name_adr; + #endif + } void CardReader::cd(const char * relpath) { diff --git a/Marlin/src/sd/cardreader.h b/Marlin/src/sd/cardreader.h index 33645b6531..6a95db298f 100644 --- a/Marlin/src/sd/cardreader.h +++ b/Marlin/src/sd/cardreader.h @@ -81,7 +81,7 @@ public: static void mount(); static void release(); static inline bool isMounted() { return flag.mounted; } - static void ls(); + static void ls(boolean ReturnDOSFileNames,boolean ReturnLongFileNames); // Handle media insert/remove static void manage_media(); @@ -104,7 +104,7 @@ public: static inline char* longest_filename() { return longFilename[0] ? longFilename : filename; } #if ENABLED(LONG_FILENAME_HOST_SUPPORT) - static void printLongPath(char * const path); // Used by M33 + static void printLongPath(char * const path, boolean PrintLineReturn); // Used by M33 #endif // Working Directory for SD card menu @@ -135,7 +135,7 @@ public: static inline uint8_t percentDone() { return (isFileOpen() && filesize) ? sdpos / ((filesize + 99) / 100) : 0; } // Helper for open and remove - static const char* diveToFile(const bool update_cwd, SdFile*& curDir, const char * const path, const bool echo=false); + static const char* diveToFile(const bool update_cwd, SdFile*& curDir, const char * const path, const bool NewFile=false); #if ENABLED(SDCARD_SORT_ALPHA) static void presort(); @@ -273,8 +273,9 @@ private: static bool is_dir_or_gcode(const dir_t &p); static int countItems(SdFile dir); static void selectByIndex(SdFile dir, const uint8_t index); - static void selectByName(SdFile dir, const char * const match); - static void printListing(SdFile parent, const char * const prepend=nullptr); + static void selectByName(SdFile dir, const char * const match, boolean debug=false); + static void printListing(SdFile parent, boolean ReturnDOSFileNames, boolean ReturnLongFileNames, const char * const prepend=nullptr); + static void printDirListing(SdFile parent, boolean ReturnDOSFileNames, boolean ReturnLongFileNames, const char * const prepend=nullptr); #if ENABLED(SDCARD_SORT_ALPHA) static void flush_presort(); From a8228bde5dafa6fc57e24a7c3106599e0a16df38 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 1 Nov 2020 01:57:21 -0500 Subject: [PATCH 2/7] Pretty up, modernize, etc. --- Marlin/Configuration_adv.h | 14 +-- Marlin/src/gcode/sd/M20.cpp | 36 ++----- Marlin/src/sd/cardreader.cpp | 179 ++++++++++++++++++----------------- Marlin/src/sd/cardreader.h | 13 +-- 4 files changed, 113 insertions(+), 129 deletions(-) diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index eb54053199..b1659407f8 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -1256,15 +1256,15 @@ // This allows hosts to request long names for files and folders with M33 //#define LONG_FILENAME_HOST_SUPPORT - //M20 Configuration - //#define M20_Reports_Directory_Names // Enable this to report each directory on the SD card in addition to any GCODE files + // Default M20 File Listing behavior #if ENABLED(LONG_FILENAME_HOST_SUPPORT) - //LONG_FILENAME_HOST_SUPPORT allows M20 to return LONG or DOS8.3 filenames to the host. Default setting can be setup here. -> If both are disabled, M20 defaults to the DOS names - //If both are enabled, then M20 will report back this format for each item: [DOS8.3 Name] --> [Long_FileName] [Size in bytes] - #define M20_Reports_DOS_FileNames - //#define M20_Reports_LONG_FileNames + #define M20_REPORT_DOS_FILENAMES // Include DOS 8.3 filenames in listings by default + //#define M20_REPORT_LONG_FILENAMES // Include long filenames in listings by default #endif - + + // List folders ahead of the .gcode file listing + //#define M20_REPORT_DIRECTORY_NAMES + // Enable this option to scroll long filenames in the SD card menu //#define SCROLL_LONG_FILENAMES diff --git a/Marlin/src/gcode/sd/M20.cpp b/Marlin/src/gcode/sd/M20.cpp index fb218fed5f..4d166aef7a 100644 --- a/Marlin/src/gcode/sd/M20.cpp +++ b/Marlin/src/gcode/sd/M20.cpp @@ -32,36 +32,12 @@ */ void GcodeSuite::M20() { if (card.flag.mounted) { - if ( parser.seen('S' ) and parser.seen('L' ) ) { - card.ls(TRUE,TRUE); - - } else if ( parser.seen('S' ) ) { - card.ls(TRUE,FALSE); // Request Short (default DSoc 8,3) filenames if user used 'M20 S' - - } else if ( parser.seen('L' ) ) { - #if ENABLED(LONG_FILENAME_HOST_SUPPORT) - card.ls(FALSE,TRUE); // Request Short (default DSoc 8,3) filenames if user used 'M20 S' - #else - SERIAL_ECHOLNPGM("ERROR: Long_FileName_Host_Support Not Enabled!"); - #endif - - } else { - #if ENABLED(LONG_FILENAME_HOST_SUPPORT) - - #if ( ENABLED(M20_Reports_LONG_FileNames) and ENABLED(M20_Reports_DOS_FileNames) ) - card.ls(TRUE,TRUE); - - #elif ENABLED(M20_Reports_LONG_FileNames) - card.ls(FALSE,TRUE); - - #elif ENABLED(M20_Reports_DOS_FileNames) - card.ls(TRUE,FALSE); - #endif - - #else - card.ls(TRUE,FALSE); - #endif - } + card.ls( + parser.boolval('S', TERN1(M20_REPORT_LONG_FILENAMES)), + parser.boolval('L', ENABLED(M20_REPORT_DOS_FILENAMES)) + ); + if (DISABLED(LONG_FILENAME_HOST_SUPPORT) && parser.boolval('L')) + SERIAL_ECHOLNPGM("ERROR: LONG_FILENAME_HOST_SUPPORT Not Enabled!"); } else SERIAL_ECHO_MSG(STR_NO_MEDIA); diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index 5dae729097..bd78490f8e 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -57,7 +57,7 @@ #include "../core/debug_out.h" #include "../libs/hex_print.h" -#include //Required for strcasecmp command to compile without warnings in VS_Code +#include // Suppress VSCode warnings about 'strcasecmp' // public: @@ -175,7 +175,7 @@ char *createFilename(char * const buffer, const dir_t &p) { bool CardReader::is_dir_or_gcode(const dir_t &p) { //uint8_t pn0 = p.name[0]; - if ( (p.attributes & DIR_ATT_HIDDEN) // Hidden by attribute + if ((p.attributes & DIR_ATT_HIDDEN) // Hidden by attribute // When readDir() > 0 these must be false: //|| pn0 == DIR_NAME_FREE || pn0 == DIR_NAME_DELETED // Clear or Deleted entry //|| pn0 == '.' || longFilename[0] == '.' // Hidden file @@ -225,63 +225,63 @@ void CardReader::selectByIndex(SdFile dir, const uint8_t index) { // // Get file/folder info for an item by name // -void CardReader::selectByName(SdFile dir, const char * const match, boolean debug/*=false*/) { +void CardReader::selectByName(SdFile dir, const char * const match, const bool debug/*=false*/) { dir_t p; for (uint8_t cnt = 0; dir.readDir(&p, longFilename) > 0; cnt++) { if (is_dir_or_gcode(p)) { createFilename(filename, p); #if ENABLED(LONG_FILENAME_HOST_SUPPORT) // Check for match using Long_File_Name or short filename - if ( (strcasecmp(match, longFilename) == 0) or (strcasecmp(match, filename) == 0) ) { + if (strcasecmp(match, longFilename) == 0 || strcasecmp(match, filename) == 0) { #if ENABLED(DEBUG_CARDREADER) //debug = true; if (debug) { - DEBUG_ECHOLN(" "); - DEBUG_ECHO(" DEBUG -SelectByName- LONG FileName: "); + DEBUG_ECHOLNPGM(" "); + DEBUG_ECHOPGM(" DEBUG -SelectByName- LONG FileName: "); DEBUG_ECHO(longFilename); - DEBUG_ECHO("-- Created FileName: "); + DEBUG_ECHOPGM("-- Created FileName: "); DEBUG_ECHO(filename); - DEBUG_ECHO(" -- Search Term: "); + DEBUG_ECHOPGM(" -- Search Term: "); DEBUG_ECHO(match); - DEBUG_ECHOLN(" -- Match Success: TRUE"); + DEBUG_ECHOLNPGM(" -- Match Success: TRUE"); } #endif //This is a workaround if the filename IS the actual longfilename. This avoids reporting incorrect filenames such as "CURVE_~1.GCO" turning into "firmware.bin" - if ( ! (strncasecmp(filename, longFilename,3) == 0) ) { + if (strncasecmp(filename, longFilename, 3) != 0) { #if ENABLED(DEBUG_CARDREADER) //debug = true; - if ( debug) DEBUG_ECHOLNPAIR("DEBUG: MisMatch Found! Returning LongFileName as FileName"); - if ( debug) DEBUG_ECHOLNPAIR("DEBUG: filename = ", filename); - if ( debug) DEBUG_ECHOLNPAIR("DEBUG: longFilename = ", longFilename); + if (debug) DEBUG_ECHOLNPAIR("DEBUG: MisMatch Found! Returning LongFileName as FileName"); + if (debug) DEBUG_ECHOLNPAIR("DEBUG: filename = ", filename); + if (debug) DEBUG_ECHOLNPAIR("DEBUG: longFilename = ", longFilename); #endif strcpy(longFilename, filename); } - return; - - } else { - //Match Not Found -> Wipe out the filenames to avoid returning a path to a different file - //if ( debug) DEBUG_ECHOLN("FALSE"); + return; + } + else { + // Match Not Found -> Wipe out the filenames to avoid returning a path to a different file + //if (debug) DEBUG_ECHOLN("FALSE"); strcpy(filename, ""); strcpy(longFilename, ""); } #else if (strcasecmp(match, filename) == 0) { - if ( debug) DEBUG_ECHOLN(" DEBUG SelectByName - MatchFound"); + if (debug) DEBUG_ECHOLN(" DEBUG SelectByName - MatchFound"); return; - } else { - if ( debug) DEBUG_ECHOLN("FALSE"); } + else if (debug) + DEBUG_ECHOLN("FALSE"); #endif } } } -#if ENABLED(M20_Reports_Directory_Names) +#if ENABLED(M20_REPORT_DIRECTORY_NAMES) // // Recursive method to list all directories within a folder // - void CardReader::printDirListing(SdFile parent, boolean ReturnDOSFileNames, boolean ReturnLongFileNames, const char * const prepend/*=nullptr*/) { + void CardReader::printDirListing(SdFile parent, const bool print_dos_names, const bool print_long_names, const char * const prepend/*=nullptr*/) { dir_t p; while (parent.readDir(&p, longFilename) > 0) { if (DIR_IS_SUBDIR(&p)) { @@ -292,8 +292,8 @@ void CardReader::selectByName(SdFile dir, const char * const match, boolean debu // Allocate enough stack space to do the work ( full path to a folder, trailing slash, and nul ) const bool prepend_is_empty = (!prepend || prepend[0] == '\0'); - const int lenPrePend = (prepend_is_empty ? 1 : strlen(prepend)) ; - const int len = lenPrePend + strlen(dosFilename) + 1 + 1; + const size_t lenPrePend = prepend_is_empty ? 1 : strlen(prepend), + len = lenPrePend + strlen(dosFilename) + 1 + 1; char path[len]; // Append the FOLDERNAME12/ to the passed string. @@ -304,15 +304,15 @@ void CardReader::selectByName(SdFile dir, const char * const match, boolean debu strcat(path, "/"); // 1 character #if DISABLED(LONG_FILENAME_HOST_SUPPORT) - SERIAL_ECHOLN( path ); // All this work is already done! + SERIAL_ECHOLN(path); // All this work is already done! #else - const int plen = lenPrePend + strlen(longFilename) + 2; + const size_t plen = lenPrePend + strlen(longFilename) + 2; // Generate the name of the file path then display char Fpath[plen]; - strcpy(Fpath, prepend_is_empty ? "/" : prepend); // root slash if prepend is empty - strcat(Fpath, longFilename) ; + strcpy(Fpath, prepend_is_empty ? "/" : prepend); // root slash if prepend is empty + strcat(Fpath, longFilename); strcat(Fpath, "/"); - SERIAL_ECHOLN( Fpath ); // Echo Result + SERIAL_ECHOLN(Fpath); // Echo Result #endif // Get a new directory object using the full path @@ -322,7 +322,7 @@ void CardReader::selectByName(SdFile dir, const char * const match, boolean debu SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR(STR_SD_CANT_OPEN_SUBDIR, dosFilename); } - printDirListing(child, ReturnDOSFileNames, ReturnLongFileNames, path); + printDirListing(child, print_dos_names, print_long_names, path); } } } @@ -331,7 +331,7 @@ void CardReader::selectByName(SdFile dir, const char * const match, boolean debu // // Recursive method to list all files within a folder // -void CardReader::printListing(SdFile parent, boolean ReturnDOSFileNames, boolean ReturnLongFileNames, const char * const prepend/*=nullptr*/) { +void CardReader::printListing(SdFile parent, const bool print_dos_names, const bool print_long_names, const char * const prepend/*=nullptr*/) { dir_t p; while (parent.readDir(&p, longFilename) > 0) { if (DIR_IS_SUBDIR(&p)) { @@ -342,7 +342,7 @@ void CardReader::printListing(SdFile parent, boolean ReturnDOSFileNames, boolean // Allocate enough stack space for the full path to a folder, trailing slash, and nul const bool prepend_is_empty = (!prepend || prepend[0] == '\0'); - const int len = (prepend_is_empty ? 1 : strlen(prepend)) + strlen(dosFilename) + 1 + 1; + const size_t len = (prepend_is_empty ? 1 : strlen(prepend)) + strlen(dosFilename) + 1 + 1; char path[len]; // Append the FOLDERNAME12/ to the passed string. @@ -361,48 +361,48 @@ void CardReader::printListing(SdFile parent, boolean ReturnDOSFileNames, boolean SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR(STR_SD_CANT_OPEN_SUBDIR, dosFilename); } - printListing(child, ReturnDOSFileNames, ReturnLongFileNames, path); + printListing(child, print_dos_names, print_long_names, path); // close() is done automatically by destructor of SdFile } else if (is_dir_or_gcode(p)) { - createFilename(filename, p); //Parse the string and retrieve a DOS 8.3 FileName+ + createFilename(filename, p); // Parse the string and retrieve a DOS 8.3 FileName+ #if ENABLED(LONG_FILENAME_HOST_SUPPORT) - if (ReturnDOSFileNames) {//Print the DOS FileName & Path - if (prepend) { SERIAL_ECHO(prepend); } + if (print_dos_names) { // Print the path element and DOS 8.3 filename + if (prepend) SERIAL_ECHO(prepend); SERIAL_ECHO(filename); } - if (ReturnLongFileNames) {// Print the Long FileName - if (ReturnDOSFileNames) SERIAL_ECHO(" --> "); + if (print_long_names) { // Print the Long FileName + if (print_dos_names) SERIAL_ECHOPGM(" --> "); if (prepend) { - //Allocate memory to concat everything before passing it into the PrintLongPath Routine - const int len = strlen(prepend) + strlen(filename) + 3; - char Fpath[len]; + // Allocate stack to join strings before passing to printLongPath + const size_t plen = strlen(prepend), + len = plen + strlen(filename) + 1; // Generate the name of the file path then display - strcpy(Fpath, prepend) ; - strcat(Fpath, filename) ; - printLongPath (Fpath, false); - }else { - //File exists on root - const int len = strlen(filename) + 3; char Fpath[len]; - strcpy(Fpath, "/") ; - strcat(Fpath, filename) ; - printLongPath(Fpath, false) ; + strcpy(Fpath, prepend); + strcpy(&Fpath[plen], filename); + printLongPath(Fpath); + } + else { + // File is in the root directory + const int len = 1 + strlen(filename) + 1; // slash, filename, terninating nul + char Fpath[len]; + Fpath[0] = '/'; + strcpy(&Fpath[1], filename); + printLongPath(Fpath); } } #else - //If Long_FileName_Host_Support is disabled -> Print the DOS8.3 filenames - if (prepend) { SERIAL_ECHO(prepend); } - SERIAL_ECHO(filename); + // If Long_FileName_Host_Support is disabled -> Print the DOS8.3 filenames + if (prepend) SERIAL_ECHO(prepend); + SERIAL_ECHO(filename); #endif - //Print the FileSize - SERIAL_CHAR(' '); - SERIAL_ECHO( p.fileSize ); - SERIAL_ECHOLN(" bytes"); + // Print the FileSize + SERIAL_ECHOLNPAIR(" ", p.fileSize, " bytes"); } } } @@ -412,7 +412,7 @@ void CardReader::printListing(SdFile parent, boolean ReturnDOSFileNames, boolean // // Get a long pretty path based on a DOS 8.3 path // - void CardReader::printLongPath(char * const path, boolean PrintLineReturn) { + void CardReader::printLongPath(char * const path, const bool print_eol/*=false*/) { int i, pathLen = strlen(path); @@ -447,7 +447,7 @@ void CardReader::printListing(SdFile parent, boolean ReturnDOSFileNames, boolean // If the filename was printed then that's it if (!flag.filenameIsDir) break; - // SERIAL_ECHOPGM("Opening dir: "); SERIAL_ECHOLN(segment); + //SERIAL_ECHOPGM("Opening dir: "); SERIAL_ECHOLN(segment); // Open the sub-item as the new dive parent SdFile dir; @@ -463,31 +463,39 @@ void CardReader::printListing(SdFile parent, boolean ReturnDOSFileNames, boolean } // while irewind(); selectByName(*diveDir, fname); @@ -791,7 +799,7 @@ void CardReader::removeFile(const char * const name) { //endFilePrint(); SdFile *curDir; - const char * const fname = diveToFile(false, curDir, name, false); + const char * const fname = diveToFile(false, curDir, name); if (!fname) return; #if ENABLED(SDCARD_READONLY) @@ -935,7 +943,7 @@ uint16_t CardReader::countFilesInWorkDir() { * * A nullptr result indicates an unrecoverable error. */ -const char* CardReader::diveToFile(const bool update_cwd, SdFile*& diveDir, const char * const path, const bool NewFile/*=false*/) { +const char* CardReader::diveToFile(const bool update_cwd, SdFile*& diveDir, const char * const path, const bool is_new_file/*=false*/) { // Track both parent and subfolder static SdFile newDir1, newDir2; SdFile *sub = &newDir1, *startDir; @@ -947,8 +955,8 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile*& diveDir, cons if (path[0] == '/') { // Starting at the root directory? DEBUG_ECHOLN("Starting from ROOT"); - root.rewind(); diveDir = &root; + diveDir->rewind(); // Redundant rewind, but no harm item_name_adr++; DEBUG_ECHOLNPAIR("diveToFile: CWD to root: ", hex_address((void*)diveDir)); if (update_cwd) workDirDepth = 0; // The cwd can be updated for the benefit of sub-programs @@ -976,14 +984,17 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile*& diveDir, cons DEBUG_ECHOLNPAIR("diveToFile: sub = ", hex_address((void*)sub)); - // Open diveDir (closing first) + // Close before dive or select sub->close(); + #if ENABLED(LONG_FILENAME_HOST_SUPPORT) // Select the folder by name and ensure the DOS8.3 name is used DEBUG_ECHOLNPAIR("Search for folder: ", dosSubdirname); - selectByName(*diveDir,dosSubdirname, false) ; - if (strlen(filename) > 0 ) strcpy(dosSubdirname,filename); + selectByName(*diveDir, dosSubdirname); + if (filename[0]) strcpy(dosSubdirname, filename); #endif + + // Open diveDir (closing first, above) if (!sub->open(diveDir, dosSubdirname, O_READ)) { openFailed(dosSubdirname); item_name_adr = nullptr; @@ -1022,23 +1033,19 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile*& diveDir, cons TERN_(SDCARD_SORT_ALPHA, presort()); } - #if ENABLED(LONG_FILENAME_HOST_SUPPORT) - // Select the file by name and ensure the DOS8.3 name is returned - if (NewFile) { - return item_name_adr; // Expecting the start location of a new file. Nothing else to do here. - }else { + #if ENABLED(LONG_FILENAME_HOST_SUPPORT) + if (!is_new_file) { // Expecting a file that already exists - Search and select diveDir->rewind(); DEBUG_ECHOLNPAIR("Search for file: ", item_name_adr); - selectByName(*diveDir, item_name_adr, false) ; + selectByName(*diveDir, item_name_adr); DEBUG_ECHOLNPAIR("diveToFile: Return String = ", filename); return filename; } - #else - DEBUG_ECHOLNPAIR("diveToFile: Return String = ", item_name_adr); - return item_name_adr; #endif + DEBUG_ECHOLNPAIR("diveToFile: Return String = ", item_name_adr); + return item_name_adr; } void CardReader::cd(const char * relpath) { diff --git a/Marlin/src/sd/cardreader.h b/Marlin/src/sd/cardreader.h index 6a95db298f..6e057aa543 100644 --- a/Marlin/src/sd/cardreader.h +++ b/Marlin/src/sd/cardreader.h @@ -81,7 +81,7 @@ public: static void mount(); static void release(); static inline bool isMounted() { return flag.mounted; } - static void ls(boolean ReturnDOSFileNames,boolean ReturnLongFileNames); + static void ls(const bool print_dos_names, const bool print_long_names); // Handle media insert/remove static void manage_media(); @@ -103,8 +103,9 @@ public: static void removeFile(const char * const name); static inline char* longest_filename() { return longFilename[0] ? longFilename : filename; } + #if ENABLED(LONG_FILENAME_HOST_SUPPORT) - static void printLongPath(char * const path, boolean PrintLineReturn); // Used by M33 + static void printLongPath(char * const path, const bool print_eol=false); // Used by M33 #endif // Working Directory for SD card menu @@ -135,7 +136,7 @@ public: static inline uint8_t percentDone() { return (isFileOpen() && filesize) ? sdpos / ((filesize + 99) / 100) : 0; } // Helper for open and remove - static const char* diveToFile(const bool update_cwd, SdFile*& curDir, const char * const path, const bool NewFile=false); + static const char* diveToFile(const bool update_cwd, SdFile*& curDir, const char * const path, const bool is_new_file=false); #if ENABLED(SDCARD_SORT_ALPHA) static void presort(); @@ -273,9 +274,9 @@ private: static bool is_dir_or_gcode(const dir_t &p); static int countItems(SdFile dir); static void selectByIndex(SdFile dir, const uint8_t index); - static void selectByName(SdFile dir, const char * const match, boolean debug=false); - static void printListing(SdFile parent, boolean ReturnDOSFileNames, boolean ReturnLongFileNames, const char * const prepend=nullptr); - static void printDirListing(SdFile parent, boolean ReturnDOSFileNames, boolean ReturnLongFileNames, const char * const prepend=nullptr); + static void selectByName(SdFile dir, const char * const match, const bool debug=false); + static void printListing(SdFile parent, const bool print_dos_names, const bool print_long_names, const char * const prepend=nullptr); + static void printDirListing(SdFile parent, const bool print_dos_names, const bool print_long_names, const char * const prepend=nullptr); #if ENABLED(SDCARD_SORT_ALPHA) static void flush_presort(); From d7b0a8892b57fe2dca71fb85a6ca4d10f22810f4 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 1 Nov 2020 01:59:19 -0500 Subject: [PATCH 3/7] Reverse reversal --- Marlin/src/gcode/sd/M20.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/src/gcode/sd/M20.cpp b/Marlin/src/gcode/sd/M20.cpp index 4d166aef7a..f4f09b73fe 100644 --- a/Marlin/src/gcode/sd/M20.cpp +++ b/Marlin/src/gcode/sd/M20.cpp @@ -33,8 +33,8 @@ void GcodeSuite::M20() { if (card.flag.mounted) { card.ls( - parser.boolval('S', TERN1(M20_REPORT_LONG_FILENAMES)), - parser.boolval('L', ENABLED(M20_REPORT_DOS_FILENAMES)) + parser.boolval('S', TERN1(M20_REPORT_DOS_FILENAMES)), + parser.boolval('L', ENABLED(M20_REPORT_LONG_FILENAMES)) ); if (DISABLED(LONG_FILENAME_HOST_SUPPORT) && parser.boolval('L')) SERIAL_ECHOLNPGM("ERROR: LONG_FILENAME_HOST_SUPPORT Not Enabled!"); From 50e21a2aa2f342cc6c69dea5c40a8daa13db7ec9 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 1 Nov 2020 01:01:09 -0600 Subject: [PATCH 4/7] Use PGM strings --- Marlin/src/HAL/STM32/eeprom_flash.cpp | 2 +- Marlin/src/sd/cardreader.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Marlin/src/HAL/STM32/eeprom_flash.cpp b/Marlin/src/HAL/STM32/eeprom_flash.cpp index c83376d265..702e42e561 100644 --- a/Marlin/src/HAL/STM32/eeprom_flash.cpp +++ b/Marlin/src/HAL/STM32/eeprom_flash.cpp @@ -113,7 +113,7 @@ bool PersistentStore::access_start() { // This must be the first time since power on that we have accessed the storage, or someone // loaded and called write_data and never called access_finish. // Lets go looking for the slot that holds our configuration. - if (eeprom_data_written) DEBUG_ECHOLN("Dangling EEPROM write_data"); + if (eeprom_data_written) DEBUG_ECHOLNPGM("Dangling EEPROM write_data"); uint32_t address = FLASH_ADDRESS_START; while (address <= FLASH_ADDRESS_END) { uint32_t address_value = (*(__IO uint32_t*)address); diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index bd78490f8e..ca95bd01c3 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -175,7 +175,7 @@ char *createFilename(char * const buffer, const dir_t &p) { bool CardReader::is_dir_or_gcode(const dir_t &p) { //uint8_t pn0 = p.name[0]; - if ((p.attributes & DIR_ATT_HIDDEN) // Hidden by attribute + if ( (p.attributes & DIR_ATT_HIDDEN) // Hidden by attribute // When readDir() > 0 these must be false: //|| pn0 == DIR_NAME_FREE || pn0 == DIR_NAME_DELETED // Clear or Deleted entry //|| pn0 == '.' || longFilename[0] == '.' // Hidden file @@ -261,17 +261,17 @@ void CardReader::selectByName(SdFile dir, const char * const match, const bool d } else { // Match Not Found -> Wipe out the filenames to avoid returning a path to a different file - //if (debug) DEBUG_ECHOLN("FALSE"); + //if (debug) DEBUG_ECHOLNPGM("FALSE"); strcpy(filename, ""); strcpy(longFilename, ""); } #else if (strcasecmp(match, filename) == 0) { - if (debug) DEBUG_ECHOLN(" DEBUG SelectByName - MatchFound"); + if (debug) DEBUG_ECHOLNPGM(" DEBUG SelectByName - MatchFound"); return; } else if (debug) - DEBUG_ECHOLN("FALSE"); + DEBUG_ECHOLNPGM("FALSE"); #endif } } @@ -954,7 +954,7 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile*& diveDir, cons DEBUG_ECHOLNPAIR("diveToFile: path = '", path, "'"); if (path[0] == '/') { // Starting at the root directory? - DEBUG_ECHOLN("Starting from ROOT"); + DEBUG_ECHOLNPGM("Starting from ROOT"); diveDir = &root; diveDir->rewind(); // Redundant rewind, but no harm item_name_adr++; @@ -962,7 +962,7 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile*& diveDir, cons if (update_cwd) workDirDepth = 0; // The cwd can be updated for the benefit of sub-programs } else - DEBUG_ECHOLN("Starting from WorkingDirectory"); + DEBUG_ECHOLNPGM("Starting from WorkingDirectory"); diveDir = &workDir; // Dive from workDir (as set by the UI) startDir = diveDir; From 0fe8b56ede958dfb45b8a182af07d1e1300e0c86 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 1 Nov 2020 01:14:42 -0600 Subject: [PATCH 5/7] More cleanup --- Marlin/src/core/language.h | 2 ++ Marlin/src/sd/cardreader.cpp | 47 +++++++++++++----------------------- 2 files changed, 19 insertions(+), 30 deletions(-) diff --git a/Marlin/src/core/language.h b/Marlin/src/core/language.h index 60d9aa6b72..f021f3dffb 100644 --- a/Marlin/src/core/language.h +++ b/Marlin/src/core/language.h @@ -121,6 +121,8 @@ #define STR_NO_MEDIA "No media" #define STR_BEGIN_FILE_LIST "Begin file list" #define STR_END_FILE_LIST "End file list" +#define STR_BEGIN_DIR_LIST "Begin dir list" +#define STR_END_DIR_LIST "End dir list" #define STR_INVALID_EXTRUDER "Invalid extruder" #define STR_INVALID_E_STEPPER "Invalid E stepper" #define STR_E_STEPPER_NOT_SPECIFIED "E stepper not specified" diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index ca95bd01c3..36877cecf1 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -236,25 +236,23 @@ void CardReader::selectByName(SdFile dir, const char * const match, const bool d #if ENABLED(DEBUG_CARDREADER) //debug = true; if (debug) { - DEBUG_ECHOLNPGM(" "); - DEBUG_ECHOPGM(" DEBUG -SelectByName- LONG FileName: "); - DEBUG_ECHO(longFilename); - DEBUG_ECHOPGM("-- Created FileName: "); - DEBUG_ECHO(filename); - DEBUG_ECHOPGM(" -- Search Term: "); - DEBUG_ECHO(match); - DEBUG_ECHOLNPGM(" -- Match Success: TRUE"); + DEBUG_ECHOLNPAIR("\n" + " DEBUG -SelectByName- LONG FileName: ", longFilename, + "-- Created FileName: ", filename, + " -- Search Term: ", match, + " -- Match Success: TRUE" + ); } #endif - //This is a workaround if the filename IS the actual longfilename. This avoids reporting incorrect filenames such as "CURVE_~1.GCO" turning into "firmware.bin" + // Workaround for a DOS8.3 name identical to long name. if (strncasecmp(filename, longFilename, 3) != 0) { - #if ENABLED(DEBUG_CARDREADER) - //debug = true; - if (debug) DEBUG_ECHOLNPAIR("DEBUG: MisMatch Found! Returning LongFileName as FileName"); - if (debug) DEBUG_ECHOLNPAIR("DEBUG: filename = ", filename); - if (debug) DEBUG_ECHOLNPAIR("DEBUG: longFilename = ", longFilename); - #endif + //debug = true; + if (TERN0(DEBUG_CARDREADER, debug)) { + DEBUG_ECHOLNPAIR("DEBUG: Mismatch! Copying filename to longFilename"); + DEBUG_ECHOLNPAIR("DEBUG: filename = ", filename); + DEBUG_ECHOLNPAIR("DEBUG: longFilename = ", longFilename); + } strcpy(longFilename, filename); } return; @@ -262,8 +260,7 @@ void CardReader::selectByName(SdFile dir, const char * const match, const bool d else { // Match Not Found -> Wipe out the filenames to avoid returning a path to a different file //if (debug) DEBUG_ECHOLNPGM("FALSE"); - strcpy(filename, ""); - strcpy(longFilename, ""); + filename[0] = longFilename[0] = '\0'; } #else if (strcasecmp(match, filename) == 0) { @@ -474,29 +471,19 @@ void CardReader::printListing(SdFile parent, const bool print_dos_names, const b void CardReader::ls(const bool print_dos_names, const bool print_long_names) { if (flag.mounted) { #if ENABLED(M20_REPORT_DIRECTORY_NAMES) - SERIAL_ECHOLNPGM("Begin Directory Listing"); root.rewind(); + SERIAL_ECHOLNPGM(STR_BEGIN_DIR_LIST); card.printDirListing(root, print_dos_names, print_long_names); - SERIAL_ECHOLNPGM("End Directory Listing"); + SERIAL_ECHOLNPGM(STR_END_DIR_LIST); SERIAL_ECHOLNPGM(" "); #endif - SERIAL_ECHOLNPGM(STR_BEGIN_FILE_LIST); root.rewind(); + SERIAL_ECHOLNPGM(STR_BEGIN_FILE_LIST); printListing(root, print_dos_names, print_long_names); SERIAL_ECHOLNPGM(STR_END_FILE_LIST); } } -// -// List all files on the SD card -// -void CardReader::ls() { - if (flag.mounted) { - root.rewind(); - printListing(root); - } -} - // // Echo the DOS 8.3 filename (and long filename, if any) // From a5fb9ef262f690f3f3946b7ce7bab061a57b414b Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 1 Nov 2020 01:22:35 -0600 Subject: [PATCH 6/7] Change M20 short name option --- Marlin/Configuration_adv.h | 2 +- Marlin/src/gcode/sd/M20.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index b1659407f8..0d578749e2 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -1258,7 +1258,7 @@ // Default M20 File Listing behavior #if ENABLED(LONG_FILENAME_HOST_SUPPORT) - #define M20_REPORT_DOS_FILENAMES // Include DOS 8.3 filenames in listings by default + //#define M20_DEFER_DOS_FILENAMES // Hide DOS 8.3 filenames in listings by default //#define M20_REPORT_LONG_FILENAMES // Include long filenames in listings by default #endif diff --git a/Marlin/src/gcode/sd/M20.cpp b/Marlin/src/gcode/sd/M20.cpp index f4f09b73fe..207b541e3e 100644 --- a/Marlin/src/gcode/sd/M20.cpp +++ b/Marlin/src/gcode/sd/M20.cpp @@ -33,7 +33,7 @@ void GcodeSuite::M20() { if (card.flag.mounted) { card.ls( - parser.boolval('S', TERN1(M20_REPORT_DOS_FILENAMES)), + parser.boolval('S', DISABLED(M20_DEFER_DOS_FILENAMES)), parser.boolval('L', ENABLED(M20_REPORT_LONG_FILENAMES)) ); if (DISABLED(LONG_FILENAME_HOST_SUPPORT) && parser.boolval('L')) From 3ddc172f6f693d42113f313588ba5e55b13d189c Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 1 Nov 2020 03:12:06 -0600 Subject: [PATCH 7/7] =?UTF-8?q?Guess=20not=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/sd/cardreader.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index 36877cecf1..44c1a2c387 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -57,8 +57,6 @@ #include "../core/debug_out.h" #include "../libs/hex_print.h" -#include // Suppress VSCode warnings about 'strcasecmp' - // public: card_flags_t CardReader::flag;