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/CLDependencies.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 '')
-rw-r--r-- | command_line/CmdLine/Src/CLDependencies.c | 407 |
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 = ¤tsrcfss->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); + } +} |