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;
This commit is contained in:
parent
c05beb74a9
commit
4eaa200113
5 changed files with 240 additions and 40 deletions
|
|
@ -1256,6 +1256,15 @@
|
||||||
// This allows hosts to request long names for files and folders with M33
|
// This allows hosts to request long names for files and folders with M33
|
||||||
//#define LONG_FILENAME_HOST_SUPPORT
|
//#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
|
// Enable this option to scroll long filenames in the SD card menu
|
||||||
//#define SCROLL_LONG_FILENAMES
|
//#define SCROLL_LONG_FILENAMES
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,9 +32,36 @@
|
||||||
*/
|
*/
|
||||||
void GcodeSuite::M20() {
|
void GcodeSuite::M20() {
|
||||||
if (card.flag.mounted) {
|
if (card.flag.mounted) {
|
||||||
SERIAL_ECHOLNPGM(STR_BEGIN_FILE_LIST);
|
if ( parser.seen('S' ) and parser.seen('L' ) ) {
|
||||||
card.ls();
|
card.ls(TRUE,TRUE);
|
||||||
SERIAL_ECHOLNPGM(STR_END_FILE_LIST);
|
|
||||||
|
} 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
|
else
|
||||||
SERIAL_ECHO_MSG(STR_NO_MEDIA);
|
SERIAL_ECHO_MSG(STR_NO_MEDIA);
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
*/
|
*/
|
||||||
void GcodeSuite::M33() {
|
void GcodeSuite::M33() {
|
||||||
|
|
||||||
card.printLongPath(parser.string_arg);
|
card.printLongPath(parser.string_arg, true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,8 @@
|
||||||
#include "../core/debug_out.h"
|
#include "../core/debug_out.h"
|
||||||
#include "../libs/hex_print.h"
|
#include "../libs/hex_print.h"
|
||||||
|
|
||||||
|
#include <strings.h> //Required for strcasecmp command to compile without warnings in VS_Code
|
||||||
|
|
||||||
// public:
|
// public:
|
||||||
|
|
||||||
card_flags_t CardReader::flag;
|
card_flags_t CardReader::flag;
|
||||||
|
|
@ -154,6 +156,7 @@ CardReader::CardReader() {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get a DOS 8.3 filename in its useful form
|
// Get a DOS 8.3 filename in its useful form
|
||||||
|
// Requires a file specified
|
||||||
//
|
//
|
||||||
char *createFilename(char * const buffer, const dir_t &p) {
|
char *createFilename(char * const buffer, const dir_t &p) {
|
||||||
char *pos = buffer;
|
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
|
// 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;
|
dir_t p;
|
||||||
for (uint8_t cnt = 0; dir.readDir(&p, longFilename) > 0; cnt++) {
|
for (uint8_t cnt = 0; dir.readDir(&p, longFilename) > 0; cnt++) {
|
||||||
if (is_dir_or_gcode(p)) {
|
if (is_dir_or_gcode(p)) {
|
||||||
createFilename(filename, 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
|
// 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;
|
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)) {
|
||||||
|
|
@ -265,26 +361,49 @@ void CardReader::printListing(SdFile parent, const char * const prepend/*=nullpt
|
||||||
SERIAL_ECHO_START();
|
SERIAL_ECHO_START();
|
||||||
SERIAL_ECHOLNPAIR(STR_SD_CANT_OPEN_SUBDIR, dosFilename);
|
SERIAL_ECHOLNPAIR(STR_SD_CANT_OPEN_SUBDIR, dosFilename);
|
||||||
}
|
}
|
||||||
printListing(child, path);
|
printListing(child, ReturnDOSFileNames, ReturnLongFileNames, path);
|
||||||
// close() is done automatically by destructor of SdFile
|
// close() is done automatically by destructor of SdFile
|
||||||
}
|
}
|
||||||
else if (is_dir_or_gcode(p)) {
|
else if (is_dir_or_gcode(p)) {
|
||||||
createFilename(filename, p);
|
createFilename(filename, p); //Parse the string and retrieve a DOS 8.3 FileName+
|
||||||
if (prepend) SERIAL_ECHO(prepend);
|
|
||||||
SERIAL_ECHO(filename);
|
|
||||||
SERIAL_CHAR(' ');
|
|
||||||
SERIAL_ECHOLN(p.fileSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
#if ENABLED(LONG_FILENAME_HOST_SUPPORT)
|
||||||
// List all files on the SD card
|
|
||||||
//
|
if (ReturnDOSFileNames) {//Print the DOS FileName & Path
|
||||||
void CardReader::ls() {
|
if (prepend) { SERIAL_ECHO(prepend); }
|
||||||
if (flag.mounted) {
|
SERIAL_ECHO(filename);
|
||||||
root.rewind();
|
}
|
||||||
printListing(root);
|
|
||||||
|
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
|
// 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);
|
int i, pathLen = strlen(path);
|
||||||
|
|
||||||
|
|
@ -344,11 +463,32 @@ void CardReader::ls() {
|
||||||
|
|
||||||
} // while i<pathLen
|
} // while i<pathLen
|
||||||
|
|
||||||
SERIAL_EOL();
|
if (PrintLineReturn) SERIAL_EOL();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // LONG_FILENAME_HOST_SUPPORT
|
#endif // LONG_FILENAME_HOST_SUPPORT
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// List all files on the SD card
|
||||||
|
//
|
||||||
|
void CardReader::ls(boolean ReturnDOSFileNames, boolean ReturnLongFileNames) {
|
||||||
|
if (flag.mounted) {
|
||||||
|
#if ENABLED(M20_Reports_Directory_Names)
|
||||||
|
SERIAL_ECHOLN("Begin Directory Listing") ;
|
||||||
|
root.rewind();
|
||||||
|
card.printDirListing(root, ReturnDOSFileNames,ReturnLongFileNames);
|
||||||
|
SERIAL_ECHOLN("End Directory Listing") ;
|
||||||
|
SERIAL_ECHOLN(" ") ;
|
||||||
|
#endif
|
||||||
|
SERIAL_ECHOLNPGM(STR_BEGIN_FILE_LIST);
|
||||||
|
root.rewind();
|
||||||
|
printListing(root, ReturnDOSFileNames, ReturnLongFileNames);
|
||||||
|
SERIAL_ECHOLNPGM(STR_END_FILE_LIST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Echo the DOS 8.3 filename (and long filename, if any)
|
// Echo the DOS 8.3 filename (and long filename, if any)
|
||||||
//
|
//
|
||||||
|
|
@ -573,7 +713,7 @@ void CardReader::openFileRead(char * const path, const uint8_t subcall_type/*=0*
|
||||||
endFilePrint();
|
endFilePrint();
|
||||||
|
|
||||||
SdFile *diveDir;
|
SdFile *diveDir;
|
||||||
const char * const fname = diveToFile(true, diveDir, path);
|
const char * const fname = diveToFile(true, diveDir, path, false);
|
||||||
if (!fname) return;
|
if (!fname) return;
|
||||||
|
|
||||||
if (file.open(diveDir, fname, O_READ)) {
|
if (file.open(diveDir, fname, O_READ)) {
|
||||||
|
|
@ -608,7 +748,7 @@ void CardReader::openFileWrite(char * const path) {
|
||||||
endFilePrint();
|
endFilePrint();
|
||||||
|
|
||||||
SdFile *diveDir;
|
SdFile *diveDir;
|
||||||
const char * const fname = diveToFile(false, diveDir, path);
|
const char * const fname = diveToFile(false, diveDir, path, true);
|
||||||
if (!fname) return;
|
if (!fname) return;
|
||||||
|
|
||||||
#if ENABLED(SDCARD_READONLY)
|
#if ENABLED(SDCARD_READONLY)
|
||||||
|
|
@ -633,7 +773,7 @@ void CardReader::openFileWrite(char * const path) {
|
||||||
bool CardReader::fileExists(const char * const path) {
|
bool CardReader::fileExists(const char * const path) {
|
||||||
if (!isMounted()) return false;
|
if (!isMounted()) return false;
|
||||||
SdFile *diveDir = nullptr;
|
SdFile *diveDir = nullptr;
|
||||||
const char * const fname = diveToFile(false, diveDir, path);
|
const char * const fname = diveToFile(false, diveDir, path, false);
|
||||||
if (fname) {
|
if (fname) {
|
||||||
diveDir->rewind();
|
diveDir->rewind();
|
||||||
selectByName(*diveDir, fname);
|
selectByName(*diveDir, fname);
|
||||||
|
|
@ -651,7 +791,7 @@ void CardReader::removeFile(const char * const name) {
|
||||||
//endFilePrint();
|
//endFilePrint();
|
||||||
|
|
||||||
SdFile *curDir;
|
SdFile *curDir;
|
||||||
const char * const fname = diveToFile(false, curDir, name);
|
const char * const fname = diveToFile(false, curDir, name, false);
|
||||||
if (!fname) return;
|
if (!fname) return;
|
||||||
|
|
||||||
#if ENABLED(SDCARD_READONLY)
|
#if ENABLED(SDCARD_READONLY)
|
||||||
|
|
@ -684,7 +824,7 @@ void CardReader::write_command(char * const buf) {
|
||||||
char* end = buf + strlen(buf) - 1;
|
char* end = buf + strlen(buf) - 1;
|
||||||
|
|
||||||
file.writeError = false;
|
file.writeError = false;
|
||||||
if ((npos = strchr(buf, 'N'))) {
|
if ((npos = strchr(buf, 'N')) != nullptr) {
|
||||||
begin = strchr(npos, ' ') + 1;
|
begin = strchr(npos, ' ') + 1;
|
||||||
end = strchr(npos, '*') - 1;
|
end = strchr(npos, '*') - 1;
|
||||||
}
|
}
|
||||||
|
|
@ -795,7 +935,7 @@ uint16_t CardReader::countFilesInWorkDir() {
|
||||||
*
|
*
|
||||||
* A nullptr result indicates an unrecoverable error.
|
* 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
|
// Track both parent and subfolder
|
||||||
static SdFile newDir1, newDir2;
|
static SdFile newDir1, newDir2;
|
||||||
SdFile *sub = &newDir1, *startDir;
|
SdFile *sub = &newDir1, *startDir;
|
||||||
|
|
@ -806,12 +946,15 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile*& diveDir, cons
|
||||||
DEBUG_ECHOLNPAIR("diveToFile: path = '", path, "'");
|
DEBUG_ECHOLNPAIR("diveToFile: path = '", path, "'");
|
||||||
|
|
||||||
if (path[0] == '/') { // Starting at the root directory?
|
if (path[0] == '/') { // Starting at the root directory?
|
||||||
|
DEBUG_ECHOLN("Starting from ROOT");
|
||||||
|
root.rewind();
|
||||||
diveDir = &root;
|
diveDir = &root;
|
||||||
item_name_adr++;
|
item_name_adr++;
|
||||||
DEBUG_ECHOLNPAIR("diveToFile: CWD to root: ", hex_address((void*)diveDir));
|
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
|
if (update_cwd) workDirDepth = 0; // The cwd can be updated for the benefit of sub-programs
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
DEBUG_ECHOLN("Starting from WorkingDirectory");
|
||||||
diveDir = &workDir; // Dive from workDir (as set by the UI)
|
diveDir = &workDir; // Dive from workDir (as set by the UI)
|
||||||
|
|
||||||
startDir = diveDir;
|
startDir = diveDir;
|
||||||
|
|
@ -831,12 +974,16 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile*& diveDir, cons
|
||||||
strncpy(dosSubdirname, item_name_adr, len);
|
strncpy(dosSubdirname, item_name_adr, len);
|
||||||
dosSubdirname[len] = 0;
|
dosSubdirname[len] = 0;
|
||||||
|
|
||||||
if (echo) SERIAL_ECHOLN(dosSubdirname);
|
|
||||||
|
|
||||||
DEBUG_ECHOLNPAIR("diveToFile: sub = ", hex_address((void*)sub));
|
DEBUG_ECHOLNPAIR("diveToFile: sub = ", hex_address((void*)sub));
|
||||||
|
|
||||||
// Open diveDir (closing first)
|
// Open diveDir (closing first)
|
||||||
sub->close();
|
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)) {
|
if (!sub->open(diveDir, dosSubdirname, O_READ)) {
|
||||||
openFailed(dosSubdirname);
|
openFailed(dosSubdirname);
|
||||||
item_name_adr = nullptr;
|
item_name_adr = nullptr;
|
||||||
|
|
@ -866,7 +1013,7 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile*& diveDir, cons
|
||||||
|
|
||||||
// Next path atom address
|
// Next path atom address
|
||||||
item_name_adr = name_end + 1;
|
item_name_adr = name_end + 1;
|
||||||
}
|
} // end while loop
|
||||||
|
|
||||||
if (update_cwd) {
|
if (update_cwd) {
|
||||||
workDir = *diveDir;
|
workDir = *diveDir;
|
||||||
|
|
@ -875,7 +1022,23 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile*& diveDir, cons
|
||||||
TERN_(SDCARD_SORT_ALPHA, presort());
|
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) {
|
void CardReader::cd(const char * relpath) {
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ public:
|
||||||
static void mount();
|
static void mount();
|
||||||
static void release();
|
static void release();
|
||||||
static inline bool isMounted() { return flag.mounted; }
|
static inline bool isMounted() { return flag.mounted; }
|
||||||
static void ls();
|
static void ls(boolean ReturnDOSFileNames,boolean ReturnLongFileNames);
|
||||||
|
|
||||||
// Handle media insert/remove
|
// Handle media insert/remove
|
||||||
static void manage_media();
|
static void manage_media();
|
||||||
|
|
@ -104,7 +104,7 @@ public:
|
||||||
|
|
||||||
static inline char* longest_filename() { return longFilename[0] ? longFilename : filename; }
|
static inline char* longest_filename() { return longFilename[0] ? longFilename : filename; }
|
||||||
#if ENABLED(LONG_FILENAME_HOST_SUPPORT)
|
#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
|
#endif
|
||||||
|
|
||||||
// Working Directory for SD card menu
|
// Working Directory for SD card menu
|
||||||
|
|
@ -135,7 +135,7 @@ public:
|
||||||
static inline uint8_t percentDone() { return (isFileOpen() && filesize) ? sdpos / ((filesize + 99) / 100) : 0; }
|
static inline uint8_t percentDone() { return (isFileOpen() && filesize) ? sdpos / ((filesize + 99) / 100) : 0; }
|
||||||
|
|
||||||
// Helper for open and remove
|
// 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)
|
#if ENABLED(SDCARD_SORT_ALPHA)
|
||||||
static void presort();
|
static void presort();
|
||||||
|
|
@ -273,8 +273,9 @@ private:
|
||||||
static bool is_dir_or_gcode(const dir_t &p);
|
static bool is_dir_or_gcode(const dir_t &p);
|
||||||
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, boolean debug=false);
|
||||||
static void printListing(SdFile parent, const char * const prepend=nullptr);
|
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)
|
#if ENABLED(SDCARD_SORT_ALPHA)
|
||||||
static void flush_presort();
|
static void flush_presort();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue