summaryrefslogtreecommitdiff
path: root/command_line/CmdLine/Src/CLDependencies.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/CLDependencies.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/CLDependencies.c407
1 files changed, 407 insertions, 0 deletions
diff --git a/command_line/CmdLine/Src/CLDependencies.c b/command_line/CmdLine/Src/CLDependencies.c
index e69de29..8c4c13b 100644
--- a/command_line/CmdLine/Src/CLDependencies.c
+++ b/command_line/CmdLine/Src/CLDependencies.c
@@ -0,0 +1,407 @@
+#include "cmdline.h"
+
+extern char STSbuf[256];
+
+static Path *specialAccessPath;
+SInt16 *CLT_filesp;
+CPrepFileInfoStack *CLT_filestack;
+
+// forward decl
+static Boolean FindFileInPaths(Paths *paths, const char *filename, Path **thepath, OSSpec *spec);
+static void SetSpecialAccessPathFromIncludeStackTOS();
+
+Boolean Incls_Initialize(Incls *incls, Target *targ) {
+ specialAccessPath = NULL;
+ incls->targ = targ;
+ incls->maxincls = 0;
+ incls->numincls = 0;
+ incls->bufpos = 0;
+ incls->buflen = 0;
+ incls->buffer = NULL;
+ incls->files = NULL;
+ incls->allPaths = xmalloc(NULL, sizeof(Paths));
+ Paths_Initialize(incls->allPaths);
+ return 1;
+}
+
+void Incls_Terminate(Incls *incls) {
+ if (incls->buffer)
+ xfree(incls->buffer);
+ if (incls->files)
+ xfree(incls->files);
+ Paths_Terminate(incls->allPaths);
+ xfree(incls->allPaths);
+}
+
+static Boolean IsSysIncl(Incls *incls, SInt32 idx) {
+ InclFile *i = &incls->files[idx];
+ return i->syspath;
+}
+
+static void MakeInclFileSpec(Incls *incls, SInt32 idx, OSSpec *spec) {
+ InclFile *f = &incls->files[idx];
+ OS_MakeSpecWithPath(
+ f->globalpath->spec,
+ &incls->buffer[f->filenameoffs],
+ 0,
+ spec);
+}
+
+static Boolean QuickFindFileInIncls(Incls *incls, Boolean fullsearch, const char *filename, OSSpec *spec, SInt32 *index, InclFile **f) {
+ int idx;
+ for (idx = 0; idx < incls->numincls; idx++) {
+ *f = &incls->files[idx];
+ if (OS_EqualPath(&incls->buffer[(*f)->filenameoffs], filename)) {
+ if (fullsearch || (*f)->syspath) {
+ MakeInclFileSpec(incls, idx, spec);
+ *index = idx;
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+static Boolean SameIncl(Incls *incls, SInt32 a, SInt32 b) {
+ InclFile *ia;
+ InclFile *ib;
+ if (a == b)
+ return 1;
+ ia = &incls->files[a];
+ ib = &incls->files[b];
+ return ia->globalpath == ib->globalpath && OS_EqualPath(&incls->buffer[ia->filenameoffs], &incls->buffer[ib->filenameoffs]);
+}
+
+static Path *FindOrAddGlobalInclPath(Paths *paths, OSPathSpec *spec) {
+ Path *path = Paths_FindPathSpec(paths, spec);
+ if (!path) {
+ path = Path_New(spec);
+ Paths_AddPath(paths, path);
+ }
+ return path;
+}
+
+static Boolean _FindFileInPath(Path *path, const char *filename, Path **thepath, OSSpec *spec) {
+ if (!OS_MakeSpecWithPath(path->spec, filename, 0, spec) && OS_IsFile(spec)) {
+ *thepath = path;
+ return 1;
+ }
+
+ if (path->recursive && FindFileInPaths(path->recursive, filename, thepath, spec))
+ return 1;
+
+ return 0;
+}
+
+static Boolean FindFileInPaths(Paths *paths, const char *filename, Path **thepath, OSSpec *spec) {
+ UInt16 idx;
+ Path *path;
+
+ for (idx = 0; idx < Paths_Count(paths); idx++) {
+ path = Paths_GetPath(paths, idx);
+#line 175
+ OPTION_ASSERT(path);
+ if (_FindFileInPath(path, filename, thepath, spec))
+ return 1;
+ }
+
+ return 0;
+}
+
+static void AddFileToIncls(Incls *incls, char *infilename, Boolean syspath, Path *accesspath, Path *globalpath, Path *specialpath, SInt32 *index) {
+ InclFile *f;
+ int fnlen;
+ char *filename;
+ OSSpec spec;
+
+ if (!accesspath && !globalpath)
+ filename = OS_GetFileNamePtr(infilename);
+ else
+ filename = infilename;
+ fnlen = strlen(filename) + 1;
+
+ if (incls->numincls >= incls->maxincls) {
+ incls->maxincls += 16;
+ incls->files = xrealloc("include list", incls->files, sizeof(InclFile) * incls->maxincls);
+ }
+
+ f = &incls->files[incls->numincls];
+ f->filenameoffs = incls->bufpos;
+ f->syspath = syspath;
+ f->accesspath = accesspath;
+ if (globalpath) {
+ f->globalpath = globalpath;
+ } else if (accesspath) {
+ f->globalpath = FindOrAddGlobalInclPath(incls->allPaths, accesspath->spec);
+ } else {
+ OS_MakeFileSpec(infilename, &spec);
+ f->globalpath = FindOrAddGlobalInclPath(incls->allPaths, &spec.path);
+ }
+ f->specialpath = Deps_GetSpecialAccessPath();
+
+ if (incls->bufpos + fnlen > incls->buflen) {
+ incls->buflen += 1024;
+ incls->buffer = xrealloc("include list", incls->buffer, incls->buflen);
+ }
+ strcpy(&incls->buffer[incls->bufpos], filename);
+ incls->bufpos += fnlen;
+ *index = incls->numincls++;
+}
+
+Boolean Incls_FindFileInPaths(Incls *incls, char *filename, Boolean fullsearch, OSSpec *spec, SInt32 *inclidx) {
+ Boolean found;
+ InclFile *incl;
+ Boolean foundglobal;
+ Path *globalpath;
+ Path *accesspath;
+ Path *specialpath;
+ Boolean userpath;
+ char rel_path[256];
+
+ found = 0;
+ if (optsCompiler.includeSearch == 3 && fullsearch)
+ SetSpecialAccessPathFromIncludeStackTOS();
+ *inclidx = -1;
+
+ foundglobal = QuickFindFileInIncls(incls, fullsearch, filename, spec, inclidx, &incl);
+ if (foundglobal) {
+ if (incl->specialpath == specialAccessPath && incl->syspath && !fullsearch)
+ found = 1;
+ else if (!incl->accesspath)
+ foundglobal = 0;
+ }
+
+ if (!found) {
+ accesspath = globalpath = NULL;
+ userpath = fullsearch;
+ if (OS_IsFullPath(filename)) {
+ found = !OS_MakeFileSpec(filename, spec) && !OS_Status(spec);
+ accesspath = globalpath = specialpath = NULL;
+ } else {
+ specialpath = Deps_GetSpecialAccessPath();
+ globalpath = specialpath;
+ if (specialpath) {
+ found = _FindFileInPath(specialpath, filename, &globalpath, spec);
+ accesspath = NULL;
+ }
+ if (!found && foundglobal && incl->syspath && !fullsearch) {
+ globalpath = incl->globalpath;
+ accesspath = incl->accesspath;
+ specialpath = NULL;
+ MakeInclFileSpec(incls, *inclidx, spec);
+ found = 1;
+ }
+ if (!found && fullsearch) {
+ userpath = 1;
+ globalpath = NULL;
+ found = FindFileInPaths(&incls->targ->userPaths, filename, &accesspath, spec);
+ }
+ if (!found) {
+ userpath = 0;
+ globalpath = NULL;
+ found = FindFileInPaths(&incls->targ->sysPaths, filename, &accesspath, spec);
+ }
+ if (!found) {
+ specialpath = Deps_GetSpecialAccessPath();
+ globalpath = specialpath;
+ if (!found && MakeFrameworkPath(rel_path, filename, specialpath)) {
+ filename = rel_path;
+ found = FindFileInPaths(&FrameworkPaths, filename, &globalpath, spec);
+ }
+ }
+ }
+
+ if (found && *inclidx < 0)
+ AddFileToIncls(incls, filename, !userpath, accesspath, globalpath, specialpath, inclidx);
+ }
+
+ return found;
+}
+
+Boolean Deps_Initialize(Deps *deps, Incls *incls) {
+ deps->numDeps = 0;
+ deps->maxDeps = 0;
+ deps->list = NULL;
+ deps->incls = incls;
+ return 1;
+}
+
+void Deps_Terminate(Deps *deps) {
+ if (deps->list)
+ xfree(deps->list);
+}
+
+int Deps_ChangeSpecialAccessPath(OSSpec *srcfss, Boolean initialize) {
+ static OSSpec *currentsrcfss;
+ OSPathSpec pathspec;
+ OSPathSpec *pathspecptr;
+
+ if (initialize && srcfss)
+ currentsrcfss = srcfss;
+
+ switch (optsCompiler.includeSearch) {
+ case IncludeSearch_Type2:
+ specialAccessPath = NULL;
+ return 1;
+ case IncludeSearch_Type0:
+ if (!initialize)
+ return 1;
+ OS_GetCWD(&pathspec);
+ pathspecptr = &pathspec;
+ break;
+ case IncludeSearch_Type1:
+ if (!initialize)
+ return 1;
+ case IncludeSearch_Type3:
+ if (srcfss) {
+ pathspecptr = &srcfss->path;
+ } else if (currentsrcfss) {
+ pathspecptr = &currentsrcfss->path;
+ } else {
+ OS_GetCWD(&pathspec);
+ pathspecptr = &pathspec;
+ }
+ break;
+ default:
+#line 468
+ DO_INTERNAL_ERROR("Unhandled include file search type (%d)\n", optsCompiler.includeSearch);
+ }
+
+ specialAccessPath = FindOrAddGlobalInclPath(gTarg->incls.allPaths, pathspecptr);
+ if (optsCmdLine.verbose > 2)
+ CLReport(105, OS_PathSpecToString(pathspecptr, STSbuf, sizeof(STSbuf)));
+ return 1;
+}
+
+Path *Deps_GetSpecialAccessPath() {
+ return specialAccessPath;
+}
+
+static void SetSpecialAccessPathFromIncludeStackTOS() {
+ // does not match, some registers are in the wrong order
+ OSSpec spec;
+ SInt16 index;
+ char *fnameptr;
+ VFile *vf;
+
+ if (optsCompiler.includeSearch == IncludeSearch_Type3 && CLT_filesp && CLT_filestack) {
+ if (*CLT_filesp >= 0) {
+ index = *CLT_filesp;
+ while (index) {
+ if (!(*CLT_filestack)[index])
+ break;
+ OS_FSSpec_To_OSSpec(&(*CLT_filestack)[index--]->textfile, &spec);
+ fnameptr = OS_GetFileNamePtr(OS_NameSpecToString(&spec.name, STSbuf, sizeof(STSbuf)));
+ vf = VFiles_Find(gTarg->virtualFiles, fnameptr);
+ if (!vf) {
+ if (!specialAccessPath || !OS_EqualPathSpec(&spec.path, specialAccessPath->spec)) {
+ Deps_ChangeSpecialAccessPath(&spec, 0);
+ return;
+ }
+ return;
+ }
+ }
+ }
+ Deps_ChangeSpecialAccessPath(NULL, 0);
+ }
+}
+
+static Boolean FindDepFile(Deps *deps, SInt32 incl) {
+ int idx;
+
+ for (idx = 0; idx < deps->numDeps; idx++) {
+ if (SameIncl(&gTarg->incls, deps->list[idx], incl))
+ return 1;
+ }
+
+ return 0;
+}
+
+static void AddDepFile(Deps *deps, SInt32 incl, SInt16 dependencyType) {
+ if (deps->numDeps >= deps->maxDeps) {
+ deps->maxDeps += 16;
+ deps->list = xrealloc("dependency list", deps->list, sizeof(SInt32) * deps->maxDeps);
+ }
+ deps->list[deps->numDeps++] = incl;
+}
+
+void Deps_AddDependency(Deps *deps, SInt32 incl, OSSpec *spec, Boolean unk, SInt16 dependencyType, Boolean *alreadyincluded) {
+ Boolean included;
+
+ if (incl < 0) {
+ AddFileToIncls(
+ &gTarg->incls,
+ OS_SpecToString(spec, STSbuf, sizeof(STSbuf)),
+ 0,
+ NULL, NULL, NULL,
+ &incl);
+ }
+
+ included = FindDepFile(deps, incl);
+ if (!included) {
+ if (!(optsCompiler.depsOnlyUserFiles ? IsSysIncl(deps->incls, incl) : 0))
+ AddDepFile(deps, incl, dependencyType);
+ }
+
+ if (alreadyincluded)
+ *alreadyincluded = included;
+}
+
+static char *EscapeName(Boolean spaces, char *escbuf, char *path) {
+ char *ret;
+
+ if (!spaces)
+ return path;
+
+ ret = escbuf;
+ while (*path) {
+ if (*path == ' ')
+ *(escbuf++) = '\\';
+ *(escbuf++) = *(path++);
+ }
+ *escbuf = 0;
+ return ret;
+}
+
+void Deps_ListDependencies(Incls *incls, File *file, OSHandle *h) {
+ Boolean spaces;
+ int idx;
+ char linebuf[512];
+ char outfilename[256];
+ int totdeps;
+ char path[256];
+ char escbuf[320];
+ OSSpec spec;
+
+#define LIST_DEP(format, name, ...) \
+do { \
+sprintf(linebuf, format, spaces ? "" : "", EscapeName(spaces, escbuf, (name)), spaces ? "" : "", __VA_ARGS__); \
+if (OS_AppendHandle(h, linebuf, strlen(linebuf))) goto memFail; \
+} while (0)
+
+ if (!OS_NewHandle(0, h)) {
+ totdeps = file->deps.numDeps;
+ OS_SpecToStringRelative(&file->outfss, NULL, outfilename, sizeof(outfilename));
+ if (outfilename[0]) {
+ spaces = strchr(outfilename, ' ') != NULL;
+ LIST_DEP("%s%s%s%s ", outfilename, ":");
+ spaces = strchr(file->srcfilename, ' ') != NULL;
+ LIST_DEP("%s%s%s %s\n", file->srcfilename, totdeps ? "\\" : "");
+ } else {
+ spaces = strchr(file->srcfilename, ' ') != NULL;
+ LIST_DEP("%s%s%s%s %s\n", file->srcfilename, ":", totdeps ? "\\" : "");
+ }
+
+ for (idx = 0; idx < file->deps.numDeps; idx++) {
+ totdeps--;
+ MakeInclFileSpec(incls, file->deps.list[idx], &spec);
+ OS_SpecToString(&spec, path, sizeof(path));
+ spaces = strchr(path, ' ') != NULL;
+ LIST_DEP("\t%s%s%s %s\n", path, totdeps ? "\\" : "");
+ }
+ } else {
+ memFail:
+ fprintf(stderr, "\n*** Out of memory\n");
+ exit(-23);
+ }
+}