1
0
mirror of https://github.com/MarlinFirmware/Marlin.git synced 2024-11-30 07:17:59 +00:00

Enable 'M20 L' with LONG_FILENAME_HOST_SUPPORT (#22271)

This commit is contained in:
Mihai 2021-07-07 07:10:35 +03:00 committed by Scott Lahteine
parent a35c234ce1
commit ee64081696
3 changed files with 70 additions and 35 deletions

View File

@ -33,7 +33,7 @@
void GcodeSuite::M20() { void GcodeSuite::M20() {
if (card.flag.mounted) { if (card.flag.mounted) {
SERIAL_ECHOLNPGM(STR_BEGIN_FILE_LIST); SERIAL_ECHOLNPGM(STR_BEGIN_FILE_LIST);
card.ls(); card.ls(TERN_(LONG_FILENAME_HOST_SUPPORT, parser.boolval('L')));
SERIAL_ECHOLNPGM(STR_END_FILE_LIST); SERIAL_ECHOLNPGM(STR_END_FILE_LIST);
} }
else else

View File

@ -258,54 +258,84 @@ void CardReader::selectByName(SdFile dir, const char * const match) {
} }
} }
// /**
// Recursive method to print all files within a folder in flat * Recursive method to print all files within a folder in flat
// DOS 8.3 format. This style of listing is the most compatible * DOS 8.3 format. This style of listing is the most compatible
// with legacy hosts. * with legacy hosts.
// *
// This method recurses to unlimited depth and lists every * This method recurses to unlimited depth and lists all G-code
// G-code file within the given parent. If the hierarchy is * files within the given parent. If the hierarchy is very deep
// very deep this can blow up the stack, so a 'depth' parameter * this can blow up the stack, so a 'depth' parameter would be a
// (as with printListingJSON) would be a good addition. * good addition.
// */
void CardReader::printListing(SdFile parent, const char * const prepend/*=nullptr*/) { void CardReader::printListing(
SdFile parent
OPTARG(LONG_FILENAME_HOST_SUPPORT, const bool includeLongNames/*=false*/)
, const char * const prepend/*=nullptr*/
OPTARG(LONG_FILENAME_HOST_SUPPORT, const char * const prependLong/*=nullptr*/)
) {
dir_t p; dir_t p;
while (parent.readDir(&p, longFilename) > 0) { while (parent.readDir(&p, longFilename) > 0) {
if (DIR_IS_SUBDIR(&p)) { if (DIR_IS_SUBDIR(&p)) {
// Get the short name for the item, which we know is a folder size_t lenPrepend = prepend ? strlen(prepend) + 1 : 0;
char dosFilename[FILENAME_LENGTH]; // Allocate enough stack space for the full path including / separator
char path[lenPrepend + FILENAME_LENGTH];
if (prepend) {
strcpy(path, prepend);
path[lenPrepend - 1] = '/';
}
char* dosFilename = path + lenPrepend;
createFilename(dosFilename, p); createFilename(dosFilename, p);
// 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;
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
// Serial.print(path);
// Get a new directory object using the full path // Get a new directory object using the full path
// and dive recursively into it. // and dive recursively into it.
SdFile child; // child.close() in destructor SdFile child; // child.close() in destructor
if (child.open(&parent, dosFilename, O_READ)) if (child.open(&parent, dosFilename, O_READ))
printListing(child, path); #if ENABLED(LONG_FILENAME_HOST_SUPPORT)
if (includeLongNames) {
size_t lenPrependLong = prependLong ? strlen(prependLong) + 1 : 0;
// Allocate enough stack space for the full long path including / separator
char pathLong[lenPrependLong + strlen(longFilename) + 1];
if (prependLong) {
strcpy(pathLong, prependLong);
pathLong[lenPrependLong - 1] = '/';
}
strcpy(pathLong + lenPrependLong, longFilename);
printListing(child, true, path, pathLong);
}
else
printListing(child, false, path);
#else
printListing(child, path);
#endif
else { else {
SERIAL_ECHO_MSG(STR_SD_CANT_OPEN_SUBDIR, dosFilename); SERIAL_ECHO_MSG(STR_SD_CANT_OPEN_SUBDIR, dosFilename);
return; return;
} }
} }
else if (is_dir_or_gcode(p)) { else if (is_dir_or_gcode(p)) {
if (prepend) SERIAL_ECHO(prepend); if (prepend) {
SERIAL_ECHO(prepend);
SERIAL_CHAR('/');
}
SERIAL_ECHO(createFilename(filename, p)); SERIAL_ECHO(createFilename(filename, p));
SERIAL_CHAR(' '); SERIAL_CHAR(' ');
SERIAL_ECHOLN(p.fileSize); #if ENABLED(LONG_FILENAME_HOST_SUPPORT)
if (!includeLongNames)
#endif
SERIAL_ECHOLN(p.fileSize);
#if ENABLED(LONG_FILENAME_HOST_SUPPORT)
else {
SERIAL_ECHO(p.fileSize);
SERIAL_CHAR(' ');
if (prependLong) {
SERIAL_ECHO(prependLong);
SERIAL_CHAR('/');
}
SERIAL_ECHOLN(longFilename[0] ? longFilename : "???");
}
#endif
} }
} }
} }
@ -313,10 +343,10 @@ void CardReader::printListing(SdFile parent, const char * const prepend/*=nullpt
// //
// List all files on the SD card // List all files on the SD card
// //
void CardReader::ls() { void CardReader::ls(TERN_(LONG_FILENAME_HOST_SUPPORT, bool includeLongNames/*=false*/)) {
if (flag.mounted) { if (flag.mounted) {
root.rewind(); root.rewind();
printListing(root); printListing(root OPTARG(LONG_FILENAME_HOST_SUPPORT, includeLongNames));
} }
} }

View File

@ -199,7 +199,7 @@ public:
FORCE_INLINE static void getfilename_sorted(const uint16_t nr) { selectFileByIndex(nr); } FORCE_INLINE static void getfilename_sorted(const uint16_t nr) { selectFileByIndex(nr); }
#endif #endif
static void ls(); static void ls(TERN_(LONG_FILENAME_HOST_SUPPORT, bool includeLongNames=false));
#if ENABLED(POWER_LOSS_RECOVERY) #if ENABLED(POWER_LOSS_RECOVERY)
static bool jobRecoverFileExists(); static bool jobRecoverFileExists();
@ -330,7 +330,12 @@ private:
static int countItems(SdFile dir); static int countItems(SdFile dir);
static void selectByIndex(SdFile dir, const uint8_t index); static void selectByIndex(SdFile dir, const uint8_t index);
static void selectByName(SdFile dir, const char * const match); static void selectByName(SdFile dir, const char * const match);
static void printListing(SdFile parent, const char * const prepend=nullptr); static void printListing(
SdFile parent
OPTARG(LONG_FILENAME_HOST_SUPPORT, const bool includeLongNames=false)
, const char * const prepend=nullptr
OPTARG(LONG_FILENAME_HOST_SUPPORT, const char * const prependLong=nullptr)
);
#if ENABLED(SDCARD_SORT_ALPHA) #if ENABLED(SDCARD_SORT_ALPHA)
static void flush_presort(); static void flush_presort();