MWCC/command_line/CmdLine/Src/OSLib/Generic.c

447 lines
9.7 KiB
C

#include "oslib.h"
#include <errno.h>
static char wildname[63];
static char wilddir[255];
static OSOpenedDir wilddirref;
static OSSpec wildmatch;
char STSbuf[256];
inline char dummyfunc(int ch) {
return ch;
}
int WildCardMatch(char *wild, char *name) {
char next;
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] == OS_PATHSEP && !name[1]);
}
OSSpec *OS_MatchPath(const char *path) {
char filename[64];
Boolean isfile;
OSSpec spec;
const char *nptr;
if (path) {
nptr = strrchr(path, OS_PATHSEP);
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, OS_PATHSEP);
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 == OS_PATHSEP) {
*pptr = 0;
--pptr;
}
while (pptr >= path && *pptr != OS_PATHSEP)
pptr--;
strncpy(buf, pptr, size - 1);
buf[size - 1] = 0;
return buf;
}
int OS_MakeSpec2(const char *path, const char *filename, OSSpec *spec) {
char bpath[256];
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] != OS_PATHSEP)
*(eptr++) = OS_PATHSEP;
strcpy(eptr, filename);
return OS_MakeSpec(bpath, spec, 0);
}
int OS_MakeSpecWithPath(OSPathSpec *path, const char *filename, Boolean noRelative, OSSpec *spec) {
Boolean relpath;
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) {
int plen;
int nlen;
char *ptr;
int bidx;
int wat;
plen = p ? strlen(p) : 0;
nlen = n ? strlen(n) : 0;
if (plen + nlen + 1 <= size) {
sprintf(buf, "%s%s", p ? p : "", n ? n : "");
return buf;
}
ptr = buf;
bidx = 0;
wat = plen + nlen - size;
while (plen > 0 && nlen > 0) {
if (plen > 0) {
*(ptr++) = *(p++);
plen--;
} else if (nlen > 0) {
*(ptr++) = *(n++);
nlen--;
}
if (++bidx == (size / 2) - 2) {
ptr[0] = '.';
ptr[1] = '.';
ptr[2] = '.';
ptr += 3;
bidx += 3;
if (plen > 0) {
plen -= wat / 2;
if (plen < 0) {
n -= plen;
nlen += plen;
plen = 0;
}
} else {
n += wat / 2;
nlen -= wat / 2;
}
}
}
*ptr = 0;
return buf;
}
char *OS_SpecToStringRelative(const OSSpec *spec, const OSPathSpec *cwdspec, char *path, int size) {
char fullbuf[256];
char *full;
char cwdbuf[256];
char *cwd;
OSPathSpec mycwdspec;
char *pptr;
full = fullbuf;
cwd = cwdbuf;
OS_SpecToString(spec, full, 256);
if (!size)
size = 256;
if (!path) {
path = malloc(size);
if (!path)
return 0;
}
if (!cwdspec) {
OS_GetCWD(&mycwdspec);
cwdspec = &mycwdspec;
}
if (!OS_PathSpecToString(cwdspec, cwdbuf, 256)) {
memcpy(path, fullbuf, size - 1);
path[size - 1] = 0;
return path;
}
while (*cwd && *full == *cwd) {
full++;
cwd++;
}
if ((cwd - cwdbuf) < (strlen(fullbuf) / 2) && (strlen(cwd) > (strlen(fullbuf) / 2))) {
memcpy(path, fullbuf, size - 1);
path[size - 1] = 0;
return path;
}
while (cwd > cwdbuf) {
cwd--;
full--;
if (*cwd == OS_PATHSEP)
break;
}
if (cwd == cwdbuf) {
strncpy(path, full, size - 1);
path[size - 1] = 0;
} else {
if (*(++cwd)) {
pptr = path;
while (*cwd) {
if (*cwd == OS_PATHSEP)
pptr += sprintf(pptr, "../");
++cwd;
}
strcpy(pptr, full + 1);
} else {
strncpy(path, full + 1, size - 1);
path[size - 1] = 0;
}
}
return path;
}
int OS_FindFileInPath(const char *filename, const char *plist, OSSpec *spec) {
const char *next;
char path[256];
int err;
while (plist && *plist) {
next = strchr(plist, ':');
if (!next)
next = strpbrk(plist, ":;");
if (!next)
next = plist + strlen(plist);
strcpyn(path, plist, next - plist, 255);
if (!OS_MakeSpec2(path, filename, spec)) {
if (!OS_Status(spec))
return 0;
}
if (*next)
plist = next + 1;
else
plist = 0;
}
err = OS_MakeFileSpec(filename, spec);
if (!err) {
err = OS_Status(spec);
if (!err)
err = 0;
}
return err;
}
int OS_FindProgram(const char *filename, OSSpec *spec) {
char *plist;
int err;
char temp[256];
strncpy(temp, filename, 256);
temp[255] = 0;
if (!strchr(temp, OS_PATHSEP)) {
plist = getenv("PATH");
err = OS_FindFileInPath(temp, plist, spec);
if (!err)
return 0;
}
err = OS_MakeFileSpec(temp, spec);
if (!err)
err = OS_Status(spec);
return err;
}
int OS_CopyHandle(OSHandle *hand, OSHandle *copy) {
int err;
UInt32 sz;
void *f;
void *t;
err = OS_GetHandleSize(hand, &sz);
if (!err) {
err = OS_NewHandle(sz, copy);
if (!err) {
f = OS_LockHandle(hand);
t = OS_LockHandle(copy);
memcpy(t, f, sz);
OS_UnlockHandle(hand);
OS_UnlockHandle(copy);
return 0;
}
}
OS_FreeHandle(copy);
return err;
}
int OS_AppendHandle(OSHandle *hand, const void *data, UInt32 len) {
int err;
UInt32 sz;
void *buffer;
err = OS_GetHandleSize(hand, &sz);
if (!err) {
err = OS_ResizeHandle(hand, sz + len);
if (!err) {
buffer = OS_LockHandle(hand);
if (buffer) {
memcpy((unsigned char *) buffer + sz, data, len);
OS_UnlockHandle(hand);
return 0;
}
}
}
return err;
}