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); +    } +}  | 
