mirror of https://git.wuffs.org/MWCC
408 lines
12 KiB
C
408 lines
12 KiB
C
#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);
|
|
}
|
|
}
|