Ver código fonte

📝 Document diveToFile, printListing

Scott Lahteine 4 anos atrás
pai
commit
4ea4fa78aa

+ 1
- 1
Marlin/src/inc/SanityCheck.h Ver arquivo

2304
   + (DISABLED(IS_LEGACY_TFT) && ENABLED(TFT_GENERIC)) \
2304
   + (DISABLED(IS_LEGACY_TFT) && ENABLED(TFT_GENERIC)) \
2305
   + (ENABLED(IS_LEGACY_TFT) && COUNT_ENABLED(TFT_320x240, TFT_320x240_SPI, TFT_480x320, TFT_480x320_SPI)) \
2305
   + (ENABLED(IS_LEGACY_TFT) && COUNT_ENABLED(TFT_320x240, TFT_320x240_SPI, TFT_480x320, TFT_480x320_SPI)) \
2306
   + COUNT_ENABLED(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON, ANYCUBIC_TFT35) \
2306
   + COUNT_ENABLED(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON, ANYCUBIC_TFT35) \
2307
-  + COUNT_ENABLED(DGUS_LCD_UI_ORIGIN, DGUS_LCD_UI_FYSETC, DGUS_LCD_UI_HIPRECY,DGUS_LCD_UI_MKS) \
2307
+  + COUNT_ENABLED(DGUS_LCD_UI_ORIGIN, DGUS_LCD_UI_FYSETC, DGUS_LCD_UI_HIPRECY, DGUS_LCD_UI_MKS) \
2308
   + COUNT_ENABLED(ENDER2_STOCKDISPLAY, CR10_STOCKDISPLAY, DWIN_CREALITY_LCD) \
2308
   + COUNT_ENABLED(ENDER2_STOCKDISPLAY, CR10_STOCKDISPLAY, DWIN_CREALITY_LCD) \
2309
   + COUNT_ENABLED(FYSETC_MINI_12864_X_X, FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1, FYSETC_GENERIC_12864_1_1) \
2309
   + COUNT_ENABLED(FYSETC_MINI_12864_X_X, FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1, FYSETC_GENERIC_12864_1_1) \
2310
   + COUNT_ENABLED(LCD_SAINSMART_I2C_1602, LCD_SAINSMART_I2C_2004) \
2310
   + COUNT_ENABLED(LCD_SAINSMART_I2C_1602, LCD_SAINSMART_I2C_2004) \

+ 56
- 46
Marlin/src/sd/cardreader.cpp Ver arquivo

261
 }
261
 }
262
 
262
 
263
 //
263
 //
264
-// Recursive method to list all files within a folder
264
+// Recursive method to print all files within a folder in flat
265
+// DOS 8.3 format. This style of listing is the most compatible
266
+// with legacy hosts.
267
+//
268
+// This method recurses to unlimited depth and lists every
269
+// G-code file within the given parent. If the hierarchy is
270
+// very deep this can blow up the stack, so a 'depth' parameter
271
+// (as with printListingJSON) would be a good addition.
265
 //
272
 //
266
 void CardReader::printListing(SdFile parent, const char * const prepend/*=nullptr*/) {
273
 void CardReader::printListing(SdFile parent, const char * const prepend/*=nullptr*/) {
267
   dir_t p;
274
   dir_t p;
288
 
295
 
289
       // Get a new directory object using the full path
296
       // Get a new directory object using the full path
290
       // and dive recursively into it.
297
       // and dive recursively into it.
291
-      SdFile child;
292
-      if (!child.open(&parent, dosFilename, O_READ))
298
+      SdFile child; // child.close() in destructor
299
+      if (child.open(&parent, dosFilename, O_READ))
300
+        printListing(child, path);
301
+      else {
293
         SERIAL_ECHO_MSG(STR_SD_CANT_OPEN_SUBDIR, dosFilename);
302
         SERIAL_ECHO_MSG(STR_SD_CANT_OPEN_SUBDIR, dosFilename);
294
-
295
-      printListing(child, path);
296
-      // close() is done automatically by destructor of SdFile
303
+        return;
304
+      }
297
     }
305
     }
298
     else if (is_dir_or_gcode(p)) {
306
     else if (is_dir_or_gcode(p)) {
299
-      createFilename(filename, p);
300
       if (prepend) SERIAL_ECHO(prepend);
307
       if (prepend) SERIAL_ECHO(prepend);
301
-      SERIAL_ECHO(filename);
308
+      SERIAL_ECHO(createFilename(filename, p));
302
       SERIAL_CHAR(' ');
309
       SERIAL_CHAR(' ');
303
       SERIAL_ECHOLN(p.fileSize);
310
       SERIAL_ECHOLN(p.fileSize);
304
     }
311
     }
342
       // Go to the next segment
349
       // Go to the next segment
343
       while (path[++i]) { }
350
       while (path[++i]) { }
344
 
351
 
345
-      // SERIAL_ECHOPGM("Looking for segment: "); SERIAL_ECHOLN(segment);
352
+      //SERIAL_ECHOLNPAIR("Looking for segment: ", segment);
346
 
353
 
347
       // Find the item, setting the long filename
354
       // Find the item, setting the long filename
348
       diveDir.rewind();
355
       diveDir.rewind();
720
 
727
 
721
   //abortFilePrintNow();
728
   //abortFilePrintNow();
722
 
729
 
723
-  SdFile *curDir;
724
-  const char * const fname = diveToFile(false, curDir, name);
730
+  SdFile *itsDirPtr;
731
+  const char * const fname = diveToFile(false, itsDirPtr, name);
725
   if (!fname) return;
732
   if (!fname) return;
726
 
733
 
727
   #if ENABLED(SDCARD_READONLY)
734
   #if ENABLED(SDCARD_READONLY)
728
     SERIAL_ECHOLNPAIR("Deletion failed (read-only), File: ", fname, ".");
735
     SERIAL_ECHOLNPAIR("Deletion failed (read-only), File: ", fname, ".");
729
   #else
736
   #else
730
-    if (file.remove(curDir, fname)) {
737
+    if (file.remove(itsDirPtr, fname)) {
731
       SERIAL_ECHOLNPAIR("File deleted:", fname);
738
       SERIAL_ECHOLNPAIR("File deleted:", fname);
732
       sdpos = 0;
739
       sdpos = 0;
733
       TERN_(SDCARD_SORT_ALPHA, presort());
740
       TERN_(SDCARD_SORT_ALPHA, presort());
870
  *  - If update_cwd was 'true' the workDir now points to the file's directory.
877
  *  - If update_cwd was 'true' the workDir now points to the file's directory.
871
  *
878
  *
872
  * Returns a pointer to the last segment (filename) of the given DOS 8.3 path.
879
  * Returns a pointer to the last segment (filename) of the given DOS 8.3 path.
880
+ * On exit, inDirPtr contains an SdFile reference to the file's directory.
873
  *
881
  *
874
  * A nullptr result indicates an unrecoverable error.
882
  * A nullptr result indicates an unrecoverable error.
883
+ *
884
+ * NOTE: End the path with a slash to dive to a folder. In this case the
885
+ *       returned filename will be blank (points to the end of the path).
875
  */
886
  */
876
-const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, const char * const path, const bool echo/*=false*/) {
887
+const char* CardReader::diveToFile(const bool update_cwd, SdFile* &inDirPtr, const char * const path, const bool echo/*=false*/) {
877
   DEBUG_SECTION(est, "diveToFile", true);
888
   DEBUG_SECTION(est, "diveToFile", true);
878
 
889
 
879
   // Track both parent and subfolder
890
   // Track both parent and subfolder
880
   static SdFile newDir1, newDir2;
891
   static SdFile newDir1, newDir2;
881
-  SdFile *sub = &newDir1, *startDir;
892
+  SdFile *sub = &newDir1, *startDirPtr;
882
 
893
 
883
   // Parsing the path string
894
   // Parsing the path string
884
-  const char *item_name_adr = path;
895
+  const char *atom_ptr = path;
885
 
896
 
886
   DEBUG_ECHOLNPAIR(" path = '", path, "'");
897
   DEBUG_ECHOLNPAIR(" path = '", path, "'");
887
 
898
 
888
   if (path[0] == '/') {               // Starting at the root directory?
899
   if (path[0] == '/') {               // Starting at the root directory?
889
-    diveDir = &root;
890
-    item_name_adr++;
891
-    DEBUG_ECHOLNPAIR(" CWD to root: ", hex_address((void*)diveDir));
900
+    inDirPtr = &root;
901
+    atom_ptr++;
902
+    DEBUG_ECHOLNPAIR(" CWD to root: ", hex_address((void*)inDirPtr));
892
     if (update_cwd) workDirDepth = 0; // The cwd can be updated for the benefit of sub-programs
903
     if (update_cwd) workDirDepth = 0; // The cwd can be updated for the benefit of sub-programs
893
   }
904
   }
894
   else
905
   else
895
-    diveDir = &workDir;               // Dive from workDir (as set by the UI)
906
+    inDirPtr = &workDir;              // Dive from workDir (as set by the UI)
896
 
907
 
897
-  startDir = diveDir;
908
+  startDirPtr = inDirPtr;
898
 
909
 
899
-  DEBUG_ECHOLNPAIR(" startDir = ", hex_address((void*)startDir));
910
+  DEBUG_ECHOLNPAIR(" startDirPtr = ", hex_address((void*)startDirPtr));
900
 
911
 
901
-  while (item_name_adr) {
912
+  while (atom_ptr) {
902
     // Find next subdirectory delimiter
913
     // Find next subdirectory delimiter
903
-    char * const name_end = strchr(item_name_adr, '/');
914
+    char * const name_end = strchr(atom_ptr, '/');
904
 
915
 
905
     // Last atom in the path? Item found.
916
     // Last atom in the path? Item found.
906
-    if (name_end <= item_name_adr) break;
917
+    if (name_end <= atom_ptr) break;
907
 
918
 
908
-    // Set subDirName
909
-    const uint8_t len = name_end - item_name_adr;
919
+    // Isolate the next subitem name
920
+    const uint8_t len = name_end - atom_ptr;
910
     char dosSubdirname[len + 1];
921
     char dosSubdirname[len + 1];
911
-    strncpy(dosSubdirname, item_name_adr, len);
922
+    strncpy(dosSubdirname, atom_ptr, len);
912
     dosSubdirname[len] = 0;
923
     dosSubdirname[len] = 0;
913
 
924
 
914
     if (echo) SERIAL_ECHOLN(dosSubdirname);
925
     if (echo) SERIAL_ECHOLN(dosSubdirname);
915
 
926
 
916
     DEBUG_ECHOLNPAIR(" sub = ", hex_address((void*)sub));
927
     DEBUG_ECHOLNPAIR(" sub = ", hex_address((void*)sub));
917
 
928
 
918
-    // Open diveDir (closing first)
929
+    // Open inDirPtr (closing first)
919
     sub->close();
930
     sub->close();
920
-    if (!sub->open(diveDir, dosSubdirname, O_READ)) {
931
+    if (!sub->open(inDirPtr, dosSubdirname, O_READ)) {
921
       openFailed(dosSubdirname);
932
       openFailed(dosSubdirname);
922
-      item_name_adr = nullptr;
933
+      atom_ptr = nullptr;
923
       break;
934
       break;
924
     }
935
     }
925
 
936
 
926
-    // Close diveDir if not at starting-point
927
-    if (diveDir != startDir) {
928
-      DEBUG_ECHOLNPAIR(" closing diveDir: ", hex_address((void*)diveDir));
929
-      diveDir->close();
937
+    // Close inDirPtr if not at starting-point
938
+    if (inDirPtr != startDirPtr) {
939
+      DEBUG_ECHOLNPAIR(" closing inDirPtr: ", hex_address((void*)inDirPtr));
940
+      inDirPtr->close();
930
     }
941
     }
931
 
942
 
932
-    // diveDir now subDir
933
-    diveDir = sub;
934
-    DEBUG_ECHOLNPAIR(" diveDir = sub: ", hex_address((void*)diveDir));
943
+    // inDirPtr now subDir
944
+    inDirPtr = sub;
945
+    DEBUG_ECHOLNPAIR(" inDirPtr = sub: ", hex_address((void*)inDirPtr));
935
 
946
 
936
     // Update workDirParents and workDirDepth
947
     // Update workDirParents and workDirDepth
937
     if (update_cwd) {
948
     if (update_cwd) {
938
       DEBUG_ECHOLNPAIR(" update_cwd");
949
       DEBUG_ECHOLNPAIR(" update_cwd");
939
       if (workDirDepth < MAX_DIR_DEPTH)
950
       if (workDirDepth < MAX_DIR_DEPTH)
940
-        workDirParents[workDirDepth++] = *diveDir;
951
+        workDirParents[workDirDepth++] = *inDirPtr;
941
     }
952
     }
942
 
953
 
943
     // Point sub at the other scratch object
954
     // Point sub at the other scratch object
944
-    sub = (diveDir != &newDir1) ? &newDir1 : &newDir2;
955
+    sub = (inDirPtr != &newDir1) ? &newDir1 : &newDir2;
945
     DEBUG_ECHOLNPAIR(" swapping sub = ", hex_address((void*)sub));
956
     DEBUG_ECHOLNPAIR(" swapping sub = ", hex_address((void*)sub));
946
 
957
 
947
     // Next path atom address
958
     // Next path atom address
948
-    item_name_adr = name_end + 1;
959
+    atom_ptr = name_end + 1;
949
   }
960
   }
950
 
961
 
951
   if (update_cwd) {
962
   if (update_cwd) {
952
-    workDir = *diveDir;
953
-    DEBUG_ECHOLNPAIR(" final workDir = ", hex_address((void*)diveDir));
963
+    workDir = *inDirPtr;
964
+    DEBUG_ECHOLNPAIR(" final workDir = ", hex_address((void*)inDirPtr));
954
     flag.workDirIsRoot = (workDirDepth == 0);
965
     flag.workDirIsRoot = (workDirDepth == 0);
955
     TERN_(SDCARD_SORT_ALPHA, presort());
966
     TERN_(SDCARD_SORT_ALPHA, presort());
956
   }
967
   }
957
 
968
 
958
-  DEBUG_ECHOLNPAIR(" returning string ", item_name_adr ?: "nullptr");
959
-  return item_name_adr;
969
+  DEBUG_ECHOLNPAIR(" returning string ", atom_ptr ?: "nullptr");
970
+  return atom_ptr;
960
 }
971
 }
961
 
972
 
962
 void CardReader::cd(const char * relpath) {
973
 void CardReader::cd(const char * relpath) {
963
-  SdFile newDir;
964
-  SdFile *parent = workDir.isOpen() ? &workDir : &root;
974
+  SdFile newDir, *parent = &getWorkDir();
965
 
975
 
966
   if (newDir.open(parent, relpath, O_READ)) {
976
   if (newDir.open(parent, relpath, O_READ)) {
967
     workDir = newDir;
977
     workDir = newDir;

+ 16
- 5
Marlin/src/sd/cardreader.h Ver arquivo

111
   static void mount();
111
   static void mount();
112
   static void release();
112
   static void release();
113
   static inline bool isMounted() { return flag.mounted; }
113
   static inline bool isMounted() { return flag.mounted; }
114
-  static void ls();
115
 
114
 
116
   // Handle media insert/remove
115
   // Handle media insert/remove
117
   static void manage_media();
116
   static void manage_media();
176
     return 0;
175
     return 0;
177
   }
176
   }
178
 
177
 
179
-  // Helper for open and remove
180
-  static const char* diveToFile(const bool update_cwd, SdFile* &curDir, const char * const path, const bool echo=false);
178
+  /**
179
+   * Dive down to a relative or absolute path.
180
+   * Relative paths apply to the workDir.
181
+   *
182
+   * update_cwd: Pass 'true' to update the workDir on success.
183
+   *   inDirPtr: On exit your pointer points to the target SdFile.
184
+   *             A nullptr indicates failure.
185
+   *       path: Start with '/' for abs path. End with '/' to get a folder ref.
186
+   *       echo: Set 'true' to print the path throughout the loop.
187
+   */
188
+  static const char* diveToFile(const bool update_cwd, SdFile* &inDirPtr, const char * const path, const bool echo=false);
181
 
189
 
182
   #if ENABLED(SDCARD_SORT_ALPHA)
190
   #if ENABLED(SDCARD_SORT_ALPHA)
183
     static void presort();
191
     static void presort();
184
     static void getfilename_sorted(const uint16_t nr);
192
     static void getfilename_sorted(const uint16_t nr);
185
     #if ENABLED(SDSORT_GCODE)
193
     #if ENABLED(SDSORT_GCODE)
186
-      FORCE_INLINE static void setSortOn(bool b) { sort_alpha = b; presort(); }
187
-      FORCE_INLINE static void setSortFolders(int i) { sort_folders = i; presort(); }
194
+      FORCE_INLINE static void setSortOn(bool b)        { sort_alpha   = b; presort(); }
195
+      FORCE_INLINE static void setSortFolders(int i)    { sort_folders = i; presort(); }
188
       //FORCE_INLINE static void setSortReverse(bool b) { sort_reverse = b; }
196
       //FORCE_INLINE static void setSortReverse(bool b) { sort_reverse = b; }
189
     #endif
197
     #endif
190
   #else
198
   #else
191
     FORCE_INLINE static void getfilename_sorted(const uint16_t nr) { selectFileByIndex(nr); }
199
     FORCE_INLINE static void getfilename_sorted(const uint16_t nr) { selectFileByIndex(nr); }
192
   #endif
200
   #endif
193
 
201
 
202
+  static void ls();
203
+
194
   #if ENABLED(POWER_LOSS_RECOVERY)
204
   #if ENABLED(POWER_LOSS_RECOVERY)
195
     static bool jobRecoverFileExists();
205
     static bool jobRecoverFileExists();
196
     static void openJobRecoveryFile(const bool read);
206
     static void openJobRecoveryFile(const bool read);
199
 
209
 
200
   // Current Working Dir - Set by cd, cdup, cdroot, and diveToFile(true, ...)
210
   // Current Working Dir - Set by cd, cdup, cdroot, and diveToFile(true, ...)
201
   static inline char* getWorkDirName()  { workDir.getDosName(filename); return filename; }
211
   static inline char* getWorkDirName()  { workDir.getDosName(filename); return filename; }
212
+  static inline SdFile& getWorkDir()    { return workDir.isOpen() ? workDir : root; }
202
 
213
 
203
   // Print File stats
214
   // Print File stats
204
   static inline uint32_t getFileSize()  { return filesize; }
215
   static inline uint32_t getFileSize()  { return filesize; }

Carregando…
Cancelar
Salvar