|
|
/***********************************************************************
* Microsoft (R) 32-Bit Incremental Linker * * Copyright (C) Microsoft Corp 1992-95. All rights reserved. * * File: defaultl.cpp * * File Comments: * * The default library handling routines. * ***********************************************************************/
#include "link.h"
STATIC BOOL FMatchDefaultLib(const char *szName, DL *pdl);
PLIB FindLib(const char *sz, LIBS *plibs) // Calls PlibFind to locate a lib with same name
//
{ char szDrive[_MAX_DRIVE]; char szDir[_MAX_DIR]; char szFname[_MAX_FNAME]; char szExt[_MAX_EXT]; char szPath[_MAX_PATH];
_splitpath(sz, szDrive, szDir, szFname, szExt);
if (szExt[0] == '\0') { strcpy(szExt, ".lib"); }
_makepath(szPath, szDrive, szDir, szFname, szExt);
return(PlibFind(szPath, plibs->plibHead, (szDrive[0] == '\0' && szDir[0] == '\0'))); }
VOID NoDefaultLib(const char *szName, LIBS *plibs) // Removes a .lib (if present) from the default libs for *plibs, and
// prevents it from becoming a default lib in the future.
//
// If szName is NULL then all default libs are removed and suppressed.
//
{ DL **ppdl; BOOL fFound;
assert(!fIncrDbFile);
if (plibs->fNoDefaultLibs) { // all defaultlibs are turned off ... don't bother
return; }
if (szName == NULL) { VERBOSE(Message(NODEFLIB)); plibs->fNoDefaultLibs = TRUE; return; }
fFound = FALSE; for (ppdl = &plibs->pdlFirst; *ppdl != NULL; ppdl = &(*ppdl)->pdlNext) { if (FMatchDefaultLib(szName, *ppdl)) { (*ppdl)->flags |= LIB_DontSearch; fFound = TRUE; } }
if (!fFound) { // Add a record to remember that this defaultlib is turned off.
*ppdl = (DL *) Malloc(sizeof(DL)); (*ppdl)->pdlNext = NULL;
(*ppdl)->szName = Strdup(szName); (*ppdl)->flags = LIB_DontSearch; (*ppdl)->pmod = NULL; }
VERBOSE(Message(NODEFLIBLIB, szName)); }
VOID MakeDefaultLib(const char *szName, LIBS *plibs) // Creates a defaultlib for the specified name, if we haven't already seen a
// nodefaultlib for it.
//
{ DL **ppdl;
assert(!fIncrDbFile);
if (plibs->fNoDefaultLibs) { return; }
for (ppdl = &plibs->pdlFirst; *ppdl != NULL; ppdl = &(*ppdl)->pdlNext) { if (FMatchDefaultLib(szName, *ppdl)) { // Either it's already there or its negation is already there.
//
(*ppdl)->flags |= LIB_Default; return; } }
*ppdl = (DL *) Malloc(sizeof(DL)); (*ppdl)->pdlNext = NULL;
(*ppdl)->szName = Strdup(szName); (*ppdl)->flags = LIB_Default; (*ppdl)->pmod = NULL;
VERBOSE(Message(DEFLIB, szName)); }
VOID ExcludeLib(const char *szName, LIBS *plibs, PMOD pmod) // Creates a excludelib for the specified name, if we haven't already seen a
// nodefaultlib for it.
//
{ DL **ppdl;
assert(!fIncrDbFile);
if (plibs->fNoDefaultLibs) { return; }
for (ppdl = &plibs->pdlFirst; *ppdl != NULL; ppdl = &(*ppdl)->pdlNext) { if (FMatchDefaultLib(szName, *ppdl)) { // it's already there.
//
(*ppdl)->flags |= LIB_Exclude; return; } }
*ppdl = (DL *) Malloc(sizeof(DL)); (*ppdl)->pdlNext = NULL;
(*ppdl)->szName = Strdup(szName); (*ppdl)->flags = LIB_Exclude; (*ppdl)->pmod = pmod;
VERBOSE(Message(EXCLUDELIB, szName)); }
STATIC BOOL FMatchDefaultLib(const char *szName, DL *pdl) // Determine identity of a name with an existing defaultlib.
// This is used for matching -defaultlib:foo with -nodefaultlib:foo.
//
// Algorithm: case-insensitive comparison, ignoring trailing .lib.
{ size_t cch1; size_t cch2;
cch1 = strlen(szName);
if ((cch1 >= 4) && (_stricmp(&szName[cch1 - 4], ".lib") == 0)) { cch1 -= 4; }
cch2 = strlen(pdl->szName);
if ((cch2 >= 4) && (_stricmp(&pdl->szName[cch2 - 4], ".lib") == 0)) { cch2 -= 4; }
return((cch1 == cch2) && (_strnicmp(szName, pdl->szName, cch1) == 0)); }
PLIB PlibInstantiateDefaultLib(PLIBS plibs) // Convert the first valid defaultlib into a LIB. This means we will attempt
// to link it.
//
// Returns NULL if none exists.
{ DL *pdl;
if (plibs->fNoDefaultLibs) { return NULL; }
for (pdl = plibs->pdlFirst; pdl != NULL; pdl = pdl->pdlNext) { LIB *plib;
if (pdl->flags & LIB_DontSearch) { continue; // this one is turned off
}
if (!(pdl->flags & LIB_Default)) { continue; // this one never got added as a default lib
}
if (pdl->flags & LIB_Processed) { continue; // this one already done
}
pdl->flags |= LIB_Processed; // we either instantiate this one or throw it away
plib = FindLib(pdl->szName, plibs); // look if the lib has already been searched
if (plib == NULL) { char *sz; struct _stat statfile;
// Name does not match a lib which is already linked.
sz = SzSearchEnv("LIB", pdl->szName, LIB_EXT); plib = PlibNew(sz, 0L, plibs); assert(plib);
if (_stat(sz, &statfile) == -1) { Fatal(NULL, CANTOPENFILE, sz); }
plib->TimeStamp = statfile.st_mtime; plib->flags |= LIB_Default;
if (szReproDir != NULL) { CopyFileToReproDir(sz, FALSE); }
return(plib); } }
return NULL; // didn't find one
}
DL * PdlFind(const char *sz, DL *pdlFirst) // checks to see if lib is on pdl
{ DL *pdl;
for (pdl = pdlFirst; pdl != NULL; pdl = pdl->pdlNext) { if (FMatchDefaultLib(sz, pdl)) { // found a match
return pdl; } }
return NULL; }
|