summaryrefslogtreecommitdiff
path: root/command_line/CmdLine/Src/Project/CLAccessPaths.c
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2022-10-19 21:16:13 +0100
committerAsh Wolf <ninji@wuffs.org>2022-10-19 21:16:13 +0100
commitd1f153d34b023d81768f6087f67dbfff714bafc9 (patch)
treea694d470a60655d0cda15a70791fbdb90a2398cf /command_line/CmdLine/Src/Project/CLAccessPaths.c
parent775b6861666af36d317fb577cf489e2c6377f878 (diff)
downloadMWCC-d1f153d34b023d81768f6087f67dbfff714bafc9.tar.gz
MWCC-d1f153d34b023d81768f6087f67dbfff714bafc9.zip
let's commit all this before my VM blows up and nukes my work
Diffstat (limited to '')
-rw-r--r--command_line/CmdLine/Src/Project/CLAccessPaths.c525
1 files changed, 525 insertions, 0 deletions
diff --git a/command_line/CmdLine/Src/Project/CLAccessPaths.c b/command_line/CmdLine/Src/Project/CLAccessPaths.c
index e69de29..1ffcd1d 100644
--- a/command_line/CmdLine/Src/Project/CLAccessPaths.c
+++ b/command_line/CmdLine/Src/Project/CLAccessPaths.c
@@ -0,0 +1,525 @@
+#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) {
+#line 52
+ OPTION_ASSERT(paths != NULL);
+
+ memset(paths, 0, sizeof(Paths));
+ paths->pathsArray = NULL;
+ return 1;
+}
+
+Boolean Paths_Terminate(Paths *paths) {
+ UInt16 index;
+
+#line 63
+ OPTION_ASSERT(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;
+
+#line 84
+ OPTION_ASSERT(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) {
+#line 151
+ OPTION_ASSERT(paths != NULL);
+
+ if (pathnum < paths->pathsCount)
+ return paths->pathsArray[pathnum];
+ else
+ return NULL;
+}
+
+UInt16 Paths_Count(const Paths *paths) {
+#line 161
+ OPTION_ASSERT(paths != NULL);
+
+ return paths->pathsCount;
+}
+
+Boolean Paths_FindPath(const Paths *paths, const Path *path) {
+ UInt16 idx;
+
+#line 169
+ OPTION_ASSERT(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;
+
+#line 182
+ OPTION_ASSERT(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);
+#line 336
+ OPTION_ASSERT(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);
+#line 353
+ OPTION_ASSERT(path && *count > 0);
+ OS_MakeSpecWithPath(path->spec, NULL, 0, &spec);
+#line 355
+ OPTION_ASSERT(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);
+#line 367
+ OPTION_ASSERT(count == 0);
+}
+
+static Boolean Frameworks_Initialize(Frameworks *fws) {
+#line 405
+ OPTION_ASSERT(fws != NULL);
+
+ memset(fws, 0, sizeof(Frameworks));
+ fws->fwsArray = NULL;
+ return 1;
+}
+
+static Boolean Frameworks_Grow(Frameworks *fws, UInt16 *index) {
+ Paths_FWInfo **newArray;
+
+#line 418
+ OPTION_ASSERT(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() {
+ char path[256];
+ char *env;
+ char *ptr;
+ OSSpec spec;
+ char name[64];
+ char version[16];
+ int err;
+ Boolean is_file;
+
+#line 672
+ OPTION_ASSERT(Paths_Initialize(&FrameworkPaths) == 1);
+ OPTION_ASSERT(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(64, sizeof(path), path);
+ } else {
+ err = OS_MakeSpec(path, &spec, &is_file);
+ if (!is_file && !err) {
+ Frameworks_AddPath(&spec.path);
+ } else {
+ CLReportError(23, 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() {
+ return FrameworkInfo.fwsCount;
+}
+
+Paths_FWInfo *Frameworks_GetInfo(int which) {
+#line 762
+ OPTION_ASSERT(FrameworkInfo.fwsArray);
+ OPTION_ASSERT(FrameworkInfo.fwsCount > which);
+ return FrameworkInfo.fwsArray[which];
+}