mirror of
https://github.com/QB64-Phoenix-Edition/QB64pe.git
synced 2024-07-06 19:50:22 +00:00
Update sub_kill() to handle file spec without wildcard correctly
This commit is contained in:
parent
07c8554f89
commit
3604a7a7f7
|
@ -25,8 +25,6 @@
|
||||||
|
|
||||||
#define PATHNAME_LENGTH_MAX (FILENAME_MAX << 4)
|
#define PATHNAME_LENGTH_MAX (FILENAME_MAX << 4)
|
||||||
|
|
||||||
#define IS_STRING_EMPTY(_s_) ((_s_) == nullptr || (_s_)[0] == 0)
|
|
||||||
|
|
||||||
/// @brief Gets the current working directory
|
/// @brief Gets the current working directory
|
||||||
/// @return A qbs containing the current working directory or an empty string on error
|
/// @return A qbs containing the current working directory or an empty string on error
|
||||||
qbs *func__cwd() {
|
qbs *func__cwd() {
|
||||||
|
@ -375,6 +373,11 @@ void sub_chdir(qbs *str) {
|
||||||
error(76); // assume errno == ENOENT; path not found
|
error(76); // assume errno == ENOENT; path not found
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Checks if s is an empty string (either NULL or zero length)
|
||||||
|
/// @param s A null-terminated string or NULL
|
||||||
|
/// @return False is we have a valid string > length 0
|
||||||
|
static inline bool IsStringEmpty(const char *s) { return s == nullptr || s[0] == '\0'; }
|
||||||
|
|
||||||
/// @brief This is a basic pattern matching function used by Dir64()
|
/// @brief This is a basic pattern matching function used by Dir64()
|
||||||
/// @param fileSpec The pattern to match
|
/// @param fileSpec The pattern to match
|
||||||
/// @param fileName The filename to match
|
/// @param fileName The filename to match
|
||||||
|
@ -416,6 +419,11 @@ static inline bool Dir64_MatchSpec(const char *fileSpec, const char *fileName) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Returns true if fileSpec has any wildcards
|
||||||
|
/// @param fileSpec The string to check
|
||||||
|
/// @return True if * or ? are found
|
||||||
|
static inline bool Dir64_HasPattern(const char *fileSpec) { return fileSpec != nullptr && (strchr(fileSpec, '*') || strchr(fileSpec, '?')); }
|
||||||
|
|
||||||
/// @brief An MS BASIC PDS DIR$ style function
|
/// @brief An MS BASIC PDS DIR$ style function
|
||||||
/// @param fileSpec This can be a directory with wildcard for the final level (i.e. C:/Windows/*.* or /usr/lib/* etc.)
|
/// @param fileSpec This can be a directory with wildcard for the final level (i.e. C:/Windows/*.* or /usr/lib/* etc.)
|
||||||
/// @return Returns a file or directory name matching fileSpec or an empty string when there is nothing left
|
/// @return Returns a file or directory name matching fileSpec or an empty string when there is nothing left
|
||||||
|
@ -426,7 +434,7 @@ static const char *Dir64(const char *fileSpec) {
|
||||||
|
|
||||||
entry[0] = '\0'; // set to an empty string
|
entry[0] = '\0'; // set to an empty string
|
||||||
|
|
||||||
if (!IS_STRING_EMPTY(fileSpec)) {
|
if (!IsStringEmpty(fileSpec)) {
|
||||||
// We got a filespec. Check if we have one already going and if so, close it
|
// We got a filespec. Check if we have one already going and if so, close it
|
||||||
if (pDir) {
|
if (pDir) {
|
||||||
closedir(pDir);
|
closedir(pDir);
|
||||||
|
@ -435,7 +443,7 @@ static const char *Dir64(const char *fileSpec) {
|
||||||
|
|
||||||
char dirName[PATHNAME_LENGTH_MAX]; // we only need this for opendir()
|
char dirName[PATHNAME_LENGTH_MAX]; // we only need this for opendir()
|
||||||
|
|
||||||
if (strchr(fileSpec, '*') || strchr(fileSpec, '?')) {
|
if (Dir64_HasPattern(fileSpec)) {
|
||||||
// We have a pattern. Check if we have a path in it
|
// We have a pattern. Check if we have a path in it
|
||||||
auto p = strrchr(fileSpec, '/'); // try *nix style separator
|
auto p = strrchr(fileSpec, '/'); // try *nix style separator
|
||||||
#ifdef QB64_WINDOWS
|
#ifdef QB64_WINDOWS
|
||||||
|
@ -619,7 +627,7 @@ void sub_files(qbs *str, int32 passed) {
|
||||||
/// @brief Deletes files from disk
|
/// @brief Deletes files from disk
|
||||||
/// @param str The file(s) to delete (may contain wildcard at the final level)
|
/// @param str The file(s) to delete (may contain wildcard at the final level)
|
||||||
void sub_kill(qbs *str) {
|
void sub_kill(qbs *str) {
|
||||||
if (new_error || !str->len)
|
if (new_error)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
static qbs *strz = nullptr;
|
static qbs *strz = nullptr;
|
||||||
|
@ -629,29 +637,65 @@ void sub_kill(qbs *str) {
|
||||||
|
|
||||||
qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1)));
|
qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1)));
|
||||||
|
|
||||||
auto entry = Dir64(filepath_fix_directory(strz)); // get the first entry
|
if (Dir64_HasPattern(filepath_fix_directory(strz))) {
|
||||||
|
// We have wildcards. So, we'll deal with it appropriately
|
||||||
|
auto entry = Dir64(reinterpret_cast<char *>(strz->chr)); // get the first entry
|
||||||
|
|
||||||
while (!IS_STRING_EMPTY(entry)) {
|
// Keep looking through the entries until we file a file matching the spec
|
||||||
// We'll delete only if it is a file
|
while (!IsStringEmpty(entry)) {
|
||||||
if (FileExists(entry)) {
|
if (FileExists(entry))
|
||||||
if (remove(entry)) {
|
break;
|
||||||
auto i = errno;
|
|
||||||
|
|
||||||
if (i == ENOENT) {
|
entry = Dir64(nullptr); // get the next entry
|
||||||
error(53);
|
|
||||||
return;
|
|
||||||
} // file not found
|
|
||||||
|
|
||||||
if (i == EACCES) {
|
|
||||||
error(75);
|
|
||||||
return;
|
|
||||||
} // path / file access error
|
|
||||||
|
|
||||||
error(64); // bad file name (assumed)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entry = Dir64(nullptr); // get the next entry
|
// Check if we have exhausted the entries without ever finding a match
|
||||||
|
if (IsStringEmpty(entry)) {
|
||||||
|
// This behavior is per QBasic
|
||||||
|
error(53);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the remaining matches
|
||||||
|
while (!IsStringEmpty(entry)) {
|
||||||
|
// We'll delete only if it is a file
|
||||||
|
if (FileExists(entry)) {
|
||||||
|
if (remove(entry)) {
|
||||||
|
auto i = errno;
|
||||||
|
|
||||||
|
if (i == ENOENT) {
|
||||||
|
error(53);
|
||||||
|
return;
|
||||||
|
} // file not found
|
||||||
|
|
||||||
|
if (i == EACCES) {
|
||||||
|
error(75);
|
||||||
|
return;
|
||||||
|
} // path / file access error
|
||||||
|
|
||||||
|
error(64); // bad file name (assumed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = Dir64(nullptr); // get the next entry
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No wildcards
|
||||||
|
if (remove(reinterpret_cast<char *>(strz->chr))) {
|
||||||
|
auto i = errno;
|
||||||
|
|
||||||
|
if (i == ENOENT) {
|
||||||
|
error(53);
|
||||||
|
return;
|
||||||
|
} // file not found
|
||||||
|
|
||||||
|
if (i == EACCES) {
|
||||||
|
error(75);
|
||||||
|
return;
|
||||||
|
} // path / file access error
|
||||||
|
|
||||||
|
error(64); // bad file name (assumed)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue