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

Consolidate all filesystem related functions to it's own translation unit

This commit is contained in:
Samuel Gomes 2023-12-10 01:16:29 +05:30
parent 79d48113f2
commit 0e251eb8e8
8 changed files with 635 additions and 608 deletions

View file

@ -21,6 +21,8 @@
#include "compression.h"
#include "datetime.h"
#include "event.h"
#include "filepath.h"
#include "filesystem.h"
#include "font.h"
#include "game_controller.h"
#include "glut-thread.h"
@ -3946,23 +3948,6 @@ int32 exit_value = 0;
void error(int32 error_number); // for forward references
char *fixdir(qbs *filename) {
// note: changes the slashes in a filename to make it compatible with the OS
// applied to QB commands: open, bload/bsave, loadfont, loadimage, sndopen/sndplayfile
static int32 i;
for (i = 0; i < filename->len; i++) {
#ifdef QB64_WINDOWS
if (filename->chr[i] == 47)
filename->chr[i] = 92;
#else
if (filename->chr[i] == 92)
filename->chr[i] = 47;
#endif
}
return (char *)filename->chr;
}
int32 width8050switch = 1; // if set, can automatically switch to WIDTH 80,50 if LOCATE'ing beyond row 26
uint32 pal[256];
@ -23022,166 +23007,6 @@ shell_complete:;
} //_DONTWAIT & _HIDE
void sub_kill(qbs *str) {
// note: file not found returned for non-existant paths too
// file already open returned if access unavailable
if (new_error)
return;
static int32 i;
static qbs *strz = NULL;
if (!strz)
strz = qbs_new(0, 0);
qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1)));
#ifdef QB64_WINDOWS
static WIN32_FIND_DATA fd;
static HANDLE hFind;
static qbs *strpath = NULL;
if (!strpath)
strpath = qbs_new(0, 0);
static qbs *strfullz = NULL;
if (!strfullz)
strfullz = qbs_new(0, 0);
// find path
qbs_set(strpath, strz);
for (i = strpath->len; i > 0; i--) {
if ((strpath->chr[i - 1] == 47) || (strpath->chr[i - 1] == 92)) {
strpath->len = i;
break;
}
} // i
if (i == 0)
strpath->len = 0; // no path specified
static int32 count;
count = 0;
hFind = FindFirstFile(fixdir(strz), &fd);
if (hFind == INVALID_HANDLE_VALUE) {
error(53);
return;
} // file not found
do {
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
qbs_set(strfullz, qbs_add(strpath, qbs_new_txt_len(fd.cFileName, strlen(fd.cFileName) + 1)));
if (!DeleteFile((char *)strfullz->chr)) {
i = GetLastError();
if ((i == 5) || (i == 19) || (i == 33) || (i == 32)) {
FindClose(hFind);
error(55);
return;
} // file already open
FindClose(hFind);
error(53);
return; // file not found
}
count++;
} // not a directory
} while (FindNextFile(hFind, &fd));
FindClose(hFind);
if (!count) {
error(53);
return;
} // file not found
return;
#else
if (remove(fixdir(strz))) {
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)
}
#endif
}
void sub_name(qbs *oldname, qbs *newname) {
if (new_error)
return;
static qbs *strz = NULL;
if (!strz)
strz = qbs_new(0, 0);
static qbs *strz2 = NULL;
if (!strz2)
strz2 = qbs_new(0, 0);
static int32 i;
qbs_set(strz, qbs_add(oldname, qbs_new_txt_len("\0", 1)));
qbs_set(strz2, qbs_add(newname, qbs_new_txt_len("\0", 1)));
if (rename(fixdir(strz), fixdir(strz2))) {
i = errno;
if (i == ENOENT) {
error(53);
return;
} // file not found
if (i == EINVAL) {
error(64);
return;
} // bad file name
if (i == EACCES) {
error(75);
return;
} // path/file access error
error(5); // Illegal function call (assumed)
}
}
void sub_chdir(qbs *str) {
if (new_error)
return;
static qbs *strz = NULL;
if (!strz)
strz = qbs_new(0, 0);
qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1)));
if (chdir(fixdir(strz)) == -1) {
// assume errno==ENOENT
error(76); // path not found
}
static int32 tmp_long;
static int32 got_ports = 0;
}
void sub_mkdir(qbs *str) {
if (new_error)
return;
static qbs *strz = NULL;
if (!strz)
strz = qbs_new(0, 0);
qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1)));
#ifdef QB64_UNIX
if (mkdir(fixdir(strz), 0770) == -1) {
#else
if (mkdir(fixdir(strz)) == -1) {
#endif
if (errno == EEXIST) {
error(75);
return;
} // path/file access error
// assume errno==ENOENT
error(76); // path not found
}
}
void sub_rmdir(qbs *str) {
if (new_error)
return;
static qbs *strz = NULL;
if (!strz)
strz = qbs_new(0, 0);
qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1)));
if (rmdir(fixdir(strz)) == -1) {
if (errno == ENOTEMPTY) {
error(75);
return;
} // path/file access error
// assume errno==ENOENT
error(76); // path not found
}
}
long double pow2(long double x, long double y) {
if (x < 0) {
if (y != std::floor(y)) {
@ -31669,134 +31494,6 @@ failed:;
#endif
void sub_files(qbs *str, int32 passed) {
if (new_error)
return;
static int32 i, i2, i3;
static qbs *strz = NULL;
if (!strz)
strz = qbs_new(0, 0);
if (passed) {
qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1)));
} else {
qbs_set(strz, qbs_new_txt_len("\0", 1));
}
#ifdef QB64_WINDOWS
static WIN32_FIND_DATA fd;
static HANDLE hFind;
static qbs *strpath = NULL;
if (!strpath)
strpath = qbs_new(0, 0);
static qbs *strz2 = NULL;
if (!strz2)
strz2 = qbs_new(0, 0);
i = 0;
if (strz->len >= 2) {
if (strz->chr[strz->len - 2] == 92)
i = 1;
} else
i = 1;
if (i) { // add * (and new NULL term.)
strz->chr[strz->len - 1] = 42; //"*"
qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1)));
}
qbs_set(strpath, strz);
for (i = strpath->len; i > 0; i--) {
if ((strpath->chr[i - 1] == 47) || (strpath->chr[i - 1] == 92)) {
strpath->len = i;
break;
}
} // i
if (i == 0)
strpath->len = 0; // no path specified
// print the current path
// note: for QBASIC compatibility reasons it does not print the directory name of the files being displayed
static uint8 curdir[4096];
static uint8 curdir2[4096];
i2 = GetCurrentDirectory(4096, (char *)curdir);
if (i2) {
i2 = GetShortPathName((char *)curdir, (char *)curdir2, 4096);
if (i2) {
qbs_set(strz2, qbs_ucase(qbs_new_txt_len((char *)curdir2, i2)));
qbs_print(strz2, 1);
} else {
error(5);
return;
}
} else {
error(5);
return;
}
hFind = FindFirstFile(fixdir(strz), &fd);
if (hFind == INVALID_HANDLE_VALUE) {
error(53);
return;
} // file not found
do {
if (!fd.cAlternateFileName[0]) { // no alternate filename exists
qbs_set(strz2, qbs_ucase(qbs_new_txt_len(fd.cFileName, strlen(fd.cFileName))));
} else {
qbs_set(strz2, qbs_ucase(qbs_new_txt_len(fd.cAlternateFileName, strlen(fd.cAlternateFileName))));
}
if (strz2->len < 12) { // padding required
qbs_set(strz2, qbs_add(strz2, func_space(12 - strz2->len)));
i2 = 0;
for (i = 0; i < 12; i++) {
if (strz2->chr[i] == 46) {
memmove(&strz2->chr[8], &strz2->chr[i], 4);
memset(&strz2->chr[i], 32, 8 - i);
break;
}
} // i
} // padding
// add " " or "<DIR> "
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
qbs_set(strz2, qbs_add(strz2, qbs_new_txt_len("<DIR> ", 6)));
} else {
qbs_set(strz2, qbs_add(strz2, func_space(6)));
}
makefit(strz2);
qbs_print(strz2, 0);
} while (FindNextFile(hFind, &fd));
FindClose(hFind);
static ULARGE_INTEGER FreeBytesAvailableToCaller;
static ULARGE_INTEGER TotalNumberOfBytes;
static ULARGE_INTEGER TotalNumberOfFreeBytes;
static int64 bytes;
static char *cp;
qbs_set(strpath, qbs_add(strpath, qbs_new_txt_len("\0", 1)));
cp = (char *)strpath->chr;
if (strpath->len == 1)
cp = NULL;
if (GetDiskFreeSpaceEx(cp, &FreeBytesAvailableToCaller, &TotalNumberOfBytes, &TotalNumberOfFreeBytes)) {
bytes = *(int64 *)(void *)&FreeBytesAvailableToCaller;
} else {
bytes = 0;
}
if (func_pos(NULL) > 1) {
strz2->len = 0;
qbs_print(strz2, 1);
} // new line if necessary
qbs_set(strz2, qbs_add(qbs_str(bytes), qbs_new_txt_len(" Bytes free", 11)));
qbs_print(strz2, 1);
#endif
}
int32 func__keyhit() {
/*
//keyhit cyclic buffer
@ -33463,65 +33160,6 @@ int32 func_strig(int32 i, int32 controller, int32 passed) {
return 0;
}
int32 func__fileexists(qbs *file) {
if (new_error)
return 0;
static qbs *strz = NULL;
if (!strz)
strz = qbs_new(0, 0);
qbs_set(strz, qbs_add(file, qbs_new_txt_len("\0", 1)));
#ifdef QB64_WINDOWS
static int32 x;
x = GetFileAttributes(fixdir(strz));
if (x == INVALID_FILE_ATTRIBUTES)
return 0;
if (x & FILE_ATTRIBUTE_DIRECTORY)
return 0;
return -1;
#elif defined(QB64_UNIX)
struct stat sb;
if (stat(fixdir(strz), &sb) == 0 && S_ISREG(sb.st_mode))
return -1;
return 0;
#else
// generic method (not currently used)
static std::ifstream fh;
fh.open(fixdir(strz), std::ios::binary | std::ios::in);
if (fh.is_open() == NULL) {
fh.clear(std::ios::goodbit);
return 0;
}
fh.clear(std::ios::goodbit);
fh.close();
return -1;
#endif
}
int32 func__direxists(qbs *file) {
if (new_error)
return 0;
static qbs *strz = NULL;
if (!strz)
strz = qbs_new(0, 0);
qbs_set(strz, qbs_add(file, qbs_new_txt_len("\0", 1)));
#ifdef QB64_WINDOWS
static int32 x;
x = GetFileAttributes(fixdir(strz));
if (x == INVALID_FILE_ATTRIBUTES)
return 0;
if (x & FILE_ATTRIBUTE_DIRECTORY)
return -1;
return 0;
#elif defined(QB64_UNIX)
struct stat sb;
if (stat(fixdir(strz), &sb) == 0 && S_ISDIR(sb.st_mode))
return -1;
return 0;
#else
return 0; // default response
#endif
}
int32 func__console() {
if (new_error)
return -1;
@ -36318,219 +35956,8 @@ int32 func__resizeheight() { return resize_event_y; }
int32 func__scaledwidth() { return environment_2d__screen_scaled_width; }
int32 func__scaledheight() { return environment_2d__screen_scaled_height; }
// Get Current Working Directory
qbs *func__cwd() {
qbs *final, *tqbs;
int length;
char *buf, *ret;
#if defined QB64_WINDOWS
length = GetCurrentDirectoryA(0, NULL);
buf = (char *)malloc(length);
if (!buf) {
error(7); //"Out of memory"
return tqbs;
}
if (GetCurrentDirectoryA(length, buf) != --length) { // Sanity check
free(buf); // It's good practice
tqbs = qbs_new(0, 1);
error(51); //"Internal error"
return tqbs;
}
#elif defined QB64_UNIX
length = 512;
while (1) {
buf = (char *)malloc(length);
if (!buf) {
tqbs = qbs_new(0, 1);
error(7);
return tqbs;
}
ret = getcwd(buf, length);
if (ret)
break;
if (errno != ERANGE) {
tqbs = qbs_new(0, 1);
error(51);
return tqbs;
}
free(buf);
length += 512;
}
length = strlen(ret);
ret = (char *)realloc(ret, length); // Chops off the null byte
if (!ret) {
tqbs = qbs_new(0, 1);
error(7);
return tqbs;
}
buf = ret;
#endif
final = qbs_new(length, 1);
memcpy(final->chr, buf, length);
free(buf);
return final;
}
qbs *startDir = NULL; // set on startup
qbs *func__startdir() {
qbs *temp = qbs_new(0, 1);
qbs_set(temp, startDir);
return temp;
}
qbs *rootDir = NULL; // the dir moved to when program begins
qbs *func__dir(qbs *context_in) {
static qbs *context = NULL;
if (!context) {
context = qbs_new(0, 0);
}
qbs_set(context, qbs_ucase(context_in));
if (qbs_equal(qbs_ucase(context), qbs_new_txt("TEXT")) || qbs_equal(qbs_ucase(context), qbs_new_txt("DOCUMENT")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("DOCUMENTS")) || qbs_equal(qbs_ucase(context), qbs_new_txt("MY DOCUMENTS"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 5, NULL, 0, osPath))) { // Documents
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("MUSIC")) || qbs_equal(qbs_ucase(context), qbs_new_txt("AUDIO")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("SOUND")) || qbs_equal(qbs_ucase(context), qbs_new_txt("SOUNDS")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("MY MUSIC"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 13, NULL, 0, osPath))) { // Music
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("PICTURE")) || qbs_equal(qbs_ucase(context), qbs_new_txt("PICTURES")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("IMAGE")) || qbs_equal(qbs_ucase(context), qbs_new_txt("IMAGES")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("MY PICTURES"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 39, NULL, 0, osPath))) { // Pictures
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("DCIM")) || qbs_equal(qbs_ucase(context), qbs_new_txt("CAMERA")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("CAMERA ROLL")) || qbs_equal(qbs_ucase(context), qbs_new_txt("PHOTO")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("PHOTOS"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 39, NULL, 0, osPath))) { // Pictures
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("MOVIE")) || qbs_equal(qbs_ucase(context), qbs_new_txt("MOVIES")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("VIDEO")) || qbs_equal(qbs_ucase(context), qbs_new_txt("VIDEOS")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("MY VIDEOS"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 14, NULL, 0, osPath))) { // Videos
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("DOWNLOAD")) || qbs_equal(qbs_ucase(context), qbs_new_txt("DOWNLOADS"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 0x0028, NULL, 0, osPath))) { // user folder
// XP & SHGetFolderPathA do not support the concept of a Downloads folder, however it can be constructed
mkdir((char *)((qbs_add(qbs_new_txt(osPath), qbs_new_txt_len("\\Downloads\0", 11)))->chr));
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\Downloads\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("DESKTOP"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 0, NULL, 0, osPath))) { // Desktop
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("APPDATA")) || qbs_equal(qbs_ucase(context), qbs_new_txt("APPLICATION DATA")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("PROGRAM DATA")) || qbs_equal(qbs_ucase(context), qbs_new_txt("DATA"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 0x001a, NULL, 0, osPath))) { // CSIDL_APPDATA (%APPDATA%)
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("LOCALAPPDATA")) || qbs_equal(qbs_ucase(context), qbs_new_txt("LOCAL APPLICATION DATA")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("LOCAL PROGRAM DATA")) || qbs_equal(qbs_ucase(context), qbs_new_txt("LOCAL DATA"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 0x001c, NULL, 0, osPath))) { // CSIDL_LOCAL_APPDATA (%LOCALAPPDATA%)
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("PROGRAMFILES")) || qbs_equal(qbs_ucase(context), qbs_new_txt("PROGRAM FILES"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 0x0026, NULL, 0, osPath))) { // CSIDL_PROGRAM_FILES (%PROGRAMFILES%)
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("PROGRAMFILESX86")) || qbs_equal(qbs_ucase(context), qbs_new_txt("PROGRAMFILES X86")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("PROGRAM FILES X86")) || qbs_equal(qbs_ucase(context), qbs_new_txt("PROGRAM FILES 86")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("PROGRAM FILES (X86)")) || qbs_equal(qbs_ucase(context), qbs_new_txt("PROGRAMFILES (X86)")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("PROGRAM FILES(X86)"))) {
#ifdef QB64_WINDOWS &&_WIN64
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 0x002a, NULL, 0, osPath))) { // CSIDL_PROGRAM_FILES (%PROGRAMFILES(X86)%)
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("TEMP")) || qbs_equal(qbs_ucase(context), qbs_new_txt("TEMP FILES"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH + 1];
DWORD pathlen;
pathlen = GetTempPathA(261, osPath); //%TEMP%
char path[pathlen];
memcpy(path, &osPath, pathlen);
if (pathlen > 0) {
return qbs_new_txt(path);
}
#endif
}
// general fallback location
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 0, NULL, 0, osPath))) { // desktop
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
return qbs_new_txt(".\\"); // current location
#else
return qbs_new_txt("./"); // current location
#endif
}
extern void set_dynamic_info();
int main(int argc, char *argv[]) {
#if defined(QB64_LINUX) && defined(X11)
@ -36753,9 +36180,6 @@ int main(int argc, char *argv[]) {
}
#endif
rootDir = qbs_new(0, 0);
qbs_set(rootDir, func__cwd());
unknown_opcode_mess = qbs_new(0, 0);
qbs_set(unknown_opcode_mess, qbs_new_txt_len("Unknown Opcode ( )\0", 20));

View file

@ -34,6 +34,20 @@ qbs *qbs_new_txt(const char *);
qbs *qbs_new_txt_len(const char *, int32_t);
qbs *qbs_add(qbs *, qbs *);
qbs *qbs_set(qbs *, qbs *);
int32 qbs_equal(qbs *str1, qbs *str2);
qbs *func_space(int32 spaces);
void makefit(qbs *text);
qbs *qbs_str(int64 value);
qbs *qbs_str(int32 value);
qbs *qbs_str(int16 value);
qbs *qbs_str(int8 value);
qbs *qbs_str(uint64 value);
qbs *qbs_str(uint32 value);
qbs *qbs_str(uint16 value);
qbs *qbs_str(uint8 value);
qbs *qbs_str(float value);
qbs *qbs_str(double value);
qbs *qbs_str(long double value);
void qbg_sub_window(float, float, float, float, int32);
extern int32 autodisplay;
// GFS forward references

View file

@ -2,6 +2,7 @@
libqb-objs-y += $(PATH_LIBQB)/src/threading.o
libqb-objs-y += $(PATH_LIBQB)/src/buffer.o
libqb-objs-y += $(PATH_LIBQB)/src/filepath.o
libqb-objs-y += $(PATH_LIBQB)/src/filesystem.o
libqb-objs-y += $(PATH_LIBQB)/src/datetime.o
libqb-objs-y += $(PATH_LIBQB)/src/rounding.o

View file

@ -1,6 +1,10 @@
#ifndef INCLUDE_LIBQB_FILEPATH_H
#define INCLUDE_LIBQB_FILEPATH_H
#include <string>
struct qbs;
// Takes a path + filename, and returns just the filename portion
// Returns either NULL or empty string if it has none.
const char *filepath_get_filename(const char *path);
@ -12,4 +16,11 @@ const char *filepath_get_extension(const char *fliename);
// Returns true if the path is to a file that matches the provided extension
bool filepath_has_extension(const char *path, const char *extension);
// The following overloaded functions changes the path separators in path based on the OS (path is modified)
char *filepath_fix_directory(char *path);
char *filepath_fix_directory(std::string &path);
char *filepath_fix_directory(qbs *path);
char *fixdir(qbs *);
#endif

View file

@ -0,0 +1,19 @@
#pragma once
#include <stdint.h>
struct qbs;
extern qbs *startDir;
qbs *func__cwd();
qbs *func__dir(qbs *context);
int32_t func__direxists(qbs *);
int32_t func__fileexists(qbs *);
qbs *func__startdir();
void sub_chdir(qbs *str);
void sub_files(qbs *str, int32_t passed);
void sub_kill(qbs *str);
void sub_mkdir(qbs *str);
void sub_name(qbs *oldname, qbs *newname);
void sub_rmdir(qbs *str);

View file

@ -5,8 +5,9 @@
#include <string.h>
const char *filepath_get_filename(const char *path)
{
#include "../../libqb.h"
const char *filepath_get_filename(const char *path) {
const char *fileName;
if (path == NULL) {
@ -32,8 +33,7 @@ const char *filepath_get_filename(const char *path)
return fileName;
}
const char *filepath_get_extension(const char *path)
{
const char *filepath_get_extension(const char *path) {
const char *extension;
const char *lastOccurance;
@ -57,8 +57,7 @@ const char *filepath_get_extension(const char *path)
return (lastOccurance != NULL) ? lastOccurance : extension;
}
bool filepath_has_extension(const char *path, const char *extension)
{
bool filepath_has_extension(const char *path, const char *extension) {
const char *ext1;
const char *ext2;
@ -75,3 +74,18 @@ bool filepath_has_extension(const char *path, const char *extension)
return strcasecmp(ext1, ext2) == 0;
#endif
}
char *fixdir(qbs *filename) {
// note: changes the slashes in a filename to make it compatible with the OS
// applied to QB commands: open, bload/bsave, loadfont, loadimage, sndopen/sndplayfile
for (auto i = 0; i < filename->len; i++) {
#ifdef QB64_WINDOWS
if (filename->chr[i] == 47)
filename->chr[i] = 92;
#else
if (filename->chr[i] == 92)
filename->chr[i] = 47;
#endif
}
return (char *)filename->chr;
}

View file

@ -0,0 +1,564 @@
#include "libqb-common.h"
#include "filepath.h"
#include "filesystem.h"
#include "../../libqb.h"
// Get Current Working Directory
qbs *func__cwd() {
qbs *final, *tqbs;
int length;
char *buf, *ret;
#if defined QB64_WINDOWS
length = GetCurrentDirectoryA(0, NULL);
buf = (char *)malloc(length);
if (!buf) {
error(7); //"Out of memory"
return tqbs;
}
if (GetCurrentDirectoryA(length, buf) != --length) { // Sanity check
free(buf); // It's good practice
tqbs = qbs_new(0, 1);
error(51); //"Internal error"
return tqbs;
}
#elif defined QB64_UNIX
length = 512;
while (1) {
buf = (char *)malloc(length);
if (!buf) {
tqbs = qbs_new(0, 1);
error(7);
return tqbs;
}
ret = getcwd(buf, length);
if (ret)
break;
if (errno != ERANGE) {
tqbs = qbs_new(0, 1);
error(51);
return tqbs;
}
free(buf);
length += 512;
}
length = strlen(ret);
ret = (char *)realloc(ret, length); // Chops off the null byte
if (!ret) {
tqbs = qbs_new(0, 1);
error(7);
return tqbs;
}
buf = ret;
#endif
final = qbs_new(length, 1);
memcpy(final->chr, buf, length);
free(buf);
return final;
}
qbs *func__dir(qbs *context_in) {
static qbs *context = NULL;
if (!context) {
context = qbs_new(0, 0);
}
qbs_set(context, qbs_ucase(context_in));
if (qbs_equal(qbs_ucase(context), qbs_new_txt("TEXT")) || qbs_equal(qbs_ucase(context), qbs_new_txt("DOCUMENT")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("DOCUMENTS")) || qbs_equal(qbs_ucase(context), qbs_new_txt("MY DOCUMENTS"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 5, NULL, 0, osPath))) { // Documents
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("MUSIC")) || qbs_equal(qbs_ucase(context), qbs_new_txt("AUDIO")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("SOUND")) || qbs_equal(qbs_ucase(context), qbs_new_txt("SOUNDS")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("MY MUSIC"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 13, NULL, 0, osPath))) { // Music
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("PICTURE")) || qbs_equal(qbs_ucase(context), qbs_new_txt("PICTURES")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("IMAGE")) || qbs_equal(qbs_ucase(context), qbs_new_txt("IMAGES")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("MY PICTURES"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 39, NULL, 0, osPath))) { // Pictures
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("DCIM")) || qbs_equal(qbs_ucase(context), qbs_new_txt("CAMERA")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("CAMERA ROLL")) || qbs_equal(qbs_ucase(context), qbs_new_txt("PHOTO")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("PHOTOS"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 39, NULL, 0, osPath))) { // Pictures
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("MOVIE")) || qbs_equal(qbs_ucase(context), qbs_new_txt("MOVIES")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("VIDEO")) || qbs_equal(qbs_ucase(context), qbs_new_txt("VIDEOS")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("MY VIDEOS"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 14, NULL, 0, osPath))) { // Videos
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("DOWNLOAD")) || qbs_equal(qbs_ucase(context), qbs_new_txt("DOWNLOADS"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 0x0028, NULL, 0, osPath))) { // user folder
// XP & SHGetFolderPathA do not support the concept of a Downloads folder, however it can be constructed
mkdir((char *)((qbs_add(qbs_new_txt(osPath), qbs_new_txt_len("\\Downloads\0", 11)))->chr));
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\Downloads\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("DESKTOP"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 0, NULL, 0, osPath))) { // Desktop
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("APPDATA")) || qbs_equal(qbs_ucase(context), qbs_new_txt("APPLICATION DATA")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("PROGRAM DATA")) || qbs_equal(qbs_ucase(context), qbs_new_txt("DATA"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 0x001a, NULL, 0, osPath))) { // CSIDL_APPDATA (%APPDATA%)
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("LOCALAPPDATA")) || qbs_equal(qbs_ucase(context), qbs_new_txt("LOCAL APPLICATION DATA")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("LOCAL PROGRAM DATA")) || qbs_equal(qbs_ucase(context), qbs_new_txt("LOCAL DATA"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 0x001c, NULL, 0, osPath))) { // CSIDL_LOCAL_APPDATA (%LOCALAPPDATA%)
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("PROGRAMFILES")) || qbs_equal(qbs_ucase(context), qbs_new_txt("PROGRAM FILES"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 0x0026, NULL, 0, osPath))) { // CSIDL_PROGRAM_FILES (%PROGRAMFILES%)
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("PROGRAMFILESX86")) || qbs_equal(qbs_ucase(context), qbs_new_txt("PROGRAMFILES X86")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("PROGRAM FILES X86")) || qbs_equal(qbs_ucase(context), qbs_new_txt("PROGRAM FILES 86")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("PROGRAM FILES (X86)")) || qbs_equal(qbs_ucase(context), qbs_new_txt("PROGRAMFILES (X86)")) ||
qbs_equal(qbs_ucase(context), qbs_new_txt("PROGRAM FILES(X86)"))) {
#ifdef QB64_WINDOWS &&_WIN64
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 0x002a, NULL, 0, osPath))) { // CSIDL_PROGRAM_FILES (%PROGRAMFILES(X86)%)
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
#endif
}
if (qbs_equal(qbs_ucase(context), qbs_new_txt("TEMP")) || qbs_equal(qbs_ucase(context), qbs_new_txt("TEMP FILES"))) {
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH + 1];
DWORD pathlen;
pathlen = GetTempPathA(261, osPath); //%TEMP%
char path[pathlen];
memcpy(path, &osPath, pathlen);
if (pathlen > 0) {
return qbs_new_txt(path);
}
#endif
}
// general fallback location
#ifdef QB64_WINDOWS
CHAR osPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, 0, NULL, 0, osPath))) { // desktop
return qbs_add(qbs_new_txt(osPath), qbs_new_txt("\\"));
}
return qbs_new_txt(".\\"); // current location
#else
return qbs_new_txt("./"); // current location
#endif
}
int32 func__direxists(qbs *file) {
if (new_error)
return 0;
static qbs *strz = NULL;
if (!strz)
strz = qbs_new(0, 0);
qbs_set(strz, qbs_add(file, qbs_new_txt_len("\0", 1)));
#ifdef QB64_WINDOWS
static int32 x;
x = GetFileAttributes(fixdir(strz));
if (x == INVALID_FILE_ATTRIBUTES)
return 0;
if (x & FILE_ATTRIBUTE_DIRECTORY)
return -1;
return 0;
#elif defined(QB64_UNIX)
struct stat sb;
if (stat(fixdir(strz), &sb) == 0 && S_ISDIR(sb.st_mode))
return -1;
return 0;
#else
return 0; // default response
#endif
}
int32 func__fileexists(qbs *file) {
if (new_error)
return 0;
static qbs *strz = NULL;
if (!strz)
strz = qbs_new(0, 0);
qbs_set(strz, qbs_add(file, qbs_new_txt_len("\0", 1)));
#ifdef QB64_WINDOWS
static int32 x;
x = GetFileAttributes(fixdir(strz));
if (x == INVALID_FILE_ATTRIBUTES)
return 0;
if (x & FILE_ATTRIBUTE_DIRECTORY)
return 0;
return -1;
#elif defined(QB64_UNIX)
struct stat sb;
if (stat(fixdir(strz), &sb) == 0 && S_ISREG(sb.st_mode))
return -1;
return 0;
#else
// generic method (not currently used)
static std::ifstream fh;
fh.open(fixdir(strz), std::ios::binary | std::ios::in);
if (fh.is_open() == NULL) {
fh.clear(std::ios::goodbit);
return 0;
}
fh.clear(std::ios::goodbit);
fh.close();
return -1;
#endif
}
qbs *startDir = NULL; // set on startup
qbs *func__startdir() {
qbs *temp = qbs_new(0, 1);
qbs_set(temp, startDir);
return temp;
}
void sub_chdir(qbs *str) {
if (new_error)
return;
static qbs *strz = NULL;
if (!strz)
strz = qbs_new(0, 0);
qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1)));
if (chdir(fixdir(strz)) == -1) {
// assume errno==ENOENT
error(76); // path not found
}
static int32 tmp_long;
static int32 got_ports = 0;
}
void sub_files(qbs *str, int32 passed) {
if (new_error)
return;
static int32 i, i2, i3;
static qbs *strz = NULL;
if (!strz)
strz = qbs_new(0, 0);
if (passed) {
qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1)));
} else {
qbs_set(strz, qbs_new_txt_len("\0", 1));
}
#ifdef QB64_WINDOWS
static WIN32_FIND_DATA fd;
static HANDLE hFind;
static qbs *strpath = NULL;
if (!strpath)
strpath = qbs_new(0, 0);
static qbs *strz2 = NULL;
if (!strz2)
strz2 = qbs_new(0, 0);
i = 0;
if (strz->len >= 2) {
if (strz->chr[strz->len - 2] == 92)
i = 1;
} else
i = 1;
if (i) { // add * (and new NULL term.)
strz->chr[strz->len - 1] = 42; //"*"
qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1)));
}
qbs_set(strpath, strz);
for (i = strpath->len; i > 0; i--) {
if ((strpath->chr[i - 1] == 47) || (strpath->chr[i - 1] == 92)) {
strpath->len = i;
break;
}
} // i
if (i == 0)
strpath->len = 0; // no path specified
// print the current path
// note: for QBASIC compatibility reasons it does not print the directory name of the files being displayed
static uint8 curdir[4096];
static uint8 curdir2[4096];
i2 = GetCurrentDirectory(4096, (char *)curdir);
if (i2) {
i2 = GetShortPathName((char *)curdir, (char *)curdir2, 4096);
if (i2) {
qbs_set(strz2, qbs_ucase(qbs_new_txt_len((char *)curdir2, i2)));
qbs_print(strz2, 1);
} else {
error(5);
return;
}
} else {
error(5);
return;
}
hFind = FindFirstFile(fixdir(strz), &fd);
if (hFind == INVALID_HANDLE_VALUE) {
error(53);
return;
} // file not found
do {
if (!fd.cAlternateFileName[0]) { // no alternate filename exists
qbs_set(strz2, qbs_ucase(qbs_new_txt_len(fd.cFileName, strlen(fd.cFileName))));
} else {
qbs_set(strz2, qbs_ucase(qbs_new_txt_len(fd.cAlternateFileName, strlen(fd.cAlternateFileName))));
}
if (strz2->len < 12) { // padding required
qbs_set(strz2, qbs_add(strz2, func_space(12 - strz2->len)));
i2 = 0;
for (i = 0; i < 12; i++) {
if (strz2->chr[i] == 46) {
memmove(&strz2->chr[8], &strz2->chr[i], 4);
memset(&strz2->chr[i], 32, 8 - i);
break;
}
} // i
} // padding
// add " " or "<DIR> "
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
qbs_set(strz2, qbs_add(strz2, qbs_new_txt_len("<DIR> ", 6)));
} else {
qbs_set(strz2, qbs_add(strz2, func_space(6)));
}
makefit(strz2);
qbs_print(strz2, 0);
} while (FindNextFile(hFind, &fd));
FindClose(hFind);
static ULARGE_INTEGER FreeBytesAvailableToCaller;
static ULARGE_INTEGER TotalNumberOfBytes;
static ULARGE_INTEGER TotalNumberOfFreeBytes;
static int64 bytes;
static char *cp;
qbs_set(strpath, qbs_add(strpath, qbs_new_txt_len("\0", 1)));
cp = (char *)strpath->chr;
if (strpath->len == 1)
cp = NULL;
if (GetDiskFreeSpaceEx(cp, &FreeBytesAvailableToCaller, &TotalNumberOfBytes, &TotalNumberOfFreeBytes)) {
bytes = *(int64 *)(void *)&FreeBytesAvailableToCaller;
} else {
bytes = 0;
}
if (func_pos(NULL) > 1) {
strz2->len = 0;
qbs_print(strz2, 1);
} // new line if necessary
qbs_set(strz2, qbs_add(qbs_str(bytes), qbs_new_txt_len(" Bytes free", 11)));
qbs_print(strz2, 1);
#endif
}
void sub_kill(qbs *str) {
// note: file not found returned for non-existant paths too
// file already open returned if access unavailable
if (new_error)
return;
static int32 i;
static qbs *strz = NULL;
if (!strz)
strz = qbs_new(0, 0);
qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1)));
#ifdef QB64_WINDOWS
static WIN32_FIND_DATA fd;
static HANDLE hFind;
static qbs *strpath = NULL;
if (!strpath)
strpath = qbs_new(0, 0);
static qbs *strfullz = NULL;
if (!strfullz)
strfullz = qbs_new(0, 0);
// find path
qbs_set(strpath, strz);
for (i = strpath->len; i > 0; i--) {
if ((strpath->chr[i - 1] == 47) || (strpath->chr[i - 1] == 92)) {
strpath->len = i;
break;
}
} // i
if (i == 0)
strpath->len = 0; // no path specified
static int32 count;
count = 0;
hFind = FindFirstFile(fixdir(strz), &fd);
if (hFind == INVALID_HANDLE_VALUE) {
error(53);
return;
} // file not found
do {
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
qbs_set(strfullz, qbs_add(strpath, qbs_new_txt_len(fd.cFileName, strlen(fd.cFileName) + 1)));
if (!DeleteFile((char *)strfullz->chr)) {
i = GetLastError();
if ((i == 5) || (i == 19) || (i == 33) || (i == 32)) {
FindClose(hFind);
error(55);
return;
} // file already open
FindClose(hFind);
error(53);
return; // file not found
}
count++;
} // not a directory
} while (FindNextFile(hFind, &fd));
FindClose(hFind);
if (!count) {
error(53);
return;
} // file not found
return;
#else
if (remove(fixdir(strz))) {
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)
}
#endif
}
void sub_mkdir(qbs *str) {
if (new_error)
return;
static qbs *strz = NULL;
if (!strz)
strz = qbs_new(0, 0);
qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1)));
#ifdef QB64_UNIX
if (mkdir(fixdir(strz), 0770) == -1) {
#else
if (mkdir(fixdir(strz)) == -1) {
#endif
if (errno == EEXIST) {
error(75);
return;
} // path/file access error
// assume errno==ENOENT
error(76); // path not found
}
}
void sub_name(qbs *oldname, qbs *newname) {
if (new_error)
return;
static qbs *strz = NULL;
if (!strz)
strz = qbs_new(0, 0);
static qbs *strz2 = NULL;
if (!strz2)
strz2 = qbs_new(0, 0);
static int32 i;
qbs_set(strz, qbs_add(oldname, qbs_new_txt_len("\0", 1)));
qbs_set(strz2, qbs_add(newname, qbs_new_txt_len("\0", 1)));
if (rename(fixdir(strz), fixdir(strz2))) {
i = errno;
if (i == ENOENT) {
error(53);
return;
} // file not found
if (i == EINVAL) {
error(64);
return;
} // bad file name
if (i == EACCES) {
error(75);
return;
} // path/file access error
error(5); // Illegal function call (assumed)
}
}
void sub_rmdir(qbs *str) {
if (new_error)
return;
static qbs *strz = NULL;
if (!strz)
strz = qbs_new(0, 0);
qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1)));
if (rmdir(fixdir(strz)) == -1) {
if (errno == ENOTEMPTY) {
error(75);
return;
} // path/file access error
// assume errno==ENOENT
error(76); // path not found
}
}

View file

@ -3,11 +3,13 @@
#include "compression.h"
#include "datetime.h"
#include "event.h"
#include "extended_math.h"
#include "filepath.h"
#include "filesystem.h"
#include "font.h"
#include "gui.h"
#include "image.h"
#include "rounding.h"
#include "extended_math.h"
extern int32 func__cinp(int32 toggle,
int32 passed); // Console INP scan code reader
@ -88,14 +90,9 @@ void requestKeyboardOverlayImage(int32 handle) {
// extern functions
extern qbs *func__dir(qbs *context);
extern int32 func__scaledwidth();
extern int32 func__scaledheight();
extern qbs *func__cwd();
extern qbs *func__startdir();
extern void sub__fps(double fps, int32 passed);
extern void sub__resize(int32 on_off, int32 stretch_smooth);
@ -176,8 +173,6 @@ extern int32 func_windowexists();
extern int32 func_screenicon();
extern int32 func_screenwidth();
extern int32 func_screenheight();
extern int32 func__borderwidth();
extern int32 func__titlebarheight();
extern void sub_screenicon();
extern void sub__console(int32);
extern int32 func__console();
@ -189,8 +184,6 @@ extern int32 func__hasfocus();
extern void set_foreground_window(ptrszint i);
extern qbs *func__title();
extern int32 func__handle();
extern int32 func__fileexists(qbs *);
extern int32 func__direxists(qbs *);
extern int32 func_stick(int32 i, int32 axis_group, int32 passed);
extern int32 func_strig(int32 i, int32 controller, int32 passed);
extern void sub__maptriangle(int32 cull_options, float sx1, float sy1,
@ -222,7 +215,6 @@ extern void field_get(int32 fileno, int64 seekpos, int32 passed);
extern void field_put(int32 fileno, int64 seekpos, int32 passed);
extern int32 func__keydown(int32 x);
extern int32 func__keyhit();
extern void sub_files(qbs *str, int32 passed);
extern int32 func_lpos(int32);
extern void sub__printimage(int32 i);
extern float func__mousemovementx(int32 context, int32 passed);
@ -244,7 +236,6 @@ extern qbs *func__clipboard();
extern int32 func__clipboardimage();
extern void sub__clipboardimage(int32 src);
extern int32 func__exit();
extern char *fixdir(qbs *);
extern void revert_input_check();
extern int32 func__openhost(qbs *);
extern int32 func__openconnection(int32);
@ -274,7 +265,6 @@ extern void sub__putimage(double f_dx1, double f_dy1, double f_dx2,
double f_sy1, double f_sx2, double f_sy2,
int32 passed);
extern int32 selectfont(int32 f, img_struct *im);
extern void sndsetup();
extern uint32 sib();
extern uint32 sib_mod0();
extern uint8 *rm8();
@ -297,10 +287,6 @@ extern void sub_defseg(int32 segment, int32 passed);
extern int32 func_peek(int32 offset);
extern void sub_poke(int32 offset, int32 value);
extern void more_return_points();
extern void qb64_generatesound(double f, double l, uint8 wait);
extern uint8 *soundwave(double frequency, double length, double volume,
double fadein, double fadeout);
extern int32 wavesize(double length);
extern qbs *qbs_new_descriptor();
extern void qbs_free_descriptor(qbs *str);
extern void qbs_free(qbs *str);
@ -522,14 +508,8 @@ extern qbs *func_input(int32 n, int32 i, int32 passed);
extern int32 func__statusCode(int32 handle);
extern double func_sqr(double value);
extern void snd_check();
extern qbs *func_command(int32 index, int32 passed);
extern int32 func__commandcount();
extern void sub_kill(qbs *str);
extern void sub_name(qbs *oldname, qbs *newname);
extern void sub_chdir(qbs *str);
extern void sub_mkdir(qbs *str);
extern void sub_rmdir(qbs *str);
extern long double pow2(long double x, long double y);
extern int32 func_freefile();
extern void sub__mousehide();