summaryrefslogtreecommitdiff
path: root/command_line
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2022-10-12 18:07:57 +0100
committerAsh Wolf <ninji@wuffs.org>2022-10-12 18:07:57 +0100
commit945f73751630db0420522b5d6af0629d90376a45 (patch)
tree4b374c13d61dd0f54abefa49c6c348d6a56c6a52 /command_line
parentf080c0e765878ae91949d91a0bc10b87e6c8269b (diff)
downloadMWCC-945f73751630db0420522b5d6af0629d90376a45.tar.gz
MWCC-945f73751630db0420522b5d6af0629d90376a45.zip
almost finished OSLib
Diffstat (limited to 'command_line')
-rw-r--r--command_line/CmdLine/Src/OSLib/FileHandles.c101
-rw-r--r--command_line/CmdLine/Src/OSLib/Generic.c178
-rw-r--r--command_line/CmdLine/Src/OSLib/MacFileTypes.c97
-rw-r--r--command_line/CmdLine/Src/OSLib/MemUtils.c41
-rw-r--r--command_line/CmdLine/Src/OSLib/StringExtras.c32
-rw-r--r--command_line/CmdLine/Src/OSLib/StringUtils.c116
6 files changed, 548 insertions, 17 deletions
diff --git a/command_line/CmdLine/Src/OSLib/FileHandles.c b/command_line/CmdLine/Src/OSLib/FileHandles.c
index 4609d77..69b4b11 100644
--- a/command_line/CmdLine/Src/OSLib/FileHandles.c
+++ b/command_line/CmdLine/Src/OSLib/FileHandles.c
@@ -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;
}
diff --git a/command_line/CmdLine/Src/OSLib/Generic.c b/command_line/CmdLine/Src/OSLib/Generic.c
index 4430790..e95ebd5 100644
--- a/command_line/CmdLine/Src/OSLib/Generic.c
+++ b/command_line/CmdLine/Src/OSLib/Generic.c
@@ -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) {
diff --git a/command_line/CmdLine/Src/OSLib/MacFileTypes.c b/command_line/CmdLine/Src/OSLib/MacFileTypes.c
index 9d18723..5c9cb1c 100644
--- a/command_line/CmdLine/Src/OSLib/MacFileTypes.c
+++ b/command_line/CmdLine/Src/OSLib/MacFileTypes.c
@@ -1,29 +1,120 @@
#include "oslib.h"
+#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);
}
diff --git a/command_line/CmdLine/Src/OSLib/MemUtils.c b/command_line/CmdLine/Src/OSLib/MemUtils.c
index 4eb611c..fcacd81 100644
--- a/command_line/CmdLine/Src/OSLib/MemUtils.c
+++ b/command_line/CmdLine/Src/OSLib/MemUtils.c
@@ -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);
}
diff --git a/command_line/CmdLine/Src/OSLib/StringExtras.c b/command_line/CmdLine/Src/OSLib/StringExtras.c
index 04ef6b4..a4415ee 100644
--- a/command_line/CmdLine/Src/OSLib/StringExtras.c
+++ b/command_line/CmdLine/Src/OSLib/StringExtras.c
@@ -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;
}
diff --git a/command_line/CmdLine/Src/OSLib/StringUtils.c b/command_line/CmdLine/Src/OSLib/StringUtils.c
index 5f0d5bd..4ede522 100644
--- a/command_line/CmdLine/Src/OSLib/StringUtils.c
+++ b/command_line/CmdLine/Src/OSLib/StringUtils.c
@@ -1,49 +1,151 @@
#include "oslib.h"
+#include "macemul.h"
-StringPtr _pstrcpy(StringPtr dst, ConstStringPtr src) {
+#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;
}