MWCC/command_line/CmdLine/Src/Project/CLAccessPaths.c

511 lines
13 KiB
C

#include "cmdline.h"
// TODO check where this should be!
Paths FrameworkPaths;
Frameworks FrameworkInfo;
Path *Path_Init(const OSPathSpec *dir, Path *path) {
path->spec = xmalloc(NULL, sizeof(OSPathSpec));
*path->spec = *dir;
path->recursive = NULL;
path->dirlist = NULL;
path->flags = 0;
return path;
}
Path *Path_New(const OSPathSpec *dir) {
Path *path;
path = xmalloc(NULL, sizeof(Path));
return Path_Init(dir, path);
}
void Path_Free(Path *path) {
if (path) {
if (path->spec)
xfree(path->spec);
if (path->recursive) {
Paths_Terminate(path->recursive);
xfree(path->recursive);
}
xfree(path);
}
}
Boolean Paths_Initialize(Paths *paths) {
OS_ASSERT(52, paths != NULL);
memset(paths, 0, sizeof(Paths));
paths->pathsArray = NULL;
return 1;
}
Boolean Paths_Terminate(Paths *paths) {
UInt16 index;
OS_ASSERT(63, paths != NULL);
if (paths->pathsArray) {
for (index = 0; index < paths->pathsCount; index++)
Path_Free(paths->pathsArray[index]);
xfree(paths->pathsArray);
}
paths->pathsArray = NULL;
return 1;
}
static Boolean Paths_GrowPaths(Paths *paths, UInt16 *index) {
Path **newArray;
OS_ASSERT(84, paths != NULL);
if (paths->pathsCount >= paths->arraySize) {
paths->arraySize += 20;
newArray = xrealloc("access paths", paths->pathsArray, sizeof(Path *) * paths->arraySize);
paths->pathsArray = newArray;
}
*index = paths->pathsCount++;
return 1;
}
Boolean Paths_AddPath(Paths *paths, Path *path) {
UInt16 ni;
if (Paths_GrowPaths(paths, &ni)) {
paths->pathsArray[ni] = path;
return 1;
} else {
return 0;
}
}
Boolean Paths_InsertPath(Paths *paths, UInt16 index, Path *path) {
UInt16 ni;
if (Paths_GrowPaths(paths, &ni)) {
if (index > ni) {
index = (ni != 0) ? (ni - 1) : 0;
}
memmove(&paths->pathsArray[index + 1], &paths->pathsArray[index], sizeof(Path *) * (paths->pathsCount - index));
paths->pathsArray[index] = path;
return 1;
} else {
return 0;
}
}
Boolean Paths_RemovePath(Paths *paths, UInt16 index) {
if (index >= paths->pathsCount)
return 0;
memmove(&paths->pathsArray[index], &paths->pathsArray[index + 1], sizeof(Path *) * (paths->pathsCount - index - 1));
paths->pathsCount--;
return 1;
}
Boolean Paths_DeletePath(Paths *paths, UInt16 index) {
if (index >= paths->pathsCount)
return 0;
Path_Free(paths->pathsArray[index]);
return Paths_RemovePath(paths, index);
}
Path *Paths_GetPath(Paths *paths, UInt16 pathnum) {
OS_ASSERT(151, paths != NULL);
if (pathnum < paths->pathsCount)
return paths->pathsArray[pathnum];
else
return NULL;
}
UInt16 Paths_Count(const Paths *paths) {
OS_ASSERT(161, paths != NULL);
return paths->pathsCount;
}
Boolean Paths_FindPath(const Paths *paths, const Path *path) {
UInt16 idx;
OS_ASSERT(169, paths != NULL);
for (idx = 0; idx < paths->pathsCount; idx++) {
if (paths->pathsArray[idx] == path)
return 1;
}
return 0;
}
Path *Paths_FindPathSpec(const Paths *paths, const OSPathSpec *dir) {
UInt16 idx;
Path *path;
OS_ASSERT(182, paths != NULL);
for (idx = 0; idx < paths->pathsCount; idx++) {
path = paths->pathsArray[idx];
if (OS_EqualPathSpec(path->spec, dir))
return path;
}
return NULL;
}
static Boolean GatherRecurse(Paths *list, Path *path) {
int err;
OSOpenedDir rf;
OSSpec ent;
int count;
char filename[64];
Boolean isfile;
char *nptr;
char *eptr;
UInt16 added;
Path *nw;
count = 0;
if (CheckForUserBreak())
return 1;
err = OS_OpenDir(path->spec, &rf);
while (!err) {
err = OS_ReadDir(&rf, &ent, filename, &isfile);
if (!err) {
if (!isfile) {
nw = Path_New(&ent.path);
nptr = OS_GetFileNamePtr(filename);
eptr = nptr + strlen(nptr) - 1;
if (eptr[0] == OS_PATHSEP)
eptr--;
if (eptr > nptr && *nptr == '(' && *eptr == ')')
continue;
if (!Paths_AddPath(list, nw))
break;
added = Paths_Count(list) - 1;
if (!GatherRecurse(list, nw))
Paths_DeletePath(list, added);
} else {
if (!(++count % 50) && CheckForUserBreak())
return 0;
}
}
}
OS_CloseDir(&rf);
return count > 0;
}
Boolean Paths_GatherRecurse(Path *path) {
path->recursive = xcalloc(NULL, sizeof(Paths));
GatherRecurse(path->recursive, path);
return Paths_Count(path->recursive) != 0;
}
int Paths_CountRecurse(Paths *paths) {
UInt16 idx;
int mine;
Path *path;
mine = Paths_Count(paths);
for (idx = 0; idx < mine; idx++) {
path = Paths_GetPath(paths, idx);
OS_ASSERT(336, path);
if (path->recursive)
mine += Paths_CountRecurse(path->recursive);
}
return mine;
}
static void CopyRecurseFSS(FSSpec **list, Paths *paths, UInt16 *count) {
UInt16 idx;
OSSpec spec;
Path *path;
for (idx = 0; idx < Paths_Count(paths); idx++) {
path = Paths_GetPath(paths, idx);
OS_ASSERT(353, path && *count > 0);
OS_MakeSpecWithPath(path->spec, NULL, 0, &spec);
OS_ASSERT(355, OS_OSSpec_To_FSSpec(&spec, *list));
(*list)++;
(*count)--;
if (path->recursive)
CopyRecurseFSS(list, path->recursive, count);
}
}
void Paths_CopyRecurseFSS(FSSpec *list, Paths *paths, UInt16 count) {
CopyRecurseFSS(&list, paths, &count);
OS_ASSERT(367, count == 0);
}
static Boolean Frameworks_Initialize(Frameworks *fws) {
OS_ASSERT(405, fws != NULL);
memset(fws, 0, sizeof(Frameworks));
fws->fwsArray = NULL;
return 1;
}
static Boolean Frameworks_Grow(Frameworks *fws, UInt16 *index) {
Paths_FWInfo **newArray;
OS_ASSERT(418, fws != NULL);
if (fws->fwsCount >= fws->arraySize) {
fws->arraySize += 20;
newArray = xrealloc("access frameworks", fws->fwsArray, sizeof(Paths_FWInfo *) * fws->arraySize);
fws->fwsArray = newArray;
}
*index = fws->fwsCount++;
return 1;
}
static Boolean Frameworks_Add(Frameworks *fws, Paths_FWInfo *info) {
UInt16 ni;
if (Frameworks_Grow(fws, &ni)) {
fws->fwsArray[ni] = info;
return 1;
} else {
return 0;
}
}
static Paths_FWInfo *Framework_Init(OSSpec *dir, const char *name, const char *version, Paths_FWInfo *info, Path *p, Boolean hidden) {
info->fileSpec = *dir;
if (version && version[0])
strncpy(info->version.s, version, sizeof(info->version.s));
else
info->version.s[0] = 0;
strncpy(info->name.s, name, sizeof(info->name.s));
info->path = p;
info->hidden = hidden;
return info;
}
static Paths_FWInfo *Framework_New(OSSpec *dir, const char *name, const char *version, Path *p, Boolean hidden) {
Paths_FWInfo *info;
info = xmalloc(NULL, sizeof(Paths_FWInfo));
return Framework_Init(dir, name, version, info, p, hidden);
}
static Boolean CheckForFileInFrameworkDir(char *out, const char *framework_path, OSPathSpec *osps, const char *fname) {
int err;
OSSpec oss;
sprintf(out, "%s/%s", framework_path, fname);
err = OS_MakeSpecWithPath(osps, out, 0, &oss);
if (err == 0 && OS_IsFile(&oss))
return 1;
sprintf(out, "%s/Headers/%s", framework_path, fname);
err = OS_MakeSpecWithPath(osps, out, 0, &oss);
if (err == 0 && OS_IsFile(&oss))
return 1;
sprintf(out, "%s/Resources/%s", framework_path, fname);
err = OS_MakeSpecWithPath(osps, out, 0, &oss);
if (err == 0 && OS_IsFile(&oss))
return 1;
sprintf(out, "%s/Resources/%s", framework_path, fname);
err = OS_MakeSpecWithPath(osps, out, 0, &oss);
if (err == 0 && OS_IsFile(&oss))
return 1;
return 0;
}
static Boolean CheckForFileInFramework(char *out, int i, const char *fname) {
Paths_FWInfo *info;
char framework_path[256];
info = Frameworks_GetInfo(i);
if (strlen(info->version.s))
sprintf(framework_path, "%s.framework/Versions/%s", info->name.s, info->version.s);
else
sprintf(framework_path, "%s.framework", info->name.s);
if (CheckForFileInFrameworkDir(out, framework_path, info->path->spec, fname))
return 1;
else
return 0;
}
Boolean MakeFrameworkPath(char *out, const char *filename, Path *globalpath) {
Paths_FWInfo *info;
int err;
char *end;
char *fname;
char framework_name[256];
char framework_path[256];
const char *s;
char *d;
int i;
int n;
n = Frameworks_GetCount();
end = strchr(filename, OS_PATHSEP);
if (!end) {
for (i = 0; i < n; i++) {
info = Frameworks_GetInfo(i);
if (!info->hidden && CheckForFileInFramework(out, i, filename))
return 1;
}
return 0;
}
fname = end + 1;
s = filename;
d = framework_name;
while (s < end)
*(d++) = *(s++);
*d = 0;
for (i = 0; i < n; i++) {
if (!strcmp(Frameworks_GetInfo(i)->name.s, framework_name)) {
return CheckForFileInFramework(out, i, fname) != 0;
}
}
if (globalpath) {
OSSpec oss;
sprintf(framework_path, "../Frameworks/%s.framework", framework_name);
err = OS_MakeSpecWithPath(globalpath->spec, framework_path, 0, &oss);
if (!err && OS_IsDir(&oss)) {
if (CheckForFileInFrameworkDir(out, framework_path, globalpath->spec, fname))
return 1;
}
}
n = Paths_Count(&FrameworkPaths);
sprintf(framework_path, "%s.framework", framework_name);
for (i = 0; i < n; i++) {
OSSpec oss;
Path *p;
p = Paths_GetPath(&FrameworkPaths, i);
err = OS_MakeSpecWithPath(p->spec, framework_path, 0, &oss);
if (!err && OS_IsDir(&oss)) {
if (CheckForFileInFrameworkDir(out, framework_path, p->spec, fname)) {
Frameworks_AddFramework(framework_name, NULL, 1);
return 1;
}
}
}
return 0;
}
void Frameworks_AddPath(const OSPathSpec *oss) {
Paths_AddPath(&FrameworkPaths, Path_New(oss));
}
int Frameworks_AddFramework(const char *name, const char *version, Boolean hidden) {
char fullname[256];
int i;
Path *p;
int n_paths;
OSSpec oss;
int err;
sprintf(fullname, "%s.framework", name);
n_paths = Paths_Count(&FrameworkPaths);
for (i = 0; i < n_paths; i++) {
p = Paths_GetPath(&FrameworkPaths, i);
err = OS_MakeSpecWithPath(p->spec, fullname, 0, &oss);
if (!err && OS_IsDir(&oss)) {
if (Frameworks_Add(&FrameworkInfo, Framework_New(&oss, name, version, p, hidden))) {
if (version && strlen(version)) {
sprintf(fullname, "Versions/%s/Frameworks", version);
err = OS_MakeSpecWithPath(&oss.path, fullname, 0, &oss);
} else {
err = OS_MakeSpecWithPath(&oss.path, "Frameworks", 0, &oss);
}
if (!err && OS_IsDir(&oss))
Frameworks_AddPath(&oss.path);
return 1;
}
}
}
return 0;
}
void Framework_GetEnvInfo(void) {
char path[256];
char *env;
char *ptr;
OSSpec spec;
char name[64];
char version[16];
int err;
Boolean is_file;
OS_ASSERT(672, Paths_Initialize(&FrameworkPaths) == 1);
OS_ASSERT(673, Frameworks_Initialize(&FrameworkInfo) == 1);
env = getenv("MWFrameworkPaths");
if (env) {
while (*env) {
ptr = path;
while (*env && *env != ':' && (ptr + 1) < &path[sizeof(path)])
*(ptr++) = *(env++);
*ptr = 0;
while (*env && *env == ':')
env++;
if (path[0]) {
if (strlen(path) >= sizeof(path)) {
CLReportError(CLStr64, sizeof(path), path);
} else {
err = OS_MakeSpec(path, &spec, &is_file);
if (!is_file && !err) {
Frameworks_AddPath(&spec.path);
} else {
CLReportError(CLStr23, path);
}
}
}
}
}
env = getenv("MWFrameworkVersions");
if (env) {
while (*env) {
ptr = name;
while (*env && *env != ':' && (ptr + 1) < &name[sizeof(name)])
*(ptr++) = *(env++);
*ptr = 0;
while (*env && *env == ':')
env++;
ptr = version;
while (*env && *env != ',' && (ptr + 1) < &version[sizeof(version)])
*(ptr++) = *(env++);
*ptr = 0;
while (*env && *env == ',')
env++;
if (name[0])
Frameworks_AddFramework(name, version, 0);
}
}
}
int Frameworks_GetCount(void) {
return FrameworkInfo.fwsCount;
}
Paths_FWInfo *Frameworks_GetInfo(int which) {
OS_ASSERT(762, FrameworkInfo.fwsArray);
OS_ASSERT(763, FrameworkInfo.fwsCount > which);
return FrameworkInfo.fwsArray[which];
}