almost finished OSLib

This commit is contained in:
Ash Wolf 2022-10-12 18:07:57 +01:00
parent f080c0e765
commit 945f737516
8 changed files with 561 additions and 16 deletions

View File

@ -1,29 +1,128 @@
#include "oslib.h"
#include <errno.h>
static int OS_LoadFileHandle(OSFileHandle *hand) {
int err;
int ref;
UInt32 sz;
void *buffer;
hand->loaded = 0;
err = OS_Open(&hand->spec, OSReadOnly, &ref);
if (!err) {
err = OS_GetSize(ref, &sz);
if (!err) {
err = OS_ResizeHandle(&hand->hand, sz);
if (!err) {
buffer = OS_LockHandle(&hand->hand);
err = OS_Read(ref, buffer, &sz);
if (!err) {
hand->loaded = 1;
hand->changed = 0;
}
OS_UnlockHandle(&hand->hand);
}
}
OS_Close(ref);
}
return err;
}
static int OS_WriteFileHandle(OSFileHandle *hand) {
int err;
int ref;
UInt32 sz;
void *buffer;
if (!hand->loaded && !hand->changed)
return 0;
OS_Delete(&hand->spec);
err = OS_Create(&hand->spec, &OS_TEXTTYPE);
if (!err) {
err = OS_Open(&hand->spec, OSReadWrite, &ref);
if (!err) {
err = OS_GetHandleSize(&hand->hand, &sz);
if (!err) {
buffer = OS_LockHandle(&hand->hand);
err = OS_Write(ref, buffer, &sz);
if (!err)
hand->changed = 0;
OS_UnlockHandle(&hand->hand);
OS_Close(ref);
}
}
}
return err;
}
int OS_NewFileHandle(const OSSpec *spec, OSHandle *src, Boolean writeable, OSFileHandle *hand) {
int err;
if (!writeable && src)
return EACCES;
hand->spec = *spec;
hand->writeable = writeable;
if (!src) {
err = OS_NewHandle(0, &hand->hand);
if (err)
return err;
err = OS_LoadFileHandle(hand);
} else {
err = OS_CopyHandle(src, &hand->hand);
if (err)
return err;
hand->changed = 1;
hand->loaded = 1;
}
return err;
}
int OS_LockFileHandle(OSFileHandle *hand, Ptr *ptr, UInt32 *size) {
*size = 0;
if (!OS_ValidHandle(&hand->hand))
return ENOMEM;
*ptr = OS_LockHandle(&hand->hand);
OS_GetHandleSize(&hand->hand, size);
return 0;
}
int OS_UnlockFileHandle(OSFileHandle *hand) {
if (!OS_ValidHandle(&hand->hand))
return ENOMEM;
OS_UnlockHandle(&hand->hand);
return 0;
}
int OS_FreeFileHandle(OSFileHandle *hand) {
int err;
if (hand->writeable && hand->changed) {
err = OS_WriteFileHandle(hand);
if (err)
return err;
}
if (!OS_ValidHandle(&hand->hand))
return ENOMEM;
err = OS_FreeHandle(&hand->hand);
if (err)
return err;
hand->loaded = 0;
return 0;
}
void OS_GetFileHandleSpec(const OSFileHandle *hand, OSSpec *spec) {
*spec = hand->spec;
}

View File

@ -1,4 +1,5 @@
#include "oslib.h"
#include <errno.h>
static char wildname[63];
static char wilddir[255];
@ -6,9 +7,48 @@ static OSOpenedDir wilddirref;
static OSSpec wildmatch;
char STSbuf[256];
int WildCardMatch(const char *wild, const char *name) {
inline char dummyfunc(int ch) {
return ch;
}
int WildCardMatch(char *wild, char *name) {
char next;
const char *prev;
char *prev;
if (!name[0])
return 0;
while (*wild) {
if (*wild == '*') {
wild++;
next = *wild;
prev = 0;
while (*name) {
if (dummyfunc(*name) == dummyfunc(next))
prev = name;
++name;
}
if (prev)
name = prev;
if (dummyfunc(*name) != dummyfunc(next))
return 0;
} else if (*wild == '?' && *name) {
wild++;
name++;
if (!*wild && *name)
return 0;
} else if (dummyfunc(*wild) == dummyfunc(*name)) {
wild++;
name++;
} else {
return 0;
}
}
return !name[0] || (name[0] == '/' && !name[1]);
}
OSSpec *OS_MatchPath(const char *path) {
@ -16,15 +56,63 @@ OSSpec *OS_MatchPath(const char *path) {
Boolean isfile;
OSSpec spec;
const char *nptr;
if (path) {
nptr = strrchr(path, '/');
if (!nptr) {
nptr = path;
strcpyn(wilddir, ".", -1, 256);
} else {
nptr = nptr + 1;
strcpyn(wilddir, path, nptr - path, 256);
}
if (OS_MakePathSpec(0, wilddir, &spec.path))
return 0;
strcpyn(wildname, nptr, -1, 64);
if (OS_MakeNameSpec(wildname, &spec.name))
return 0;
if (OS_OpenDir(&spec.path, &wilddirref))
return 0;
}
while (!OS_ReadDir(&wilddirref, &wildmatch, filename, &isfile)) {
if (isfile && WildCardMatch(wildname, filename))
return &wildmatch;
}
OS_CloseDir(&wilddirref);
return 0;
}
char *OS_GetFileNamePtr(char *path) {
char *ptr;
ptr = strrchr(path, '/');
return !ptr ? path : (ptr + 1);
}
char *OS_GetDirName(const OSPathSpec *spec, char *buf, int size) {
char *path;
char *pptr;
if (!spec || !buf || size <= 0)
return 0;
path = OS_PathSpecToString(spec, STSbuf, 256);
pptr = path + strlen(path) - 1;
if (pptr > path && *pptr == '/') {
*pptr = 0;
--pptr;
}
while (pptr >= path && *pptr != '/')
pptr--;
strncpy(buf, pptr, size - 1);
buf[size - 1] = 0;
return buf;
}
int OS_MakeSpec2(const char *path, const char *filename, OSSpec *spec) {
@ -32,6 +120,24 @@ int OS_MakeSpec2(const char *path, const char *filename, OSSpec *spec) {
char *eptr;
int pthlen;
int fnlen;
if (!path)
path = "";
if (!filename)
filename = "";
fnlen = strlen(filename);
pthlen = strlen(path);
if (fnlen + pthlen + 1 > 255)
return ENAMETOOLONG;
strncpy(bpath, path, pthlen);
eptr = bpath + pthlen;
if (eptr[-1] != '/')
*(eptr++) = '/';
strcpy(eptr, filename);
return OS_MakeSpec(bpath, spec, 0);
}
int OS_MakeSpecWithPath(OSPathSpec *path, const char *filename, Boolean noRelative, OSSpec *spec) {
@ -39,16 +145,84 @@ int OS_MakeSpecWithPath(OSPathSpec *path, const char *filename, Boolean noRelati
char buf[256];
char *mptr;
char *eptr;
relpath = filename && strpbrk(filename, "/\\:");
if (!filename) {
if (path)
spec->path = *path;
else
OS_GetCWD(&spec->path);
return OS_MakeNameSpec("", &spec->name);
} else {
if ((!noRelative || !relpath) && !OS_IsFullPath(filename)) {
if (path)
OS_PathSpecToString(path, buf, 256);
else
buf[0] = 0;
mptr = &buf[255] - strlen(filename);
eptr = &buf[strlen(buf)];
strcpy((eptr > mptr) ? mptr : eptr, filename);
return OS_MakeSpec(buf, spec, 0);
} else {
return OS_MakeSpec(filename, spec, 0);
}
}
}
int OS_NameSpecChangeExtension(OSNameSpec *spec, const char *ext, Boolean append) {
char tmp[64];
char *per;
OS_NameSpecToString(spec, tmp, 256);
if (!append) {
per = strrchr(tmp, '.');
if (!per)
per = tmp + strlen(tmp);
} else {
per = tmp + strlen(tmp);
if (ext[0] != '.') {
per[0] = '.';
per[1] = 0;
per += 1;
}
}
if (strlen(tmp) + strlen(ext) > 64)
per = tmp + 63 - strlen(ext);
strcpy(per, ext);
return OS_MakeNameSpec(tmp, spec);
}
int OS_NameSpecSetExtension(OSNameSpec *spec, const char *ext) {
char tmp[64];
char *per;
OS_NameSpecToString(spec, tmp, 256);
if (ext[0] != '.') {
per = strrchr(tmp, '.');
if (!per)
per = tmp + strlen(tmp);
if (ext[0]) {
if (strlen(tmp) + 1 >= 64) {
per[-1] = '.';
} else {
per[0] = '.';
per++;
}
}
} else {
per = tmp + strlen(tmp);
}
if (strlen(tmp) + strlen(ext) > 64)
per = tmp + 63 - strlen(ext);
strcpy(per, ext);
return OS_MakeNameSpec(tmp, spec);
}
char *OS_CompactPaths(char *buf, const char *p, const char *n, int size) {

View File

@ -1,29 +1,120 @@
#include "oslib.h"
void OS_AddFileTypeMappingList(OSFileTypeMappings **list, OSFileTypeMappingList *entry) {
#define OPTION_ASSERT(cond) do { if (!(cond)) { printf("%s:%u: failed assertion\n", __FILE__, __LINE__); abort(); } } while(0)
static OSFileTypeMappings *defaultList;
static OSFileTypeMappings **fmList = &defaultList;
int (*__OS_ExtendedGetMacFileTypeHook)(const OSSpec *, OSType *);
void OS_AddFileTypeMappingList(OSFileTypeMappings **list, OSFileTypeMappingList *entry) {
OSFileTypeMappings **scan;
if (!list)
list = fmList;
scan = list;
while (*scan)
scan = &(*scan)->next;
*scan = malloc(sizeof(OSFileTypeMappings));
#line 40
OPTION_ASSERT(*scan != NULL);
(*scan)->mappingList = entry;
(*scan)->next = 0;
}
void OS_UseFileTypeMappings(OSFileTypeMappings *list) {
fmList = list ? &list : &defaultList;
}
void OS_MacType_To_OSType(OSType mactype, uOSTypePair *type) {
OSFileTypeMappings *list;
OSFileTypeMappingList *scan;
int idx;
for (list = *fmList; list; list = list->next) {
scan = list->mappingList;
for (idx = 0; idx < scan->numMappings; idx++) {
if (scan->mappings[idx].mactype == mactype) {
type->perm = scan->mappings[idx].executable ? 0777 : 0666;
return;
}
}
}
*type = OS_TEXTTYPE;
}
int OS_SetMacFileType(const OSSpec *spec, OSType mactype) {
uOSTypePair type;
OS_MacType_To_OSType(mactype, &type);
return OS_SetFileType(spec, &type);
}
Boolean OS_GetMacFileTypeMagic(const char *buffer, int count, OSType *mactype) {
OSFileTypeMappings *list;
OSFileTypeMappingList *scan;
int idx;
*mactype = 0;
for (list = *fmList; list; list = list->next) {
scan = list->mappingList;
for (idx = 0; idx < scan->numMappings; idx++) {
if (scan->mappings[idx].length <= count && scan->mappings[idx].magic && !memcmp(buffer, scan->mappings[idx].magic, scan->mappings[idx].length)) {
*mactype = scan->mappings[idx].mactype;
return 1;
}
}
}
return 0;
}
int OS_GetMacFileType(const OSSpec *spec, OSType *mactype) {
int ref;
int err;
char buffer[32];
UInt32 count;
UInt32 flen;
OSSpec rsrc;
UInt32 rsize;
err = OS_Open(spec, OSReadOnly, &ref);
if (err < 0)
return err;
OS_GetSize(ref, &flen);
count = sizeof(buffer);
err = OS_Read(ref, buffer, &count);
OS_Close(ref);
if (err >= 0 && count) {
if (OS_GetMacFileTypeMagic(buffer, count, mactype))
return 0;
}
if (!__OS_ExtendedGetMacFileTypeHook || !__OS_ExtendedGetMacFileTypeHook(spec, mactype)) {
if (flen == 0) {
if (!OS_GetRsrcOSSpec(spec, &rsrc, 0)) {
int ref;
if (!OS_Open(&rsrc, OSReadOnly, &ref)) {
OS_GetSize(ref, &rsize);
OS_Close(ref);
if (rsize) {
*mactype = 'rsrc';
return 0;
}
}
}
}
*mactype = 'TEXT';
}
return 0;
}
int OS_SetMacFileCreatorAndType(const OSSpec *spec, OSType creator, OSType mactype) {
return OS_SetMacFileType(spec, mactype);
}

View File

@ -1,21 +1,54 @@
#include "oslib.h"
void *xmalloc(const char *what, int size) {
void *ret;
ret = malloc(size ? size : 1);
if (!ret) {
fprintf(
stderr,
"*** Out of memory when allocating %d bytes%s%s",
size,
what ? " for " : "",
what ? what : "");
exit(-23);
return 0;
}
return ret;
}
void *xcalloc(const char *what, int size) {
void *ret;
ret = xmalloc(what, size);
memset(ret, 0, size);
return ret;
}
void *xrealloc(const char *what, void *old, int size) {
void *ret;
ret = realloc(old, size ? size : 1);
if (!ret) {
fprintf(
stderr,
"*** Out of memory when resizing buffer to %d bytes%s%s",
size,
what ? " for " : "",
what ? what : "");
exit(-23);
return 0;
}
return ret;
}
char *xstrdup(const char *str) {
return strcpy(xmalloc(0, strlen(str) + 1), str);
}
void xfree(void *ptr) {
if (ptr)
free(ptr);
}

View File

@ -1,17 +1,49 @@
#include "oslib.h"
char *strcatn(char *d, const char *s, SInt32 max) {
char *p;
p = d + strlen(d);
while (*s && (p - d) + 1 < max)
*(p++) = *(s++);
*p = 0;
return d;
}
char *strcpyn(char *d, const char *s, SInt32 len, SInt32 max) {
char *p;
p = d;
while (len-- && *s && (p - d) + 1 < max)
*(p++) = *(s++);
*p = 0;
return d;
}
int ustrcmp(const char *src, const char *dst) {
int x;
do {
x = tolower(*src) - tolower(*(dst++));
if (x)
return x;
} while (*(src++));
return 0;
}
int ustrncmp(const char *src, const char *dst, UInt32 len) {
int x;
while (len--) {
x = tolower(*src) - tolower(*(dst++));
if (x)
return x;
if (!*(src++))
return 0;
}
return 0;
}

View File

@ -1,49 +1,151 @@
#include "oslib.h"
#include "macemul.h"
#define OPTION_ASSERT(cond) do { if (!(cond)) { printf("%s:%u: failed assertion\n", __FILE__, __LINE__); abort(); } } while(0)
static char pfbuf[256];
StringPtr _pstrcpy(StringPtr dst, ConstStringPtr src) {
memcpy(dst, src, src[0] + 1);
return dst;
}
void _pstrcat(StringPtr dst, ConstStringPtr src) {
int cnt = dst[0] + src[0];
if (cnt > 255)
cnt = 255;
memcpy(dst + 1 + dst[0], src + 1, cnt - dst[0]);
dst[0] = cnt;
}
void _pstrcharcat(StringPtr to, char ch) {
if (to[0] < 255) {
to[0]++;
to[to[0]] = ch;
}
}
void pstrncpy(StringPtr to, ConstStringPtr from, int max) {
SInt16 i = (from[0] > max) ? max : from[0];
while (i >= 0) {
*(to++) = *(from++);
--i;
}
}
void pstrncat(StringPtr to, ConstStringPtr append, int max) {
SInt16 i;
SInt16 n;
i = *(append++);
n = to[0];
if (i + n > max)
i = max - n;
to[0] += i;
to += n + 1;
while (i-- > 0) {
*(to++) = *(append++);
}
}
int pstrcmp(ConstStringPtr a, ConstStringPtr b) {
int d = *(b++), n = *(a++);
if (n - d)
return n - d;
while (n-- > 0) {
d = *(a++) != *(b++);
if (d)
return d;
}
return 0;
}
int pstrchr(ConstStringPtr str, char find) {
int idx = 0;
while (idx++ < str[0]) {
if (find == str[idx])
return idx;
}
return 0;
}
void c2pstrcpy(StringPtr dst, const char *src) {
int len = strlen(src);
if (len > 255)
len = 255;
memmove(dst + 1, src, len);
dst[0] = len;
}
void p2cstrcpy(char *dst, ConstStringPtr src) {
memcpy(dst, src + 1, src[0]);
dst[src[0]] = 0;
}
char *mvprintf(char *mybuf, unsigned int len, const char *format, va_list va) {
int maxlen;
int ret;
char *buf;
#line 134
OPTION_ASSERT(mybuf != NULL);
maxlen = len - 1;
buf = mybuf;
ret = vsnprintf(mybuf, maxlen, format, va);
if (ret < 0) {
do {
if (buf != mybuf)
free(buf);
maxlen <<= 1;
buf = malloc(maxlen);
if (!buf)
return strncpy(mybuf, "<out of memory>", len);
ret = vsnprintf(buf, maxlen, format, va);
} while (ret < 0);
} else if (ret > maxlen) {
maxlen = ret + 1;
buf = malloc(maxlen);
if (!buf)
return strncpy(mybuf, "<out of memory>", len);
vsnprintf(buf, maxlen, format, va);
}
return buf;
}
char *mprintf(char *mybuf, unsigned int len, const char *format, ...) {
char *ret;
va_list ap;
va_start(ap, format);
ret = mvprintf(mybuf, len, format, ap);
va_end(ap);
return ret;
}
int HPrintF(Handle text, const char *format, ...) {
char *buf;
int ret;
va_list ap;
va_start(ap, format);
buf = mvprintf(pfbuf, sizeof(pfbuf), format, ap);
va_end(ap);
ret = strlen(buf);
if (PtrAndHand(buf, text, strlen(buf)))
return 0;
if (buf != pfbuf)
free(buf);
return ret;
}

View File

@ -15,6 +15,14 @@
//#include <MacHeadersMach-O>
#define CW_PASCAL pascal
#undef toupper
#undef tolower
// What the fuck is this haha
// typedef char * va_list;
#define va_start(a,b) (a = ((va_list) __builtin_next_arg(b)))
#define va_arg(a,b) (*(b *) (void *) ((a = (char *) (((((unsigned long)(a)) + ((__alignof__ (b) == 16) ? 15 : 3)) & ~((__alignof__ (b) == 16) ? 15 : 3)) + ((sizeof (b) + 3) & ~3))) - ((sizeof (b) + 3) & ~3)))
#define va_end(a) ((void)0)
#else
#include <stdarg.h>
// expand this to nothing

View File

@ -54,12 +54,15 @@ typedef struct {
OSPathSpec spec;
} OSOpenedDir; // assumed name, might be something like OSDirRef though?
#ifdef __MWERKS__
#pragma options align=packed
#endif
typedef struct OSFileTypeMapping {
OSType mactype;
const char *magic;
char length;
char executable;
const char *mimetype;
char executable; // not sure why this is rearranged
} OSFileTypeMapping;
typedef struct OSFileTypeMappingList {
@ -71,10 +74,13 @@ typedef struct OSFileTypeMappings {
OSFileTypeMappingList *mappingList;
struct OSFileTypeMappings *next;
} OSFileTypeMappings;
#ifdef __MWERKS__
#pragma options align=reset
#endif
/********************************/
/* Generic */
extern int WildCardMatch(const char *wild, const char *name);
extern int WildCardMatch(char *wild, char *name);
extern OSSpec *OS_MatchPath(const char *path);
extern char *OS_GetFileNamePtr(char *path);
extern char *OS_GetDirName(const OSPathSpec *spec, char *buf, int size);