diff options
author | Ash Wolf <ninji@wuffs.org> | 2022-10-19 21:16:13 +0100 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2022-10-19 21:16:13 +0100 |
commit | d1f153d34b023d81768f6087f67dbfff714bafc9 (patch) | |
tree | a694d470a60655d0cda15a70791fbdb90a2398cf /command_line/CmdLine/Src/Project/CLAccessPaths.c | |
parent | 775b6861666af36d317fb577cf489e2c6377f878 (diff) | |
download | MWCC-d1f153d34b023d81768f6087f67dbfff714bafc9.tar.gz MWCC-d1f153d34b023d81768f6087f67dbfff714bafc9.zip |
let's commit all this before my VM blows up and nukes my work
Diffstat (limited to 'command_line/CmdLine/Src/Project/CLAccessPaths.c')
-rw-r--r-- | command_line/CmdLine/Src/Project/CLAccessPaths.c | 525 |
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]; +} |