|
@@ -100,25 +100,25 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m
|
100
|
100
|
uint8_t cnt = 0;
|
101
|
101
|
|
102
|
102
|
// Read the next entry from a directory
|
103
|
|
- while (parent.readDir(p, longFilename) > 0) {
|
|
103
|
+ while (parent.readDir(&p, longFilename) > 0) {
|
104
|
104
|
|
105
|
105
|
// If the entry is a directory and the action is LS_SerialPrint
|
106
|
106
|
if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) {
|
107
|
107
|
|
108
|
108
|
// Get the short name for the item, which we know is a folder
|
109
|
|
- char lfilename[FILENAME_LENGTH];
|
110
|
|
- createFilename(lfilename, p);
|
|
109
|
+ char dosFilename[FILENAME_LENGTH];
|
|
110
|
+ createFilename(dosFilename, p);
|
111
|
111
|
|
112
|
112
|
// Allocate enough stack space for the full path to a folder, trailing slash, and nul
|
113
|
113
|
bool prepend_is_empty = (prepend[0] == '\0');
|
114
|
|
- int len = (prepend_is_empty ? 1 : strlen(prepend)) + strlen(lfilename) + 1 + 1;
|
|
114
|
+ int len = (prepend_is_empty ? 1 : strlen(prepend)) + strlen(dosFilename) + 1 + 1;
|
115
|
115
|
char path[len];
|
116
|
116
|
|
117
|
117
|
// Append the FOLDERNAME12/ to the passed string.
|
118
|
118
|
// It contains the full path to the "parent" argument.
|
119
|
119
|
// We now have the full path to the item in this folder.
|
120
|
120
|
strcpy(path, prepend_is_empty ? "/" : prepend); // root slash if prepend is empty
|
121
|
|
- strcat(path, lfilename); // FILENAME_LENGTH-1 characters maximum
|
|
121
|
+ strcat(path, dosFilename); // FILENAME_LENGTH-1 characters maximum
|
122
|
122
|
strcat(path, "/"); // 1 character
|
123
|
123
|
|
124
|
124
|
// Serial.print(path);
|
|
@@ -126,11 +126,11 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m
|
126
|
126
|
// Get a new directory object using the full path
|
127
|
127
|
// and dive recursively into it.
|
128
|
128
|
SdFile dir;
|
129
|
|
- if (!dir.open(parent, lfilename, O_READ)) {
|
|
129
|
+ if (!dir.open(&parent, dosFilename, O_READ)) {
|
130
|
130
|
if (lsAction == LS_SerialPrint) {
|
131
|
131
|
SERIAL_ECHO_START_P(port);
|
132
|
132
|
SERIAL_ECHOPGM_P(port, MSG_SD_CANT_OPEN_SUBDIR);
|
133
|
|
- SERIAL_ECHOLN_P(port, lfilename);
|
|
133
|
+ SERIAL_ECHOLN_P(port, dosFilename);
|
134
|
134
|
}
|
135
|
135
|
}
|
136
|
136
|
lsDive(path, dir
|
|
@@ -246,7 +246,7 @@ void CardReader::ls(
|
246
|
246
|
|
247
|
247
|
// Open the sub-item as the new dive parent
|
248
|
248
|
SdFile dir;
|
249
|
|
- if (!dir.open(diveDir, segment, O_READ)) {
|
|
249
|
+ if (!dir.open(&diveDir, segment, O_READ)) {
|
250
|
250
|
SERIAL_EOL_P(port);
|
251
|
251
|
SERIAL_ECHO_START_P(port);
|
252
|
252
|
SERIAL_ECHOPGM_P(port, MSG_SD_CANT_OPEN_SUBDIR);
|
|
@@ -273,11 +273,11 @@ void CardReader::printFilename(
|
273
|
273
|
#endif
|
274
|
274
|
) {
|
275
|
275
|
if (file.isOpen()) {
|
276
|
|
- char lfilename[FILENAME_LENGTH];
|
277
|
|
- file.getFilename(lfilename);
|
278
|
|
- SERIAL_ECHO_P(port, lfilename);
|
|
276
|
+ char dosFilename[FILENAME_LENGTH];
|
|
277
|
+ file.getFilename(dosFilename);
|
|
278
|
+ SERIAL_ECHO_P(port, dosFilename);
|
279
|
279
|
#if ENABLED(LONG_FILENAME_HOST_SUPPORT)
|
280
|
|
- getfilename(0, lfilename);
|
|
280
|
+ getfilename(0, dosFilename);
|
281
|
281
|
if (longFilename[0]) {
|
282
|
282
|
SERIAL_ECHO_P(port, ' ');
|
283
|
283
|
SERIAL_ECHO_P(port, longFilename);
|
|
@@ -298,16 +298,16 @@ void CardReader::initsd() {
|
298
|
298
|
#define SPI_SPEED SPI_FULL_SPEED
|
299
|
299
|
#endif
|
300
|
300
|
|
301
|
|
- if (!card.init(SPI_SPEED, SDSS)
|
|
301
|
+ if (!sd2card.init(SPI_SPEED, SDSS)
|
302
|
302
|
#if defined(LCD_SDSS) && (LCD_SDSS != SDSS)
|
303
|
|
- && !card.init(SPI_SPEED, LCD_SDSS)
|
|
303
|
+ && !sd2card.init(SPI_SPEED, LCD_SDSS)
|
304
|
304
|
#endif
|
305
|
305
|
) {
|
306
|
|
- //if (!card.init(SPI_HALF_SPEED,SDSS))
|
|
306
|
+ //if (!sd2card.init(SPI_HALF_SPEED,SDSS))
|
307
|
307
|
SERIAL_ECHO_START();
|
308
|
308
|
SERIAL_ECHOLNPGM(MSG_SD_INIT_FAIL);
|
309
|
309
|
}
|
310
|
|
- else if (!volume.init(&card)) {
|
|
310
|
+ else if (!volume.init(&sd2card)) {
|
311
|
311
|
SERIAL_ERROR_START();
|
312
|
312
|
SERIAL_ERRORLNPGM(MSG_SD_VOL_INIT_FAIL);
|
313
|
313
|
}
|
|
@@ -323,17 +323,6 @@ void CardReader::initsd() {
|
323
|
323
|
setroot();
|
324
|
324
|
}
|
325
|
325
|
|
326
|
|
-void CardReader::setroot() {
|
327
|
|
- /*if (!workDir.openRoot(&volume)) {
|
328
|
|
- SERIAL_ECHOLNPGM(MSG_SD_WORKDIR_FAIL);
|
329
|
|
- }*/
|
330
|
|
- workDir = root;
|
331
|
|
- curDir = &workDir;
|
332
|
|
- #if ENABLED(SDCARD_SORT_ALPHA)
|
333
|
|
- presort();
|
334
|
|
- #endif
|
335
|
|
-}
|
336
|
|
-
|
337
|
326
|
void CardReader::release() {
|
338
|
327
|
sdprinting = false;
|
339
|
328
|
cardOK = false;
|
|
@@ -371,9 +360,9 @@ void CardReader::stopSDPrint(
|
371
|
360
|
#endif
|
372
|
361
|
}
|
373
|
362
|
|
374
|
|
-void CardReader::openLogFile(char* name) {
|
|
363
|
+void CardReader::openLogFile(char * const path) {
|
375
|
364
|
logging = true;
|
376
|
|
- openFile(name, false);
|
|
365
|
+ openFile(path, false);
|
377
|
366
|
}
|
378
|
367
|
|
379
|
368
|
void appendAtom(SdFile &file, char *& dst, uint8_t &cnt) {
|
|
@@ -396,7 +385,7 @@ void CardReader::getAbsFilename(char *t) {
|
396
|
385
|
*t = '\0';
|
397
|
386
|
}
|
398
|
387
|
|
399
|
|
-void CardReader::openFile(char* name, const bool read, const bool subcall/*=false*/) {
|
|
388
|
+void CardReader::openFile(char * const path, const bool read, const bool subcall/*=false*/) {
|
400
|
389
|
|
401
|
390
|
if (!cardOK) return;
|
402
|
391
|
|
|
@@ -416,7 +405,7 @@ void CardReader::openFile(char* name, const bool read, const bool subcall/*=fals
|
416
|
405
|
filespos[file_subcall_ctr] = sdpos;
|
417
|
406
|
|
418
|
407
|
SERIAL_ECHO_START();
|
419
|
|
- SERIAL_ECHOPAIR("SUBROUTINE CALL target:\"", name);
|
|
408
|
+ SERIAL_ECHOPAIR("SUBROUTINE CALL target:\"", path);
|
420
|
409
|
SERIAL_ECHOPAIR("\" parent:\"", proc_filenames[file_subcall_ctr]);
|
421
|
410
|
SERIAL_ECHOLNPAIR("\" pos", sdpos);
|
422
|
411
|
file_subcall_ctr++;
|
|
@@ -437,49 +426,14 @@ void CardReader::openFile(char* name, const bool read, const bool subcall/*=fals
|
437
|
426
|
SERIAL_ECHO_START();
|
438
|
427
|
SERIAL_ECHOPGM("Now ");
|
439
|
428
|
serialprintPGM(doing == 1 ? PSTR("doing") : PSTR("fresh"));
|
440
|
|
- SERIAL_ECHOLNPAIR(" file: ", name);
|
|
429
|
+ SERIAL_ECHOLNPAIR(" file: ", path);
|
441
|
430
|
}
|
442
|
431
|
|
443
|
432
|
stopSDPrint();
|
444
|
433
|
|
445
|
|
- SdFile myDir;
|
446
|
|
- curDir = &root;
|
447
|
|
- char *fname = name;
|
448
|
|
- char *dirname_start, *dirname_end;
|
449
|
|
-
|
450
|
|
- if (name[0] == '/') {
|
451
|
|
- dirname_start = &name[1];
|
452
|
|
- while (dirname_start != NULL) {
|
453
|
|
- dirname_end = strchr(dirname_start, '/');
|
454
|
|
- //SERIAL_ECHOPGM("start:");SERIAL_ECHOLN((int)(dirname_start - name));
|
455
|
|
- //SERIAL_ECHOPGM("end :");SERIAL_ECHOLN((int)(dirname_end - name));
|
456
|
|
- if (dirname_end != NULL && dirname_end > dirname_start) {
|
457
|
|
- char subdirname[FILENAME_LENGTH];
|
458
|
|
- strncpy(subdirname, dirname_start, dirname_end - dirname_start);
|
459
|
|
- subdirname[dirname_end - dirname_start] = '\0';
|
460
|
|
- if (!myDir.open(curDir, subdirname, O_READ)) {
|
461
|
|
- SERIAL_PROTOCOLPGM(MSG_SD_OPEN_FILE_FAIL);
|
462
|
|
- SERIAL_PROTOCOL(subdirname);
|
463
|
|
- SERIAL_PROTOCOLCHAR('.');
|
464
|
|
- return;
|
465
|
|
- }
|
466
|
|
- else {
|
467
|
|
- //SERIAL_ECHOLNPGM("dive ok");
|
468
|
|
- }
|
469
|
|
-
|
470
|
|
- curDir = &myDir;
|
471
|
|
- dirname_start = dirname_end + 1;
|
472
|
|
- }
|
473
|
|
- else { // the remainder after all /fsa/fdsa/ is the filename
|
474
|
|
- fname = dirname_start;
|
475
|
|
- //SERIAL_ECHOLNPGM("remainder");
|
476
|
|
- //SERIAL_ECHOLN(fname);
|
477
|
|
- break;
|
478
|
|
- }
|
479
|
|
- }
|
480
|
|
- }
|
481
|
|
- else
|
482
|
|
- curDir = &workDir; // Relative paths start in current directory
|
|
434
|
+ SdFile *curDir;
|
|
435
|
+ const char * const fname = diveToFile(curDir, path, false);
|
|
436
|
+ if (!fname) return;
|
483
|
437
|
|
484
|
438
|
if (read) {
|
485
|
439
|
if (file.open(curDir, fname, O_READ)) {
|
|
@@ -509,7 +463,7 @@ void CardReader::openFile(char* name, const bool read, const bool subcall/*=fals
|
509
|
463
|
}
|
510
|
464
|
else {
|
511
|
465
|
saving = true;
|
512
|
|
- SERIAL_PROTOCOLLNPAIR(MSG_SD_WRITE_TO_FILE, name);
|
|
466
|
+ SERIAL_PROTOCOLLNPAIR(MSG_SD_WRITE_TO_FILE, path);
|
513
|
467
|
lcd_setstatus(fname);
|
514
|
468
|
}
|
515
|
469
|
}
|
|
@@ -520,40 +474,9 @@ void CardReader::removeFile(const char * const name) {
|
520
|
474
|
|
521
|
475
|
stopSDPrint();
|
522
|
476
|
|
523
|
|
- SdFile myDir;
|
524
|
|
- curDir = &root;
|
525
|
|
- const char *fname = name;
|
526
|
|
-
|
527
|
|
- char *dirname_start, *dirname_end;
|
528
|
|
- if (name[0] == '/') {
|
529
|
|
- dirname_start = strchr(name, '/') + 1;
|
530
|
|
- while (dirname_start != NULL) {
|
531
|
|
- dirname_end = strchr(dirname_start, '/');
|
532
|
|
- //SERIAL_ECHOPGM("start:");SERIAL_ECHOLN((int)(dirname_start - name));
|
533
|
|
- //SERIAL_ECHOPGM("end :");SERIAL_ECHOLN((int)(dirname_end - name));
|
534
|
|
- if (dirname_end != NULL && dirname_end > dirname_start) {
|
535
|
|
- char subdirname[FILENAME_LENGTH];
|
536
|
|
- strncpy(subdirname, dirname_start, dirname_end - dirname_start);
|
537
|
|
- subdirname[dirname_end - dirname_start] = 0;
|
538
|
|
- SERIAL_ECHOLN(subdirname);
|
539
|
|
- if (!myDir.open(curDir, subdirname, O_READ)) {
|
540
|
|
- SERIAL_PROTOCOLPAIR(MSG_SD_OPEN_FILE_FAIL, subdirname);
|
541
|
|
- SERIAL_PROTOCOLCHAR('.');
|
542
|
|
- SERIAL_EOL();
|
543
|
|
- return;
|
544
|
|
- }
|
545
|
|
-
|
546
|
|
- curDir = &myDir;
|
547
|
|
- dirname_start = dirname_end + 1;
|
548
|
|
- }
|
549
|
|
- else {
|
550
|
|
- fname = dirname_start;
|
551
|
|
- break;
|
552
|
|
- }
|
553
|
|
- }
|
554
|
|
- }
|
555
|
|
- else // Relative paths are rooted in the current directory
|
556
|
|
- curDir = &workDir;
|
|
477
|
+ SdFile *curDir;
|
|
478
|
+ const char * const fname = diveToFile(curDir, name, false);
|
|
479
|
+ if (!fname) return;
|
557
|
480
|
|
558
|
481
|
if (file.remove(curDir, fname)) {
|
559
|
482
|
SERIAL_PROTOCOLPGM("File deleted:");
|
|
@@ -623,7 +546,7 @@ void CardReader::checkautostart() {
|
623
|
546
|
sprintf_P(autoname, PSTR("auto%i.g"), autostart_index);
|
624
|
547
|
dir_t p;
|
625
|
548
|
root.rewind();
|
626
|
|
- while (root.readDir(p, NULL) > 0) {
|
|
549
|
+ while (root.readDir(&p, NULL) > 0) {
|
627
|
550
|
for (int8_t i = (int8_t)strlen((char*)p.name); i--;) p.name[i] = tolower(p.name[i]);
|
628
|
551
|
if (p.name[9] != '~' && strncmp((char*)p.name, autoname, 5) == 0) {
|
629
|
552
|
openAndPrintFile(autoname);
|
|
@@ -653,6 +576,7 @@ void CardReader::closefile(const bool store_location) {
|
653
|
576
|
|
654
|
577
|
/**
|
655
|
578
|
* Get the name of a file in the current directory by index
|
|
579
|
+ * with optional name to match.
|
656
|
580
|
*/
|
657
|
581
|
void CardReader::getfilename(uint16_t nr, const char * const match/*=NULL*/) {
|
658
|
582
|
#if ENABLED(SDSORT_CACHE_NAMES)
|
|
@@ -669,35 +593,60 @@ void CardReader::getfilename(uint16_t nr, const char * const match/*=NULL*/) {
|
669
|
593
|
return;
|
670
|
594
|
}
|
671
|
595
|
#endif // SDSORT_CACHE_NAMES
|
672
|
|
- curDir = &workDir;
|
673
|
596
|
lsAction = LS_GetFilename;
|
674
|
597
|
nrFile_index = nr;
|
675
|
|
- curDir->rewind();
|
676
|
|
- lsDive(NULL, *curDir, match);
|
|
598
|
+ workDir.rewind();
|
|
599
|
+ lsDive(NULL, workDir, match);
|
677
|
600
|
}
|
678
|
601
|
|
679
|
602
|
uint16_t CardReader::getnrfilenames() {
|
680
|
|
- curDir = &workDir;
|
681
|
603
|
lsAction = LS_Count;
|
682
|
604
|
nrFiles = 0;
|
683
|
|
- curDir->rewind();
|
684
|
|
- lsDive(NULL, *curDir);
|
|
605
|
+ workDir.rewind();
|
|
606
|
+ lsDive(NULL, workDir);
|
685
|
607
|
//SERIAL_ECHOLN(nrFiles);
|
686
|
608
|
return nrFiles;
|
687
|
609
|
}
|
688
|
610
|
|
689
|
|
-void CardReader::chdir(const char * relpath) {
|
690
|
|
- SdFile newDir;
|
691
|
|
- SdFile *parent = &root;
|
|
611
|
+/**
|
|
612
|
+ * Dive to the given file path, with optional echo.
|
|
613
|
+ * On exit set curDir and return the name part of the path.
|
|
614
|
+ * A NULL result indicates an unrecoverable error.
|
|
615
|
+ */
|
|
616
|
+const char* CardReader::diveToFile(SdFile*& curDir, const char * const path, const bool echo) {
|
|
617
|
+ SdFile myDir;
|
|
618
|
+ if (path[0] != '/') { curDir = &workDir; return path; }
|
692
|
619
|
|
693
|
|
- if (workDir.isOpen()) parent = &workDir;
|
|
620
|
+ curDir = &root;
|
|
621
|
+ const char *dirname_start = &path[1];
|
|
622
|
+ while (dirname_start) {
|
|
623
|
+ char * const dirname_end = strchr(dirname_start, '/');
|
|
624
|
+ if (dirname_end <= dirname_start) break;
|
694
|
625
|
|
695
|
|
- if (!newDir.open(*parent, relpath, O_READ)) {
|
696
|
|
- SERIAL_ECHO_START();
|
697
|
|
- SERIAL_ECHOPGM(MSG_SD_CANT_ENTER_SUBDIR);
|
698
|
|
- SERIAL_ECHOLN(relpath);
|
|
626
|
+ char dosSubdirname[FILENAME_LENGTH];
|
|
627
|
+ const uint8_t len = dirname_end - dirname_start;
|
|
628
|
+ strncpy(dosSubdirname, dirname_start, len);
|
|
629
|
+ dosSubdirname[len] = 0;
|
|
630
|
+
|
|
631
|
+ if (echo) SERIAL_ECHOLN(dosSubdirname);
|
|
632
|
+
|
|
633
|
+ if (!myDir.open(curDir, dosSubdirname, O_READ)) {
|
|
634
|
+ SERIAL_PROTOCOLPAIR(MSG_SD_OPEN_FILE_FAIL, dosSubdirname);
|
|
635
|
+ SERIAL_PROTOCOLCHAR('.');
|
|
636
|
+ SERIAL_EOL();
|
|
637
|
+ return NULL;
|
|
638
|
+ }
|
|
639
|
+ curDir = &myDir;
|
|
640
|
+ dirname_start = dirname_end + 1;
|
699
|
641
|
}
|
700
|
|
- else {
|
|
642
|
+ return dirname_start;
|
|
643
|
+}
|
|
644
|
+
|
|
645
|
+void CardReader::chdir(const char * relpath) {
|
|
646
|
+ SdFile newDir;
|
|
647
|
+ SdFile *parent = workDir.isOpen() ? &workDir : &root;
|
|
648
|
+
|
|
649
|
+ if (newDir.open(parent, relpath, O_READ)) {
|
701
|
650
|
workDir = newDir;
|
702
|
651
|
if (workDirDepth < MAX_DIR_DEPTH)
|
703
|
652
|
workDirParents[workDirDepth++] = workDir;
|
|
@@ -705,6 +654,11 @@ void CardReader::chdir(const char * relpath) {
|
705
|
654
|
presort();
|
706
|
655
|
#endif
|
707
|
656
|
}
|
|
657
|
+ else {
|
|
658
|
+ SERIAL_ECHO_START();
|
|
659
|
+ SERIAL_ECHOPGM(MSG_SD_CANT_ENTER_SUBDIR);
|
|
660
|
+ SERIAL_ECHOLN(relpath);
|
|
661
|
+ }
|
708
|
662
|
}
|
709
|
663
|
|
710
|
664
|
int8_t CardReader::updir() {
|
|
@@ -717,6 +671,16 @@ int8_t CardReader::updir() {
|
717
|
671
|
return workDirDepth;
|
718
|
672
|
}
|
719
|
673
|
|
|
674
|
+void CardReader::setroot() {
|
|
675
|
+ /*if (!workDir.openRoot(&volume)) {
|
|
676
|
+ SERIAL_ECHOLNPGM(MSG_SD_WORKDIR_FAIL);
|
|
677
|
+ }*/
|
|
678
|
+ workDir = root;
|
|
679
|
+ #if ENABLED(SDCARD_SORT_ALPHA)
|
|
680
|
+ presort();
|
|
681
|
+ #endif
|
|
682
|
+}
|
|
683
|
+
|
720
|
684
|
#if ENABLED(SDCARD_SORT_ALPHA)
|
721
|
685
|
|
722
|
686
|
/**
|