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:
parent
a35c234ce1
commit
ee64081696
@ -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
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user