Added support for ls wildcards. Issue 135 fixed.

Fixed issue #135: ls with wildcard works again. Thank you dlkeng!
This commit is contained in:
Nathan Seidle 2013-04-08 17:19:44 -06:00
parent 1888d3df36
commit 50ee63bc0e

View File

@ -151,6 +151,8 @@
Added support for newlines when using the 'write' command. Added support for newlines when using the 'write' command.
Should fix issue #149. Should fix issue #149.
Fixed issue #135: When removing files and there is a directory, all wildcard files are now removed correctly.
*/ */
#include <SdFat.h> //We do not use the built-in SD.h file because it calls Serial.print #include <SdFat.h> //We do not use the built-in SD.h file because it calls Serial.print
@ -1168,10 +1170,20 @@ void command_shell(void)
NewSerial.println(volume.fatType(), DEC); NewSerial.println(volume.fatType(), DEC);
} }
//ERROR if (count_cmd_args() == 1) // has no arguments
// currentDirectory.ls(LS_SIZE, 0, &wildcmp, get_cmd_arg(1)); {
currentDirectory.ls(LS_SIZE | LS_R); // Don't use the 'ls()' method in the SdFat library as it does not
NewSerial.println(F("Wild card ls not yet supported")); // limit recursion into subdirectories.
command_arg[0] = '*'; // use global wildcard
command_arg[1] = '\0';
}
else // has argument (and possible wildcards)
{
command_arg = get_cmd_arg(1);
strupr(command_arg);
}
// display listing with limited recursion into subdirectories
lsPrint(&currentDirectory, command_arg, LS_SIZE | LS_R, 0);
#ifdef INCLUDE_SIMPLE_EMBEDDED #ifdef INCLUDE_SIMPLE_EMBEDDED
command_succedded = 1; command_succedded = 1;
@ -1255,7 +1267,8 @@ void command_shell(void)
strupr(command_arg); strupr(command_arg);
currentDirectory.rewind(); currentDirectory.rewind();
while (tempFile.openNext(&currentDirectory, O_READ)) //Step through each object in the current directory { while (tempFile.openNext(&currentDirectory, O_READ)) //Step through each object in the current directory
{
if (!tempFile.isDir() && !tempFile.isSubDir()) // Remove only files if (!tempFile.isDir() && !tempFile.isSubDir()) // Remove only files
{ {
if (tempFile.getFilename(fname)) // Get the filename of the object we're looking at if (tempFile.getFilename(fname)) // Get the filename of the object we're looking at
@ -2238,3 +2251,165 @@ byte wildcmp(const char* wild, const char* string)
//End wildcard functions //End wildcard functions
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//------------------------------------------------------------------------------
// Listing functions
// - Modeled loosely on the ls() methods in SdBaseFile.cpp from the SdFat library.
// Written by dlkeng in relation to issue 135 https://github.com/sparkfun/OpenLog/issues/135
#define WAS_EOF 0
#define WAS_FILE 1
#define WAS_SUBDIR 2
#define FILENAME_EXT_SIZE 13
#define LS_FIELD_SIZE (FILENAME_EXT_SIZE + 1)
#define SUBDIR_INDENT 2
#define DIR_SIZE (sizeof(dir_t))
/*
* NAME:
* void lsPrint(SdFile * theDir, char * cmdStr, byte flags, byte indent)
*
* PARAMETERS:
* SdFile * theDir = the directory to list (assumed opened)
* char * cmdStr = the command line file/directory string (with possible wildcards)
* byte flags = the inclusive OR of
* LS_SIZE - print the file size
* LS_R - recursively list subdirectories
* byte indent = amount of space before file name
* (used for recursive list to indicate subdirectory level)
*
* WHAT:
* List directory contents to serial port.
*
* Wildcard support rules:
* Wildcard characters ('*', '?') only apply to the selection of filenames to
* list, not to the listing of directory or subdirectory names. All directory
* and subdirectory names are always listed.
*
* RETURN VALUES:
* None.
*
* SPECIAL CONSIDERATIONS:
* May be called recursively with limited recursion depth (see FOLDER_TRACK_DEPTH).
* Each recursion uses ~50 bytes of RAM.
*/
void lsPrint(SdFile * theDir, char * cmdStr, byte flags, byte indent)
{
static byte depth = 0; // current recursion depth
byte status;
uint16_t index;
SdFile subdir;
theDir->rewind();
while ((status = lsPrintNext(theDir, cmdStr, flags, indent)))
{
if ((status == WAS_SUBDIR) && (flags & LS_R) && (depth < FOLDER_TRACK_DEPTH))
{
// was a subdirectory, recursion allowed, recursion depth OK
index = (theDir->curPosition() / DIR_SIZE) - 1; // determine current directory entry index
if (subdir.open(theDir, index, O_READ))
{
++depth; // limit recursion
lsPrint(&subdir, cmdStr, flags, indent + SUBDIR_INDENT); // recursively list subdirectory
--depth;
subdir.close();
}
}
}
}
/*
* NAME:
* void lsPrintNext(SdFile * theDir, char * cmdStr, byte flags, byte indent)
*
* PARAMETERS:
* SdFile * theDir = the directory to list (assumed opened)
* char * cmdStr = the command line file/directory string (with possible wildcards)
* byte flags = the inclusive OR of
* LS_SIZE - print the file size
* LS_R - recursively list subdirectories
* byte indent = amount of space before file name
* (used for recursive list to indicate subdirectory level)
*
* WHAT:
* List directory's next contents to serial port.
*
* Wildcard support rules:
* Wildcard characters ('*', '?') only apply to the selection of filenames to
* list, not to the listing of directory or subdirectory names. All directory
* and subdirectory names are always listed.
*
* RETURN VALUES:
* byte = WAS_EOF - EOF, WAS_FILE - normal file, or WAS_SUBDIR - subdirectory
*
* SPECIAL CONSIDERATIONS:
* None.
*/
byte lsPrintNext(SdFile * theDir, char * cmdStr, byte flags, byte indent)
{
byte pos = 0; // output position
byte open_stat; // file open status
byte status; // return status
SdFile tempFile;
char fname[FILENAME_EXT_SIZE];
// Find next available object to display in the specified directory
while ((open_stat = tempFile.openNext(theDir, O_READ)))
{
if (tempFile.getFilename(fname)) // Get the filename of the object we're looking at
{
if (tempFile.isDir() || tempFile.isFile() || tempFile.isSubDir())
{
if (tempFile.isFile()) // wildcards only apply to files
{
if (wildcmp(cmdStr, fname)) // see if it matches the wildcard
{
status = WAS_FILE;
break; // is a matching file name, display it
}
// else skip it
}
else // is a subdirectory
{
status = WAS_SUBDIR;
break; // display subdirectory name
}
}
}
tempFile.close();
}
if (!open_stat)
{
return WAS_EOF; // nothing more in this (sub)directory
}
// output the file or directory name
// indent for dir level
for (byte i = 0; i < indent; i++)
{
NewSerial.write(' ');
}
// print name
pos += NewSerial.print(fname);
if (tempFile.isSubDir())
{
pos += NewSerial.write('/'); // subdirectory indicator
}
// print size if requested (files only)
if (tempFile.isFile() && (flags & LS_SIZE))
{
while (pos++ < LS_FIELD_SIZE)
{
NewSerial.write(' ');
}
NewSerial.write(' '); // ensure at least 1 separating space
NewSerial.print(tempFile.fileSize());
}
NewSerial.writeln();
tempFile.close();
return status;
}