1
1
Fork 0
mirror of https://github.com/QB64-Phoenix-Edition/QB64pe.git synced 2024-07-04 04:50:22 +00:00

Update sub_kill() to handle file spec without wildcard correctly

This commit is contained in:
Samuel Gomes 2023-12-11 16:17:53 +05:30
parent 07c8554f89
commit 3604a7a7f7

View file

@ -25,8 +25,6 @@
#define PATHNAME_LENGTH_MAX (FILENAME_MAX << 4)
#define IS_STRING_EMPTY(_s_) ((_s_) == nullptr || (_s_)[0] == 0)
/// @brief Gets the current working directory
/// @return A qbs containing the current working directory or an empty string on error
qbs *func__cwd() {
@ -375,6 +373,11 @@ void sub_chdir(qbs *str) {
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()
/// @param fileSpec The pattern 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;
}
/// @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
/// @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
@ -426,7 +434,7 @@ static const char *Dir64(const char *fileSpec) {
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
if (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()
if (strchr(fileSpec, '*') || strchr(fileSpec, '?')) {
if (Dir64_HasPattern(fileSpec)) {
// We have a pattern. Check if we have a path in it
auto p = strrchr(fileSpec, '/'); // try *nix style separator
#ifdef QB64_WINDOWS
@ -619,7 +627,7 @@ void sub_files(qbs *str, int32 passed) {
/// @brief Deletes files from disk
/// @param str The file(s) to delete (may contain wildcard at the final level)
void sub_kill(qbs *str) {
if (new_error || !str->len)
if (new_error)
return;
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)));
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)) {
// We'll delete only if it is a file
if (FileExists(entry)) {
if (remove(entry)) {
auto i = errno;
// Keep looking through the entries until we file a file matching the spec
while (!IsStringEmpty(entry)) {
if (FileExists(entry))
break;
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
}
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)
}
}
}