From f343e6432ac33c7417d35d3f2faadcb9f94ae515 Mon Sep 17 00:00:00 2001 From: Voinea Dragos Date: Sun, 31 Jan 2021 16:42:01 +0200 Subject: [PATCH 1/6] Fix diveSubfolder string termination --- Firmware/cardreader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index a96268972..4b55e8161 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -340,9 +340,9 @@ void CardReader::diveSubfolder (const char *fileName, SdFile& dir) { const size_t maxLen = 12; char subdirname[maxLen+1]; - subdirname[maxLen] = 0; const size_t len = ((static_cast(dirname_end-dirname_start))>maxLen) ? maxLen : (dirname_end-dirname_start); strncpy(subdirname, dirname_start, len); + subdirname[len] = 0; SERIAL_ECHOLN(subdirname); if (!dir.open(curDir, subdirname, O_READ)) { From 52f7a71dce177cf7dc484988a6701f08e689d9e2 Mon Sep 17 00:00:00 2001 From: Voinea Dragos Date: Sat, 6 Feb 2021 14:59:11 +0200 Subject: [PATCH 2/6] More fixes that were extracted from #2405 --- Firmware/Marlin.h | 4 -- Firmware/Marlin_main.cpp | 8 +--- Firmware/cardreader.cpp | 81 +++++++++++++++++++++------------------- Firmware/cardreader.h | 10 +++-- Firmware/messages.c | 1 + Firmware/messages.h | 1 + Firmware/ultralcd.cpp | 12 ++---- 7 files changed, 57 insertions(+), 60 deletions(-) diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 1ed5e0bd3..cbe03c0f6 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -350,10 +350,6 @@ extern unsigned long t_fan_rising_edge; extern bool mesh_bed_leveling_flag; extern bool mesh_bed_run_from_menu; -extern bool sortAlpha; - -extern char dir_names[][9]; - extern int8_t lcd_change_fil_state; // save/restore printing extern bool saved_printing; diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 6db1d2770..e5daeee07 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -228,10 +228,6 @@ bool fan_state[2]; int fan_edge_counter[2]; int fan_speed[2]; -char dir_names[MAX_DIR_DEPTH][9]; - -bool sortAlpha = false; - float extruder_multiplier[EXTRUDERS] = {1.0 #if EXTRUDERS > 1 @@ -11281,8 +11277,8 @@ void restore_print_from_eeprom(bool mbl_was_active) { } dir_name[8] = '\0'; MYSERIAL.println(dir_name); - strcpy(dir_names[i], dir_name); - card.chdir(dir_name); + // strcpy(dir_names[i], dir_name); + card.chdir(dir_name, false); } for (int i = 0; i < 8; i++) { diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 4b55e8161..418dbb940 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -32,6 +32,7 @@ CardReader::CardReader() workDirDepth = 0; file_subcall_ctr=0; memset(workDirParents, 0, sizeof(workDirParents)); + presort_flag = false; autostart_stilltocheck=true; //the SD start is delayed, because otherwise the serial cannot answer fast enough to make contact with the host software. lastnr=0; @@ -69,12 +70,15 @@ char *createFilename(char *buffer,const dir_t &p) //buffer>12characters +*/ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/) { + static uint8_t recursionCnt = 0; dir_t p; uint8_t cnt = 0; // Read the next entry from a directory while (parent.readDir(p, longFilename) > 0) { - // If the entry is a directory and the action is LS_SerialPrint - if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) { + if (recursionCnt >= MAX_DIR_DEPTH) + return; + else if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) { // If the entry is a directory and the action is LS_SerialPrint + recursionCnt++; // Get the short name for the item, which we know is a folder char lfilename[FILENAME_LENGTH]; createFilename(lfilename, p); @@ -108,6 +112,7 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m if (lsAction == LS_SerialPrint_LFN) puts_P(PSTR("DIR_EXIT")); + recursionCnt--; } else { uint8_t pn0 = p.name[0]; @@ -241,18 +246,18 @@ void CardReader::initsd() } -void CardReader::setroot() +void CardReader::setroot(bool doPresort) { - /*if(!workDir.openRoot(&volume)) - { - SERIAL_ECHOLNPGM(MSG_SD_WORKDIR_FAIL); - }*/ workDir=root; + workDirDepth = 0; curDir=&workDir; - #ifdef SDCARD_SORT_ALPHA - presort(); - #endif +#ifdef SDCARD_SORT_ALPHA + if (doPresort) + presort(); + else + presort_flag = true; +#endif } void CardReader::release() { @@ -317,19 +322,17 @@ void CardReader::getAbsFilename(char *t) * @param[in,out] fileName * expects file name including path * in case of absolute path, file name without path is returned - * @param[in,out] dir SdFile object to operate with, - * in case of absolute path, curDir is modified to point to dir, - * so it is not possible to create on stack inside this function, - * as curDir would point to destroyed object. */ -void CardReader::diveSubfolder (const char *fileName, SdFile& dir) +bool CardReader::diveSubfolder (const char *&fileName) { curDir=&root; - if (!fileName) return; + if (!fileName) + return 1; const char *dirname_start, *dirname_end; if (fileName[0] == '/') // absolute path { + setroot(false); dirname_start = fileName + 1; while (*dirname_start) { @@ -344,19 +347,10 @@ void CardReader::diveSubfolder (const char *fileName, SdFile& dir) strncpy(subdirname, dirname_start, len); subdirname[len] = 0; SERIAL_ECHOLN(subdirname); - if (!dir.open(curDir, subdirname, O_READ)) - { - SERIAL_PROTOCOLRPGM(MSG_SD_OPEN_FILE_FAIL); - SERIAL_PROTOCOL(subdirname); - SERIAL_PROTOCOLLN('.'); - return; - } - else - { - //SERIAL_ECHOLN("dive ok"); - } + if (!chdir(subdirname, false)) + return 0; - curDir = &dir; + curDir = &workDir; dirname_start = dirname_end + 1; } else // the reminder after all /fsa/fdsa/ is the filename @@ -373,6 +367,7 @@ void CardReader::diveSubfolder (const char *fileName, SdFile& dir) { curDir = &workDir; } + return 1; } void CardReader::openFile(const char* name,bool read, bool replace_current/*=true*/) @@ -423,9 +418,9 @@ void CardReader::openFile(const char* name,bool read, bool replace_current/*=tru } sdprinting = false; - SdFile myDir; const char *fname=name; - diveSubfolder(fname,myDir); + if (!diveSubfolder(fname)) + return; if(read) { @@ -438,10 +433,9 @@ void CardReader::openFile(const char* name,bool read, bool replace_current/*=tru SERIAL_PROTOCOLLN(filesize); sdpos = 0; - SERIAL_PROTOCOLLNRPGM(_N("File selected"));////MSG_SD_FILE_SELECTED + SERIAL_PROTOCOLLNRPGM(MSG_FILE_SELECTED); + lcd_setstatuspgm(MSG_FILE_SELECTED); getfilename(0, fname); - lcd_setstatus(longFilename[0] ? longFilename : fname); - lcd_setstatuspgm(PSTR("SD-PRINTING")); } else { @@ -475,9 +469,9 @@ void CardReader::removeFile(const char* name) file.close(); sdprinting = false; - SdFile myDir; const char *fname=name; - diveSubfolder(fname,myDir); + if (!diveSubfolder(fname)) + return; if (file.remove(curDir, fname)) { @@ -670,7 +664,7 @@ uint16_t CardReader::getnrfilenames() return nrFiles; } -void CardReader::chdir(const char * relpath) +bool CardReader::chdir(const char * relpath, bool doPresort) { SdFile newfile; SdFile *parent=&root; @@ -678,23 +672,32 @@ void CardReader::chdir(const char * relpath) if(workDir.isOpen()) parent=&workDir; - if(!newfile.open(*parent,relpath, O_READ)) + if(!newfile.open(*parent,relpath, O_READ) || ((workDirDepth + 1) >= MAX_DIR_DEPTH)) { SERIAL_ECHO_START; SERIAL_ECHORPGM(_n("Cannot enter subdir: "));////MSG_SD_CANT_ENTER_SUBDIR SERIAL_ECHOLN(relpath); + return 0; } else { + strcpy(dir_names[workDirDepth], relpath); + puts(relpath); + if (workDirDepth < MAX_DIR_DEPTH) { for (int d = ++workDirDepth; d--;) workDirParents[d+1] = workDirParents[d]; workDirParents[0]=*parent; } workDir=newfile; - #ifdef SDCARD_SORT_ALPHA + +#ifdef SDCARD_SORT_ALPHA + if (doPresort) presort(); - #endif + else + presort_flag = true; +#endif + return 1; } } diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 9bf9bd0a6..819e8bf27 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -39,9 +39,9 @@ public: void ls(bool printLFN); - void chdir(const char * relpath); + bool chdir(const char * relpath, bool doPresort); void updir(); - void setroot(); + void setroot(bool doPresort); #ifdef SDCARD_SORT_ALPHA void presort(); @@ -82,6 +82,10 @@ public: char longFilename[LONG_FILENAME_LENGTH]; bool filenameIsDir; int lastnr; //last number of the autostart; +#ifdef SDCARD_SORT_ALPHA + bool presort_flag; + char dir_names[MAX_DIR_DEPTH][9]; +#endif // SDCARD_SORT_ALPHA private: SdFile root,*curDir,workDir,workDirParents[MAX_DIR_DEPTH]; uint16_t workDirDepth; @@ -155,7 +159,7 @@ private: int16_t nrFiles; //counter for the files in the current directory and recycled as position counter for getting the nrFiles'th name in the directory. char* diveDirName; - void diveSubfolder (const char *fileName, SdFile& dir); + bool diveSubfolder (const char *&fileName); void lsDive(const char *prepend, SdFile parent, const char * const match=NULL); #ifdef SDCARD_SORT_ALPHA void flush_presort(); diff --git a/Firmware/messages.c b/Firmware/messages.c index 0b1d58e04..39f0cf336 100644 --- a/Firmware/messages.c +++ b/Firmware/messages.c @@ -197,3 +197,4 @@ const char MSG_M112_KILL[] PROGMEM_N1 = "M112 called. Emergency Stop."; ////c=20 const char MSG_ADVANCE_K[] PROGMEM_N1 = "Advance K:"; ////c=13 const char MSG_POWERPANIC_DETECTED[] PROGMEM_N1 = "POWER PANIC DETECTED"; ////c=20 const char MSG_LCD_STATUS_CHANGED[] PROGMEM_N1 = "LCD status changed"; +const char MSG_FILE_SELECTED[] PROGMEM_N1 = "File selected"; ////c=20 diff --git a/Firmware/messages.h b/Firmware/messages.h index 0a05c58f5..a5b672fa2 100644 --- a/Firmware/messages.h +++ b/Firmware/messages.h @@ -197,6 +197,7 @@ extern const char MSG_M112_KILL[]; extern const char MSG_ADVANCE_K[]; extern const char MSG_POWERPANIC_DETECTED[]; extern const char MSG_LCD_STATUS_CHANGED[]; +extern const char MSG_FILE_SELECTED[]; #if defined(__cplusplus) } diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 0f6bc1fa3..2d92596f0 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -4317,7 +4317,7 @@ static void lcd_sort_type_set() { default: sdSort = SD_SORT_TIME; } eeprom_update_byte((unsigned char *)EEPROM_SD_SORT, sdSort); - presort_flag = true; + card.presort_flag = true; } #endif //SDCARD_SORT_ALPHA @@ -8548,7 +8548,7 @@ static void menu_action_sdfile(const char* filename) for (uint_least8_t i = 0; i < depth; i++) { for (uint_least8_t j = 0; j < 8; j++) { - eeprom_write_byte((uint8_t*)EEPROM_DIRS + j + 8 * i, dir_names[i][j]); + eeprom_write_byte((uint8_t*)EEPROM_DIRS + j + 8 * i, card.dir_names[i][j]); } } @@ -8566,12 +8566,8 @@ static void menu_action_sdfile(const char* filename) void menu_action_sddirectory(const char* filename) { - uint8_t depth = (uint8_t)card.getWorkDirDepth(); - - strcpy(dir_names[depth], filename); - MYSERIAL.println(dir_names[depth]); - card.chdir(filename); - lcd_encoder = 0; + card.chdir(filename, true); + lcd_encoder = 0; } /** LCD API **/ From 77a5082b5664c7ccfe05ed08af16c89ad7c7b448 Mon Sep 17 00:00:00 2001 From: Voinea Dragos Date: Sat, 6 Feb 2021 17:25:17 +0200 Subject: [PATCH 3/6] Fix presort_flag duplicate declaration --- Firmware/ultralcd.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 2d92596f0..a736f8c2b 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -75,11 +75,6 @@ int8_t FSensorStateMenu = 1; bool bMenuFSDetect=false; #endif //IR_SENSOR_ANALOG - -#ifdef SDCARD_SORT_ALPHA -bool presort_flag = false; -#endif - LcdCommands lcd_commands_type = LcdCommands::Idle; static uint8_t lcd_commands_step = 0; @@ -7183,8 +7178,8 @@ void lcd_sdcard_menu() { uint8_t sdSort = eeprom_read_byte((uint8_t*)EEPROM_SD_SORT); - if (presort_flag == true) { - presort_flag = false; + if (card.presort_flag == true) { + card.presort_flag = false; card.presort(); } if (lcd_draw_update == 0 && LCD_CLICKED == 0) From f5cde38a7c000eeacfc7dc08f46e820359ee8777 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Sat, 6 Feb 2021 21:06:37 +0200 Subject: [PATCH 4/6] Remove duplicit debug line --- Firmware/cardreader.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 418dbb940..8273e3d04 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -346,7 +346,6 @@ bool CardReader::diveSubfolder (const char *&fileName) const size_t len = ((static_cast(dirname_end-dirname_start))>maxLen) ? maxLen : (dirname_end-dirname_start); strncpy(subdirname, dirname_start, len); subdirname[len] = 0; - SERIAL_ECHOLN(subdirname); if (!chdir(subdirname, false)) return 0; From c739aa900303fddd86c62bc951f26ef18178a0a8 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Sun, 7 Feb 2021 21:51:44 +0200 Subject: [PATCH 5/6] M23 full path support. --- Firmware/cardreader.cpp | 22 ++++++++++++++++------ Firmware/cardreader.h | 1 + 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 8273e3d04..c414e2823 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -309,6 +309,18 @@ void CardReader::getAbsFilename(char *t) else t[0]=0; } + +void CardReader::printAbsFilenameFast() +{ + SERIAL_PROTOCOL('/'); + for (uint8_t i = 0; i < getWorkDirDepth(); i++) + { + SERIAL_PROTOCOL(dir_names[i]); + SERIAL_PROTOCOL('/'); + } + SERIAL_PROTOCOL(LONGEST_FILENAME); +} + /** * @brief Dive into subfolder * @@ -425,16 +437,16 @@ void CardReader::openFile(const char* name,bool read, bool replace_current/*=tru { if (file.open(curDir, fname, O_READ)) { + getfilename(0, fname); filesize = file.fileSize(); SERIAL_PROTOCOLRPGM(_N("File opened: "));////MSG_SD_FILE_OPENED - SERIAL_PROTOCOL(fname); + printAbsFilenameFast(); SERIAL_PROTOCOLRPGM(_n(" Size: "));////MSG_SD_SIZE SERIAL_PROTOCOLLN(filesize); sdpos = 0; SERIAL_PROTOCOLLNRPGM(MSG_FILE_SELECTED); lcd_setstatuspgm(MSG_FILE_SELECTED); - getfilename(0, fname); } else { @@ -508,10 +520,8 @@ void CardReader::getStatus(bool arg_P) { if (arg_P) { - SERIAL_PROTOCOL('/'); - for (uint8_t i = 0; i < getWorkDirDepth(); i++) - printf_P(PSTR("%s/"), dir_names[i]); - puts(filename); + printAbsFilenameFast(); + SERIAL_PROTOCOLLN(); } else SERIAL_PROTOCOLLN(LONGEST_FILENAME); diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 819e8bf27..0e94bd3c9 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -34,6 +34,7 @@ public: uint16_t getnrfilenames(); void getAbsFilename(char *t); + void printAbsFilenameFast(); void getDirName(char* name, uint8_t level); uint16_t getWorkDirDepth(); From 4fcbf95db65e33d4fa7ee561a510c8f79f2bdfd1 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 9 Feb 2021 15:00:46 +0200 Subject: [PATCH 6/6] apply RAII principle on the lsDive recursion limiter --- Firmware/cardreader.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index c414e2823..3ca88f63c 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -71,14 +71,22 @@ char *createFilename(char *buffer,const dir_t &p) //buffer>12characters void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/) { static uint8_t recursionCnt = 0; + // RAII incrementer for the recursionCnt + class _incrementer + { + public: + _incrementer() {recursionCnt++;} + ~_incrementer() {recursionCnt--;} + } recursionCntIncrementer; + dir_t p; uint8_t cnt = 0; // Read the next entry from a directory while (parent.readDir(p, longFilename) > 0) { - if (recursionCnt >= MAX_DIR_DEPTH) + if (recursionCnt > MAX_DIR_DEPTH) return; else if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) { // If the entry is a directory and the action is LS_SerialPrint - recursionCnt++; + // Get the short name for the item, which we know is a folder char lfilename[FILENAME_LENGTH]; createFilename(lfilename, p); @@ -112,7 +120,6 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m if (lsAction == LS_SerialPrint_LFN) puts_P(PSTR("DIR_EXIT")); - recursionCnt--; } else { uint8_t pn0 = p.name[0];