357 lines
7.1 KiB
C
357 lines
7.1 KiB
C
|
#define LINT_ARGS
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
#include <ctype.h>
|
||
|
#include <search.h>
|
||
|
#include <sys\types.h>
|
||
|
#include <sys\stat.h>
|
||
|
|
||
|
#include "mbrmake.h"
|
||
|
|
||
|
#define LONGESTPATH 128
|
||
|
|
||
|
#define SLASH "\\"
|
||
|
#define SLASHCHAR '\\'
|
||
|
#define XSLASHCHAR '/'
|
||
|
|
||
|
WORD near cAtomsMac; // total number of atoms
|
||
|
WORD near cModulesMac; // total number of modules
|
||
|
WORD near cSymbolsMac; // total number of symbols
|
||
|
|
||
|
static char *tmpl = "XXXXXX";
|
||
|
|
||
|
extern WORD HashAtomStr (char *);
|
||
|
|
||
|
// rjsa LPCH GetAtomStr (VA vaSym);
|
||
|
|
||
|
void
|
||
|
SeekError (char *pfilenm)
|
||
|
// couldn't seek to position ... emit error message
|
||
|
//
|
||
|
{
|
||
|
Error(ERR_SEEK_FAILED, pfilenm);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
ReadError (char *pfilenm)
|
||
|
// couldn't read from file... emit error message
|
||
|
//
|
||
|
{
|
||
|
Error(ERR_READ_FAILED, pfilenm);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
WriteError (char *pfilenm)
|
||
|
// couldn't write to file ... emit error message
|
||
|
//
|
||
|
{
|
||
|
Error(ERR_WRITE_FAILED, pfilenm);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
FindTmp (char *pbuf) /* copy TMP path to pbuf if exists */
|
||
|
//
|
||
|
//
|
||
|
{
|
||
|
char ebuf[LONGESTPATH];
|
||
|
char *env = ebuf;
|
||
|
|
||
|
*pbuf = '\0';
|
||
|
*env = '\0';
|
||
|
|
||
|
// if (!(env = getenv("TMP")))
|
||
|
if (!(env = getenvOem("TMP")))
|
||
|
return; /* no path, return */
|
||
|
|
||
|
// env = strncpy(ebuf, env, LONGESTPATH-1);
|
||
|
strncpy(ebuf, env, LONGESTPATH-1);
|
||
|
free( env );
|
||
|
env = ebuf;
|
||
|
ebuf[LONGESTPATH-1] = '\0';
|
||
|
|
||
|
if (!( env = ebuf ) )
|
||
|
return;
|
||
|
|
||
|
env = ebuf + strcspn(ebuf, ";");
|
||
|
if (*env == ';')
|
||
|
*env = '\0';
|
||
|
|
||
|
if (env != ebuf) {
|
||
|
env--;
|
||
|
if (*env != SLASHCHAR
|
||
|
&& *env != XSLASHCHAR)
|
||
|
strcat(ebuf, SLASH);
|
||
|
}
|
||
|
strcpy (pbuf, ebuf);
|
||
|
}
|
||
|
|
||
|
|
||
|
char *
|
||
|
MakTmpFileName (char *pext)
|
||
|
// Create a temporary file with the extension supplied.
|
||
|
// returns a pointer to the file name on the heap.
|
||
|
//
|
||
|
{
|
||
|
char ptmpnam[96];
|
||
|
char btmpl[7];
|
||
|
char *p;
|
||
|
|
||
|
strcpy (btmpl, tmpl);
|
||
|
p = mktemp(btmpl);
|
||
|
FindTmp (ptmpnam);
|
||
|
strcat (ptmpnam, p);
|
||
|
free (p);
|
||
|
strcat (ptmpnam, pext); /* /tmp/xxxxxx.ext file */
|
||
|
return (LszDup(ptmpnam));
|
||
|
}
|
||
|
|
||
|
LSZ
|
||
|
LszBaseName (LSZ lsz)
|
||
|
// return the base name part of a path
|
||
|
//
|
||
|
{
|
||
|
LPCH lpch;
|
||
|
|
||
|
lpch = strrchr(lsz, '\\');
|
||
|
if (lpch) return lpch+1;
|
||
|
if (lsz[1] == ':')
|
||
|
return lsz+2;
|
||
|
|
||
|
return lsz;
|
||
|
}
|
||
|
|
||
|
VA
|
||
|
VaSearchModule (char *p)
|
||
|
// search for the named module in the module list
|
||
|
//
|
||
|
{
|
||
|
VA vaMod;
|
||
|
LSZ lsz, lszBase;
|
||
|
char buf[PATH_BUF];
|
||
|
|
||
|
strcpy(buf, ToAbsPath(p, r_cwd));
|
||
|
lszBase = LszBaseName(buf);
|
||
|
|
||
|
SetVMClient(VM_SEARCH_MOD);
|
||
|
|
||
|
vaMod = vaRootMod;
|
||
|
|
||
|
while (vaMod) {
|
||
|
gMOD(vaMod);
|
||
|
|
||
|
lsz = GetAtomStr(cMOD.vaNameSym);
|
||
|
|
||
|
if (strcmpi(LszBaseName(lsz), lszBase) == 0 &&
|
||
|
strcmpi(buf,ToAbsPath(lsz, c_cwd)) == 0) {
|
||
|
SetVMClient(VM_MISC);
|
||
|
return (vaMod);
|
||
|
}
|
||
|
vaMod = cMOD.vaNextMod;
|
||
|
}
|
||
|
SetVMClient(VM_MISC);
|
||
|
return vaNil;
|
||
|
}
|
||
|
|
||
|
VA
|
||
|
VaSearchModuleExact (char *p)
|
||
|
// search for the named module in the module list -- EXACT match only
|
||
|
//
|
||
|
{
|
||
|
VA vaMod;
|
||
|
|
||
|
SetVMClient(VM_SEARCH_MOD);
|
||
|
|
||
|
vaMod = vaRootMod;
|
||
|
|
||
|
while (vaMod) {
|
||
|
gMOD(vaMod);
|
||
|
|
||
|
if (strcmp(p,GetAtomStr(cMOD.vaNameSym)) == 0) {
|
||
|
SetVMClient(VM_MISC);
|
||
|
return (vaMod);
|
||
|
}
|
||
|
vaMod = cMOD.vaNextMod;
|
||
|
}
|
||
|
SetVMClient(VM_MISC);
|
||
|
return vaNil;
|
||
|
}
|
||
|
|
||
|
VA
|
||
|
VaSearchSymbol (char *pStr)
|
||
|
// search for the named symbol (not a module!)
|
||
|
//
|
||
|
{
|
||
|
WORD hashid;
|
||
|
VA vaRootSym, vaSym;
|
||
|
LSZ lszAtom;
|
||
|
|
||
|
SetVMClient(VM_SEARCH_SYM);
|
||
|
|
||
|
vaRootSym = rgVaSym[hashid = HashAtomStr (pStr)];
|
||
|
|
||
|
if (vaRootSym) {
|
||
|
vaSym = vaRootSym;
|
||
|
while (vaSym) {
|
||
|
|
||
|
gSYM(vaSym);
|
||
|
lszAtom = gTEXT(cSYM.vaNameText);
|
||
|
|
||
|
if (strcmp (pStr, lszAtom) == 0) {
|
||
|
SetVMClient(VM_MISC);
|
||
|
return (vaSym); // Duplicate entry
|
||
|
}
|
||
|
|
||
|
vaSym = cSYM.vaNextSym; // current = next
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SetVMClient(VM_MISC);
|
||
|
return vaNil;
|
||
|
}
|
||
|
|
||
|
LPCH
|
||
|
GetAtomStr (VA vaSym)
|
||
|
// Swap in the Atom page for the symbol chain entry pSym
|
||
|
// Return the atom's address in the page.
|
||
|
//
|
||
|
{
|
||
|
gSYM(vaSym);
|
||
|
return gTEXT(cSYM.vaNameText);
|
||
|
}
|
||
|
|
||
|
VA
|
||
|
MbrAddAtom (char *pStr, char fFILENM)
|
||
|
// create a new symbol with the given name
|
||
|
//
|
||
|
{
|
||
|
WORD hashid;
|
||
|
VA vaSym, vaSymRoot, vaText;
|
||
|
|
||
|
if (!fFILENM)
|
||
|
vaSymRoot = rgVaSym[hashid = HashAtomStr (pStr)];
|
||
|
else
|
||
|
vaSymRoot = rgVaSym[hashid = MAXSYMPTRTBLSIZ - 1];
|
||
|
|
||
|
SetVMClient(VM_SEARCH_SYM);
|
||
|
|
||
|
if (vaSymRoot) {
|
||
|
vaSym = vaSymRoot;
|
||
|
while (vaSym) {
|
||
|
gSYM(vaSym);
|
||
|
|
||
|
if (!strcmp (pStr, GetAtomStr(vaSym))) {
|
||
|
#if defined (DEBUG)
|
||
|
if (OptD & 2)
|
||
|
printf("MbrAddAtom: duplicate (%s)\n", pStr);
|
||
|
#endif
|
||
|
SetVMClient(VM_SEARCH_SYM);
|
||
|
return (vaSym); // Duplicate entry
|
||
|
}
|
||
|
|
||
|
vaSym = cSYM.vaNextSym; // current = next
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// we are now going to have to add the symbol
|
||
|
|
||
|
|
||
|
if (fFILENM) {
|
||
|
SetVMClient(VM_ADD_MOD);
|
||
|
cModulesMac++;
|
||
|
}
|
||
|
else {
|
||
|
SetVMClient(VM_ADD_SYM);
|
||
|
cSymbolsMac++;
|
||
|
}
|
||
|
|
||
|
cAtomsMac++;
|
||
|
|
||
|
vaSym = VaAllocGrpCb(grpSym, sizeof(SYM));
|
||
|
vaText = VaAllocGrpCb(grpText, strlen(pStr) + 1);
|
||
|
|
||
|
gSYM(vaSym);
|
||
|
cSYM.vaNameText = vaText;
|
||
|
cSYM.vaNextSym = rgVaSym[hashid];
|
||
|
pSYM(vaSym);
|
||
|
|
||
|
rgVaSym[hashid] = vaSym;
|
||
|
|
||
|
strcpy(gTEXT(vaText), pStr);
|
||
|
|
||
|
pTEXT(vaText);
|
||
|
|
||
|
SetVMClient(VM_MISC);
|
||
|
|
||
|
return (vaSym);
|
||
|
}
|
||
|
|
||
|
VA FAR * near rgvaSymSorted;
|
||
|
|
||
|
// rjsa int CmpSym(VA FAR *lhsym1, VA FAR *lhsym2);
|
||
|
|
||
|
void
|
||
|
SortAtoms ()
|
||
|
// create the "subscript sort" array pointers rgvaSymSorted
|
||
|
//
|
||
|
{
|
||
|
VA vaSym;
|
||
|
char buf[PATH_BUF];
|
||
|
WORD i, iSym;
|
||
|
|
||
|
SetVMClient(VM_SORT_ATOMS);
|
||
|
|
||
|
rgvaSymSorted = (VA FAR *)LpvAllocCb(cAtomsMac * sizeof(VA));
|
||
|
|
||
|
iSym = 0;
|
||
|
for (i=0; i < MAXSYMPTRTBLSIZ; i++) {
|
||
|
vaSym = rgVaSym[i];
|
||
|
while (vaSym) {
|
||
|
gSYM(vaSym);
|
||
|
rgvaSymSorted[iSym] = cSYM.vaNameText;
|
||
|
vaSym = cSYM.vaNextSym;
|
||
|
iSym++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// sort symbols
|
||
|
qsort(rgvaSymSorted, cSymbolsMac, sizeof(VA), CmpSym);
|
||
|
|
||
|
// the files are in the last hash bucket so they went to the
|
||
|
// end of this array we just made -- we sort them separately
|
||
|
|
||
|
// sort files
|
||
|
qsort(rgvaSymSorted + cSymbolsMac, cModulesMac, sizeof(VA), CmpSym);
|
||
|
|
||
|
// convert the Page/Atom values back to virtual symbol addresses
|
||
|
for (i=0; i < cSymbolsMac; i++) {
|
||
|
strcpy(buf, gTEXT(rgvaSymSorted[i]));
|
||
|
rgvaSymSorted[i] = VaSearchSymbol(buf);
|
||
|
}
|
||
|
|
||
|
for (; i < cAtomsMac; i++) {
|
||
|
strcpy(buf, gTEXT(rgvaSymSorted[i]));
|
||
|
#ifdef DEBUG
|
||
|
if (OptD & 64) printf("Module: %s\n", buf);
|
||
|
#endif
|
||
|
rgvaSymSorted[i] = (VaSearchModuleExact(buf), cMOD.vaNameSym);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int __cdecl
|
||
|
CmpSym (VA FAR *sym1, VA FAR *sym2)
|
||
|
// compare two symbols given their pointers
|
||
|
//
|
||
|
{
|
||
|
register char far *lpch1, *lpch2;
|
||
|
register int cmp;
|
||
|
|
||
|
lpch1 = gTEXT(*sym1); // LRU will not page out lpch1
|
||
|
lpch2 = gTEXT(*sym2);
|
||
|
|
||
|
cmp = strcmpi(lpch1, lpch2);
|
||
|
|
||
|
if (cmp) return cmp;
|
||
|
|
||
|
return strcmp(lpch1, lpch2);
|
||
|
}
|