|
@@ -258,54 +258,82 @@ void CardReader::selectByName(SdFile dir, const char * const match) {
|
258
|
258
|
}
|
259
|
259
|
}
|
260
|
260
|
|
261
|
|
-//
|
262
|
|
-// Recursive method to print all files within a folder in flat
|
263
|
|
-// DOS 8.3 format. This style of listing is the most compatible
|
264
|
|
-// with legacy hosts.
|
265
|
|
-//
|
266
|
|
-// This method recurses to unlimited depth and lists every
|
267
|
|
-// G-code file within the given parent. If the hierarchy is
|
268
|
|
-// very deep this can blow up the stack, so a 'depth' parameter
|
269
|
|
-// (as with printListingJSON) would be a good addition.
|
270
|
|
-//
|
271
|
|
-void CardReader::printListing(SdFile parent, const char * const prepend/*=nullptr*/) {
|
|
261
|
+/**
|
|
262
|
+ * Recursive method to print all files within a folder in flat
|
|
263
|
+ * DOS 8.3 format. This style of listing is the most compatible
|
|
264
|
+ * with legacy hosts.
|
|
265
|
+ *
|
|
266
|
+ * This method recurses to unlimited depth and lists all G-code
|
|
267
|
+ * files within the given parent. If the hierarchy is very deep
|
|
268
|
+ * this can blow up the stack, so a 'depth' parameter would be a
|
|
269
|
+ * good addition.
|
|
270
|
+ */
|
|
271
|
+void CardReader::printListing(
|
|
272
|
+ SdFile parent
|
|
273
|
+ OPTARG(LONG_FILENAME_HOST_SUPPORT, const bool includeLongNames/*=false*/)
|
|
274
|
+ , const char * const prepend/*=nullptr*/
|
|
275
|
+ OPTARG(LONG_FILENAME_HOST_SUPPORT, const char * const prependLong/*=nullptr*/)
|
|
276
|
+) {
|
272
|
277
|
dir_t p;
|
273
|
278
|
while (parent.readDir(&p, longFilename) > 0) {
|
274
|
279
|
if (DIR_IS_SUBDIR(&p)) {
|
275
|
280
|
|
276
|
|
- // Get the short name for the item, which we know is a folder
|
277
|
|
- char dosFilename[FILENAME_LENGTH];
|
|
281
|
+ size_t lenPrepend = prepend ? strlen(prepend) + 1 : 0;
|
|
282
|
+ // Allocate enough stack space for the full path including / separator
|
|
283
|
+ char path[lenPrepend + FILENAME_LENGTH];
|
|
284
|
+ if (prepend) {
|
|
285
|
+ strcpy(path, prepend);
|
|
286
|
+ path[lenPrepend - 1] = '/';
|
|
287
|
+ }
|
|
288
|
+ char* dosFilename = path + lenPrepend;
|
278
|
289
|
createFilename(dosFilename, p);
|
279
|
290
|
|
280
|
|
- // Allocate enough stack space for the full path to a folder, trailing slash, and nul
|
281
|
|
- const bool prepend_is_empty = (!prepend || prepend[0] == '\0');
|
282
|
|
- const int len = (prepend_is_empty ? 1 : strlen(prepend)) + strlen(dosFilename) + 1 + 1;
|
283
|
|
- char path[len];
|
284
|
|
-
|
285
|
|
- // Append the FOLDERNAME12/ to the passed string.
|
286
|
|
- // It contains the full path to the "parent" argument.
|
287
|
|
- // We now have the full path to the item in this folder.
|
288
|
|
- strcpy(path, prepend_is_empty ? "/" : prepend); // root slash if prepend is empty
|
289
|
|
- strcat(path, dosFilename); // FILENAME_LENGTH characters maximum
|
290
|
|
- strcat(path, "/"); // 1 character
|
291
|
|
-
|
292
|
|
- // Serial.print(path);
|
293
|
|
-
|
294
|
291
|
// Get a new directory object using the full path
|
295
|
292
|
// and dive recursively into it.
|
296
|
293
|
SdFile child; // child.close() in destructor
|
297
|
294
|
if (child.open(&parent, dosFilename, O_READ))
|
298
|
|
- printListing(child, path);
|
|
295
|
+ #if ENABLED(LONG_FILENAME_HOST_SUPPORT)
|
|
296
|
+ if (includeLongNames) {
|
|
297
|
+ size_t lenPrependLong = prependLong ? strlen(prependLong) + 1 : 0;
|
|
298
|
+ // Allocate enough stack space for the full long path including / separator
|
|
299
|
+ char pathLong[lenPrependLong + strlen(longFilename) + 1];
|
|
300
|
+ if (prependLong) {
|
|
301
|
+ strcpy(pathLong, prependLong);
|
|
302
|
+ pathLong[lenPrependLong - 1] = '/';
|
|
303
|
+ }
|
|
304
|
+ strcpy(pathLong + lenPrependLong, longFilename);
|
|
305
|
+ printListing(child, /*includeLongNames=*/true, path, pathLong);
|
|
306
|
+ }
|
|
307
|
+ else
|
|
308
|
+ #endif
|
|
309
|
+ printListing(child, path);
|
299
|
310
|
else {
|
300
|
311
|
SERIAL_ECHO_MSG(STR_SD_CANT_OPEN_SUBDIR, dosFilename);
|
301
|
312
|
return;
|
302
|
313
|
}
|
303
|
314
|
}
|
304
|
315
|
else if (is_dir_or_gcode(p)) {
|
305
|
|
- if (prepend) SERIAL_ECHO(prepend);
|
|
316
|
+ if (prepend) {
|
|
317
|
+ SERIAL_ECHO(prepend);
|
|
318
|
+ SERIAL_CHAR('/');
|
|
319
|
+ }
|
306
|
320
|
SERIAL_ECHO(createFilename(filename, p));
|
307
|
321
|
SERIAL_CHAR(' ');
|
308
|
|
- SERIAL_ECHOLN(p.fileSize);
|
|
322
|
+ #if ENABLED(LONG_FILENAME_HOST_SUPPORT)
|
|
323
|
+ if (!includeLongNames)
|
|
324
|
+ #endif
|
|
325
|
+ SERIAL_ECHOLN(p.fileSize);
|
|
326
|
+ #if ENABLED(LONG_FILENAME_HOST_SUPPORT)
|
|
327
|
+ else {
|
|
328
|
+ SERIAL_ECHO(p.fileSize);
|
|
329
|
+ SERIAL_CHAR(' ');
|
|
330
|
+ if (prependLong) {
|
|
331
|
+ SERIAL_ECHO(prependLong);
|
|
332
|
+ SERIAL_CHAR('/');
|
|
333
|
+ }
|
|
334
|
+ SERIAL_ECHOLN(longFilename[0] ? longFilename : "???");
|
|
335
|
+ }
|
|
336
|
+ #endif
|
309
|
337
|
}
|
310
|
338
|
}
|
311
|
339
|
}
|
|
@@ -313,10 +341,10 @@ void CardReader::printListing(SdFile parent, const char * const prepend/*=nullpt
|
313
|
341
|
//
|
314
|
342
|
// List all files on the SD card
|
315
|
343
|
//
|
316
|
|
-void CardReader::ls() {
|
|
344
|
+void CardReader::ls(TERN_(LONG_FILENAME_HOST_SUPPORT, bool includeLongNames/*=false*/)) {
|
317
|
345
|
if (flag.mounted) {
|
318
|
346
|
root.rewind();
|
319
|
|
- printListing(root);
|
|
347
|
+ printListing(root OPTARG(LONG_FILENAME_HOST_SUPPORT, includeLongNames));
|
320
|
348
|
}
|
321
|
349
|
}
|
322
|
350
|
|