From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- private/utils/mep/browser/bsc/bsc.c | 734 +++++++++++++++++++ private/utils/mep/browser/bsc/bscdump.c | 114 +++ private/utils/mep/browser/bsc/calltree.c | 213 ++++++ private/utils/mep/browser/bsc/dump.c | 99 +++ private/utils/mep/browser/bsc/filter.c | 44 ++ private/utils/mep/browser/bsc/format.c | 112 +++ private/utils/mep/browser/bsc/listref.c | 185 +++++ private/utils/mep/browser/bsc/makefile | 6 + private/utils/mep/browser/bsc/outline.c | 101 +++ private/utils/mep/browser/bsc/printf.c | 114 +++ private/utils/mep/browser/bsc/query.c | 575 +++++++++++++++ private/utils/mep/browser/bsc/revtree.c | 198 +++++ private/utils/mep/browser/bsc/sources | 26 + private/utils/mep/browser/bsc/stats.c | 96 +++ private/utils/mep/browser/bsc/wild.c | 73 ++ private/utils/mep/browser/bscdump/bscdump.c | 324 +++++++++ private/utils/mep/browser/bscdump/bscdump.h | 15 + private/utils/mep/browser/bscdump/makefile | 6 + private/utils/mep/browser/bscdump/sources | 21 + private/utils/mep/browser/bscdump/thunk.c | 174 +++++ private/utils/mep/browser/dirs | 25 + private/utils/mep/browser/inc/bsc.h | 228 ++++++ private/utils/mep/browser/inc/bscsup.h | 106 +++ private/utils/mep/browser/inc/hungary.h | 31 + private/utils/mep/browser/inc/mbrcache.h | 7 + private/utils/mep/browser/inc/sbrbsc.h | 43 ++ private/utils/mep/browser/inc/sbrfdef.h | 65 ++ private/utils/mep/browser/inc/sbrvers.h | 7 + private/utils/mep/browser/mbrmake/addtolst.c | 1004 ++++++++++++++++++++++++++ private/utils/mep/browser/mbrmake/casts.h | 22 + private/utils/mep/browser/mbrmake/convert.c | 266 +++++++ private/utils/mep/browser/mbrmake/dcodesbr.c | 148 ++++ private/utils/mep/browser/mbrmake/errors.h | 20 + private/utils/mep/browser/mbrmake/extern.h | 83 +++ private/utils/mep/browser/mbrmake/getsbrec.c | 165 +++++ private/utils/mep/browser/mbrmake/list.c | 284 ++++++++ private/utils/mep/browser/mbrmake/list.h | 41 ++ private/utils/mep/browser/mbrmake/makefile | 6 + private/utils/mep/browser/mbrmake/mbrhash.c | 41 ++ private/utils/mep/browser/mbrmake/mbrmake.c | 756 +++++++++++++++++++ private/utils/mep/browser/mbrmake/mbrmake.h | 246 +++++++ private/utils/mep/browser/mbrmake/mbrwbsc.c | 782 ++++++++++++++++++++ private/utils/mep/browser/mbrmake/ord.c | 116 +++ private/utils/mep/browser/mbrmake/owner.c | 76 ++ private/utils/mep/browser/mbrmake/profile.h | 58 ++ private/utils/mep/browser/mbrmake/readbsc.c | 790 ++++++++++++++++++++ private/utils/mep/browser/mbrmake/sbrproto.h | 61 ++ private/utils/mep/browser/mbrmake/sbrx.c | 357 +++++++++ private/utils/mep/browser/mbrmake/sources | 31 + private/utils/mep/browser/mbrmake/vm.c | 197 +++++ private/utils/mep/browser/mbrmake/vm.h | 67 ++ 51 files changed, 9359 insertions(+) create mode 100644 private/utils/mep/browser/bsc/bsc.c create mode 100644 private/utils/mep/browser/bsc/bscdump.c create mode 100644 private/utils/mep/browser/bsc/calltree.c create mode 100644 private/utils/mep/browser/bsc/dump.c create mode 100644 private/utils/mep/browser/bsc/filter.c create mode 100644 private/utils/mep/browser/bsc/format.c create mode 100644 private/utils/mep/browser/bsc/listref.c create mode 100644 private/utils/mep/browser/bsc/makefile create mode 100644 private/utils/mep/browser/bsc/outline.c create mode 100644 private/utils/mep/browser/bsc/printf.c create mode 100644 private/utils/mep/browser/bsc/query.c create mode 100644 private/utils/mep/browser/bsc/revtree.c create mode 100644 private/utils/mep/browser/bsc/sources create mode 100644 private/utils/mep/browser/bsc/stats.c create mode 100644 private/utils/mep/browser/bsc/wild.c create mode 100644 private/utils/mep/browser/bscdump/bscdump.c create mode 100644 private/utils/mep/browser/bscdump/bscdump.h create mode 100644 private/utils/mep/browser/bscdump/makefile create mode 100644 private/utils/mep/browser/bscdump/sources create mode 100644 private/utils/mep/browser/bscdump/thunk.c create mode 100644 private/utils/mep/browser/dirs create mode 100644 private/utils/mep/browser/inc/bsc.h create mode 100644 private/utils/mep/browser/inc/bscsup.h create mode 100644 private/utils/mep/browser/inc/hungary.h create mode 100644 private/utils/mep/browser/inc/mbrcache.h create mode 100644 private/utils/mep/browser/inc/sbrbsc.h create mode 100644 private/utils/mep/browser/inc/sbrfdef.h create mode 100644 private/utils/mep/browser/inc/sbrvers.h create mode 100644 private/utils/mep/browser/mbrmake/addtolst.c create mode 100644 private/utils/mep/browser/mbrmake/casts.h create mode 100644 private/utils/mep/browser/mbrmake/convert.c create mode 100644 private/utils/mep/browser/mbrmake/dcodesbr.c create mode 100644 private/utils/mep/browser/mbrmake/errors.h create mode 100644 private/utils/mep/browser/mbrmake/extern.h create mode 100644 private/utils/mep/browser/mbrmake/getsbrec.c create mode 100644 private/utils/mep/browser/mbrmake/list.c create mode 100644 private/utils/mep/browser/mbrmake/list.h create mode 100644 private/utils/mep/browser/mbrmake/makefile create mode 100644 private/utils/mep/browser/mbrmake/mbrhash.c create mode 100644 private/utils/mep/browser/mbrmake/mbrmake.c create mode 100644 private/utils/mep/browser/mbrmake/mbrmake.h create mode 100644 private/utils/mep/browser/mbrmake/mbrwbsc.c create mode 100644 private/utils/mep/browser/mbrmake/ord.c create mode 100644 private/utils/mep/browser/mbrmake/owner.c create mode 100644 private/utils/mep/browser/mbrmake/profile.h create mode 100644 private/utils/mep/browser/mbrmake/readbsc.c create mode 100644 private/utils/mep/browser/mbrmake/sbrproto.h create mode 100644 private/utils/mep/browser/mbrmake/sbrx.c create mode 100644 private/utils/mep/browser/mbrmake/sources create mode 100644 private/utils/mep/browser/mbrmake/vm.c create mode 100644 private/utils/mep/browser/mbrmake/vm.h (limited to 'private/utils/mep/browser') diff --git a/private/utils/mep/browser/bsc/bsc.c b/private/utils/mep/browser/bsc/bsc.c new file mode 100644 index 000000000..b611e591a --- /dev/null +++ b/private/utils/mep/browser/bsc/bsc.c @@ -0,0 +1,734 @@ +// +// bsc.c -- manage queries on the database +// +// Copyright 1988, Microsoft Corporation +// +// Revision History: +// +// + +#include +#include +#include +#include +#include +#define LINT_ARGS +#if defined(OS2) +#define INCL_NOCOMMON +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#define INCL_DOSMISC +#include +#include +#else +#include +#endif + + + +#include "hungary.h" +#include "mbrcache.h" +#include "version.h" +#include "sbrbsc.h" +#include "bsc.h" + +#define LISTALLOC 50 // Browser max list size + +// static data + +static FILEHANDLE fhBSC = (FILEHANDLE)(-1); // .BSC file handle + +static BYTE fCase; // TRUE for case compare +static BYTE MaxSymLen; // longest symbol length +static WORD ModCnt; // count of modules + +static ISYM Unknown; // UNKNOWN symbol index + +static WORD ModSymCnt; // count of modsyms +static WORD SymCnt; // count of symbols +static WORD PropCnt; // count of properties +static DWORD RefCnt; // count of references +static WORD DefCnt; // count of definitions +static WORD CalCnt; // count of calls +static WORD CbyCnt; // count of called bys +static WORD lastAtomPage; // last atom page # +static WORD lastAtomCnt; // last atom page size + +static WORD cbModSymCnt; // size of list of modsyms +static WORD cbSymCnt; // size of list of symbols +static WORD cbPropCnt; // size of list of properties +static WORD cbRefCnt; // size of list of references +static WORD cbDefCnt; // size of list of definitions +static WORD cbCalCnt; // size of list of calls +static WORD cbCbyCnt; // size of list of called bys + +static WORD MaxModSymCnt; // max list of modsyms +static WORD MaxSymCnt; // max list of symbols +static WORD MaxPropCnt; // max list of properties +static WORD MaxRefCnt; // max list of references +static WORD MaxDefCnt; // max list of references +static WORD MaxCalCnt; // max list of calls +static WORD MaxCbyCnt; // max list of called bys + +static DWORD lbModSymList; // modsym list file start +static DWORD lbSymList; // symbol list file start +static DWORD lbPropList; // property list file start +static DWORD lbRefList; // reference list file start +static DWORD lbDefList; // def'n list file start +static DWORD lbCalList; // calls list file start +static DWORD lbCbyList; // call bys list file start +static DWORD lbSbrList; // sbr list file start +static DWORD lbAtomCache; // atom cache file start + +static WORD CurModSymPage = 0; // Current page of modsyms +static WORD CurSymPage = 0; // Current page of symbols +static WORD CurPropPage = 0; // Current page of properties +static WORD CurRefPage = 0; // Current page of references +static WORD CurDefPage = 0; // Current page of definitions +static WORD CurCalPage = 0; // Current page of calls +static WORD CurCbyPage = 0; // Current page of called bys + +static LSZ lszBSCName = NULL; // name of .bsc file + +static MODLIST far *pfModList = NULL; // module list cache start +static MODSYMLIST far *pfModSymList = NULL; // modsym list cache start +static SYMLIST far *pfSymList = NULL; // symbol list cache start +static PROPLIST far *pfPropList = NULL; // property list cache start +static REFLIST far *pfRefList = NULL; // reference list cache start +static REFLIST far *pfDefList = NULL; // def'n list cache start +static USELIST far *pfCalList = NULL; // calls list cache start +static USELIST far *pfCbyList = NULL; // call bys list cache start + +static WORD AtomPageTblMac = 0; // last cache page used +static CACHEPAGE AtomPageTbl[MAXATOMPAGETBL]; // Atom Cache table + +#define bMOD(imod) (pfModList[imod]) +#define bMODSYM(isym) (pfModSymList[isym]) +#define bSYM(isym) (pfSymList[isym]) +#define bPROP(iprop) (pfPropList[iprop]) + +#define bREF(iref) (pfRefList[iref]) +#define bDEF(idef) (pfDefList[idef]) + +#define bCAL(iuse) (pfCalList[iuse]) +#define bCBY(iuse) (pfCbyList[iuse]) +#define bUSE(iuse) (pfCalList[iuse]) +#define bUBY(iuse) (pfCbyList[iuse]) + +// prototypes +// + +#define BSCIn(v) ReadBSC(&v, sizeof(v)); + +static VOID GetBSC (DWORD lpos, LPV lpv, WORD cb); +static VOID ReadBSC(LPV lpv, WORD cb); +static WORD SwapPAGE (DWORD, LPV, WORD, WORD, WORD *, DWORD); +static LPCH GetAtomCache (WORD); + +static VOID +ReadBSC(LPV lpv, WORD cb) +// read a block of data from the BSC file +// +{ + if (BSCRead(fhBSC, lpv, cb) != cb) + ReadError(lszBSCName); +} + +static VOID +GetBSC(DWORD lpos, LPV lpv, WORD cb) +// Read a block of the specified size from the specified position +// +{ +#if defined (OS2) + if (BSCSeek(fhBSC, lpos, SEEK_SET) == -1) +#else + if (BSCSeek(fhBSC, lpos, FILE_BEGIN) == -1) + SeekError(lszBSCName); +#endif + + if (BSCRead(fhBSC, lpv, cb) != cb) + ReadError(lszBSCName); +} + +static WORD +SwapPAGE (DWORD lbuflist, LPV pfTABLE, WORD tblsiz, +/* */ WORD lstsiz, WORD * pcurpage, DWORD idx) +// +// +// SwapPAGE - Swap in the table page for the table pfTABLE[idx] +// and return the table's new index in the page. +{ + WORD page; + WORD newidx; + + page = (WORD)(idx / lstsiz); + newidx = (WORD)(idx % lstsiz); + + if (page == *pcurpage) + return newidx; + + GetBSC(lbuflist+((long)tblsiz*(long)page), pfTABLE, tblsiz); + + *pcurpage = page; + return newidx; +} + +static WORD +ModSymPAGE (IMOD imod) +// Swap in the ModSym page for ModSym[imod] +// return the ModSym's index in the page. +// +{ + return SwapPAGE (lbModSymList, pfModSymList, + cbModSymCnt, MaxModSymCnt, &CurModSymPage, (IDX)imod); +} + +static WORD +SymPAGE (ISYM isym) +// Swap in the Symbol page for symbol[isym] +// return the Symbol's index in the page. +// +{ + return SwapPAGE (lbSymList, pfSymList, + cbSymCnt, MaxSymCnt, &CurSymPage, (IDX)isym); +} + +static WORD +PropPAGE (IINST iinst) +// Swap in the Property page for Property[idx] +// return the Property's index in the page. +// +{ + return SwapPAGE (lbPropList, pfPropList, + cbPropCnt, MaxPropCnt, &CurPropPage, (IDX)iinst); +} + +static WORD +RefPAGE (IREF iref) +// Swap in the Reference page for Reference[idx] +// return the Reference's index in the page. +// +{ + return SwapPAGE (lbRefList, pfRefList, + cbRefCnt, MaxRefCnt, &CurRefPage, (IDX)iref); +} + +static WORD +DefPAGE (IDEF idef) +// Swap in the Deference page for Definition[idef] +// return the Definitions index in the page. +// +{ + return SwapPAGE (lbDefList, pfDefList, + cbDefCnt, MaxDefCnt, &CurDefPage, (IDX)idef); +} + +static WORD +CalPAGE (IUSE iuse) +// Swap in the Usage page for Usage[iuse] (cal/cby) +// and return the Usage's index in the page. +// +{ + return SwapPAGE (lbCalList, pfCalList, + cbCalCnt, MaxCalCnt, &CurCalPage, (IDX)iuse); +} + +static WORD +CbyPAGE (IUSE iuse) +// Swap in the Usage page for Usage[iuse] (cal/cby) +// and return the Usage's index in the page. +// +{ + return SwapPAGE (lbCbyList, pfCbyList, + cbCbyCnt, MaxCbyCnt, &CurCbyPage, (IDX)iuse); +} + +static LPCH +GetAtomCache (WORD Page) +// load the requested page into the cache +// +{ + register WORD ipg; + WORD pagesize; + LPCH pfAtomCsave; + + for (ipg = 0; ipg < AtomPageTblMac; ipg++) { + if (AtomPageTbl[ipg].uPage == Page) + return AtomPageTbl[ipg].pfAtomCache; + } + + if (ipg != MAXATOMPAGETBL) { + if (AtomPageTbl[ipg].pfAtomCache || + (AtomPageTbl[ipg].pfAtomCache = LpvAllocCb(ATOMALLOC))) + AtomPageTblMac++; + } + + pfAtomCsave = AtomPageTbl[AtomPageTblMac-1].pfAtomCache; + + for (ipg = AtomPageTblMac-1; ipg; ipg--) + AtomPageTbl[ipg] = AtomPageTbl[ipg-1]; // move up + + AtomPageTbl[0].pfAtomCache = pfAtomCsave; + AtomPageTbl[0].uPage = Page; + + if (Page == lastAtomPage) + pagesize = lastAtomCnt; + else + pagesize = ATOMALLOC; + + GetBSC(lbAtomCache+ATOMALLOC*(long)Page, + AtomPageTbl[0].pfAtomCache, pagesize); + + return AtomPageTbl[0].pfAtomCache; +} + +LSZ BSC_API +LszNameFrSym (ISYM isym) +// Swap in the Atom page for the symbol isym +// return the atom's address in the page. +// +{ + SYMLIST sym; + + sym = bSYM(isym); + return GetAtomCache (sym.Page) + sym.Atom; +} + +LSZ BSC_API +LszNameFrMod (IMOD imod) +// Swap in the Atom page for the module isym +// return the atom's address in the page. +// +{ + return LszNameFrSym(bMOD(imod).ModName); +} + +int BSC_API +CaseCmp(LSZ lsz1, LSZ lsz2) +// +// think of lsz1 and lsz2 being in a list of things that are sorted +// case insensitively and then case sensitively within that. This is +// the case for browser symbols +// +// return -1, 0, or 1 if lsz1 before, at, or after lsz2 in the list +// +{ + int ret; + + // do case insensitive compare + ret = _stricmp(lsz1, lsz2); + + // if this is good enough then use it, or if we are only doing + // a case insensitive search then this is good enough + + if (ret || !fCase) return ret; + + // if we must, do the case sensitive compare + + return strcmp(lsz1, lsz2); +} + + +ISYM BSC_API +IsymFrLsz (LSZ lszReqd) +// find the symbol with the specifed name +// +{ + ISYM Lo, Hi, Mid; + int Cmp; + LSZ lszCur; + + Lo = 0; + Hi = (ISYM)(SymCnt - 1); + + while (Lo <= Hi) { + Mid = (ISYM)((Hi + Lo) / 2); + + lszCur = LszNameFrSym (Mid); + Cmp = CaseCmp (lszReqd, lszCur); + + if (Cmp == 0) + return Mid; + + if (Cmp < 0) + Hi = (ISYM)(Mid - 1); + else + Lo = (ISYM)(Mid + 1); + } + return isymNil; +} + +IMOD BSC_API +ImodFrLsz (LSZ lszReqd) +// find the module with the specifed name +// +{ + IMOD imod; + + for (imod = 0; imod < ModCnt; imod++) { + if (_stricmp (lszReqd, LszNameFrSym (bMOD(imod).ModName)) == 0) + return imod; + } + + return imodNil; +} + +ISYM BSC_API +IsymMac() +// return the biggest isym in this database +// +{ + return SymCnt; +} + +IMOD BSC_API +ImodMac() +// return the biggest imod in this database +// +{ + return ModCnt; +} + +IINST BSC_API +IinstMac() +// return the biggest iinst in this database +// +{ + return PropCnt; +} + +VOID BSC_API +MsRangeOfMod(IMOD imod, IMS *pimsFirst, IMS *pimsLast) +// fill in the module information +// +{ + *pimsFirst = imod ? bMOD(imod-1).mSymEnd : 0; + *pimsLast = bMOD(imod).mSymEnd; +} + +IINST BSC_API +IinstOfIms(IMS ims) +// give the instance (PROP) index of the modsym +// +{ + return bMODSYM(ims).ModSymProp; +} + +VOID BSC_API +InstRangeOfSym(ISYM isym, IINST *piinstFirst, IINST *piinstLast) +// fill in the range of inst values for this symbol +// +{ + *piinstFirst = isym ? bSYM(isym-1).PropEnd:0; + *piinstLast = bSYM(isym).PropEnd; +} + +VOID BSC_API +InstInfo(IINST iinst, ISYM *pisymInst, TYP *pTyp, ATR *pAtr) +// get the information that qualifies this instance +// +{ + *pisymInst = bPROP(iinst).PropName; + *pAtr = bPROP(iinst).PropAttr & 0x3ff; + *pTyp = (bPROP(iinst).PropAttr >> 11) & 0x1f; +} + +VOID BSC_API +RefRangeOfInst(IINST iinst, IREF *pirefFirst, IREF *pirefLast) +// fill in the reference ranges from the inst +// +{ + *pirefFirst = iinst ? bPROP(iinst-1).RefEnd : 0; + *pirefLast = bPROP(iinst).RefEnd; +} + +VOID BSC_API +DefRangeOfInst(IINST iinst, IDEF *pidefFirst, IDEF *pidefLast) +// fill in the definition ranges from the inst +// +{ + *pidefFirst = iinst ? bPROP(iinst-1).DefEnd : 0; + *pidefLast = bPROP(iinst).DefEnd; +} + +VOID BSC_API +UseRangeOfInst(IINST iinst, IUSE *piuseFirst, IUSE *piuseLast) +// fill in the use ranges from the inst +// +{ + *piuseFirst = iinst ? bPROP(iinst-1).CalEnd : 0; + *piuseLast = bPROP(iinst).CalEnd; +} + +VOID BSC_API +UbyRangeOfInst(IINST iinst, IUBY *piubyFirst, IUBY *piubyLast) +// fill in the used by ranges from the inst +// +{ + *piubyFirst = iinst ? bPROP(iinst-1).CbyEnd : 0; + *piubyLast = bPROP(iinst).CbyEnd; +} + +VOID BSC_API +UseInfo(IUSE iuse, IINST *piinst, WORD *pcnt) +// fill in the information about this things which an inst uses +// +{ + *piinst = bUSE(iuse).UseProp; + *pcnt = bUSE(iuse).UseCnt; +} + +VOID BSC_API +UbyInfo(IUBY iuby, IINST *piinst, WORD *pcnt) +// fill in the information about this things which an inst is used by +// +{ + *piinst = bUBY(iuby).UseProp; + *pcnt = bUBY(iuby).UseCnt; +} + +VOID BSC_API +RefInfo(IREF iref, LSZ *plszName, WORD *pline) +// fill in the information about this reference +// +{ + *pline = bREF(iref).RefLin; + *plszName = LszNameFrSym(bREF(iref).RefNam); +} + +VOID BSC_API +DefInfo(IDEF idef, LSZ *plszName, WORD *pline) +// fill in the information about this definition +// +{ + *pline = bDEF(idef).RefLin; + *plszName = LszNameFrSym(bDEF(idef).RefNam); +} + +VOID BSC_API +CloseBSC() +// close database and free as much memory as possible +// +{ + int i; + + // close file if open + + if (fhBSC != (FILEHANDLE)(-1)) { + BSCClose (fhBSC); + fhBSC = (FILEHANDLE)(-1); + } + + // free any memory we may have allocated + + if (pfModList) { FreeLpv (pfModList); pfModList = NULL; } + if (pfModSymList) { FreeLpv (pfModSymList); pfModSymList = NULL; } + if (pfSymList) { FreeLpv (pfSymList); pfSymList = NULL; } + if (pfPropList) { FreeLpv (pfPropList); pfPropList = NULL; } + if (pfRefList) { FreeLpv (pfRefList); pfRefList = NULL; } + if (pfDefList) { FreeLpv (pfDefList); pfDefList = NULL; } + if (pfCalList) { FreeLpv (pfCalList); pfCalList = NULL; } + if (pfCbyList) { FreeLpv (pfCbyList); pfCbyList = NULL; } + + for (i=0; i < MAXATOMPAGETBL; i++) { + if (AtomPageTbl[i].pfAtomCache) { + FreeLpv (AtomPageTbl[i].pfAtomCache); // dispose Atom Cache + AtomPageTbl[i].pfAtomCache = NULL; + } + } +} + +BOOL BSC_API +FOpenBSC (LSZ lszName) +// Open the specified data base. +// Allocate buffers for cache areas +// Initialize the data cache from the data base. +// +// Return TRUE iff successful, FALSE if database can't be read +// +{ + WORD pagesize; + + BYTE MajorVer; // .bsc version (major) + BYTE MinorVer; // .bsc version (minor) + BYTE UpdatVer; // .bsc version (updat) + + WORD MaxModCnt; // max list of modules + WORD cbModCnt; // size of list of modules + DWORD lbModList; // module list file start + + int i; + + #define ABORT_OPEN CloseBSC(); return FALSE; + + lszBSCName = lszName; + +#if defined (OS2) + fhBSC = BSCOpen(lszBSCName, O_BINARY|O_RDONLY); +#else + fhBSC = BSCOpen(lszBSCName, GENERIC_READ); +#endif + + // if the .bsc file doesn't exist then we don't do any work + // this is the cold compile case + // + + if (fhBSC == (FILEHANDLE)(-1)) {ABORT_OPEN;} + + // read and check BSC version (major, minor and update) + + BSCIn(MajorVer); + BSCIn(MinorVer); + BSCIn(UpdatVer); + + BSCPrintf("Browser Data Base: %s ver %d.%d.%d\n\n", + lszBSCName, MajorVer, MinorVer, UpdatVer); + + if ((MajorVer != BSC_MAJ) || + (MinorVer != BSC_MIN) || + (UpdatVer != BSC_UPD)) { + + CloseBSC(); + BadBSCVer(lszBSCName); + return FALSE; + } + + // read Case sense switch, max symbol length and Unknown module id + + BSCIn(fCase); + BSCIn(MaxSymLen); + BSCIn(Unknown); + + // this will make the formatting look more reasonable if there are + // only very short names in the database + + if (MaxSymLen < 8 ) MaxSymLen = 8; + + // read counts (sizes) of each data area + + BSCIn(ModCnt); + BSCIn(ModSymCnt); + BSCIn(SymCnt); + BSCIn(PropCnt); + BSCIn(RefCnt); + BSCIn(DefCnt); + BSCIn(CalCnt); + BSCIn(CbyCnt); + BSCIn(lastAtomPage); + BSCIn(lastAtomCnt); + + // read BSC data area offsets + + BSCIn(lbModList); + BSCIn(lbModSymList); + BSCIn(lbSymList); + BSCIn(lbPropList); + BSCIn(lbRefList); + BSCIn(lbDefList); + BSCIn(lbCalList); + BSCIn(lbCbyList); + BSCIn(lbAtomCache); + BSCIn(lbSbrList); + + // determine data cache area sizes + + #define MIN(a,b) ((a)>(b) ? (b) : (a)) + + MaxModCnt = ModCnt; // max list of modules + MaxModSymCnt = ModSymCnt; // max list of modsyms + MaxSymCnt = SymCnt+ModCnt; // max list of symbols + MaxPropCnt = PropCnt; // max list of props + MaxRefCnt = RefCnt; // max list of refs + MaxDefCnt = DefCnt; // max list of defs + MaxCalCnt = CalCnt; // max list of cals + MaxCbyCnt = CbyCnt; // max list of cbys + + cbModCnt = sizeof(MODLIST) * MaxModCnt; // size of mods list + cbModSymCnt = sizeof(MODSYMLIST) * MaxModSymCnt; // size of modsyms list + cbSymCnt = sizeof(SYMLIST) * MaxSymCnt; // size of syms list + cbPropCnt = sizeof(PROPLIST) * MaxPropCnt; // size of props list + cbRefCnt = sizeof(REFLIST) * MaxRefCnt; // size of refs list + cbDefCnt = sizeof(REFLIST) * MaxDefCnt; // size of defs list + cbCalCnt = sizeof(USELIST) * MaxCalCnt; // size of cals list + cbCbyCnt = sizeof(USELIST) * MaxCbyCnt; // size of cbys list + + // Allocate buffers for each of the object types + + if (!(pfModList = LpvAllocCb(cbModCnt))) { ABORT_OPEN; } + if (!(pfModSymList = LpvAllocCb(cbModSymCnt))) { ABORT_OPEN; } + if (!(pfSymList = LpvAllocCb(cbSymCnt))) { ABORT_OPEN; } + if (!(pfPropList = LpvAllocCb(cbPropCnt))) { ABORT_OPEN; } + if (!(pfRefList = LpvAllocCb(cbRefCnt))) { ABORT_OPEN; } + if (!(pfDefList = LpvAllocCb(cbDefCnt))) { ABORT_OPEN; } + if (!(pfCalList = LpvAllocCb(cbCalCnt))) { ABORT_OPEN; } + if (!(pfCbyList = LpvAllocCb(cbCbyCnt))) { ABORT_OPEN; } + + // read data areas + + if (lastAtomPage == 0) + pagesize = lastAtomCnt; + else + pagesize = ATOMALLOC; + + // clear out the atom cache + // we must be able to allocate at least one page + + AtomPageTblMac = 0; + + for (i=0; i < MAXATOMPAGETBL; i++) + AtomPageTbl[i].pfAtomCache = NULL; + + AtomPageTbl[0].uPage = 65535; + AtomPageTbl[0].pfAtomCache = LpvAllocCb(pagesize); + if (!AtomPageTbl[0].pfAtomCache) { ABORT_OPEN; } + + + GetBSC(lbModList, pfModList, cbModCnt); // Init Mod cache + GetBSC(lbModSymList, pfModSymList, cbModSymCnt); // Init ModSym cache + GetBSC(lbSymList, pfSymList, cbSymCnt); // Init Sym cache + GetBSC(lbPropList, pfPropList, cbPropCnt); // Init Prop cache + GetBSC(lbRefList, pfRefList, cbRefCnt); // Init Ref cache + GetBSC(lbDefList, pfDefList, cbDefCnt); // Init Def cache + GetBSC(lbCalList, pfCalList, cbCalCnt); // Init Cal cache + GetBSC(lbCbyList, pfCbyList, cbCbyCnt); // Init Cby cache + + // current page for all database items is now page zero + + CurModSymPage = 0; + CurSymPage = 0; + CurPropPage = 0; + CurRefPage = 0; + CurDefPage = 0; + CurCalPage = 0; + CurCbyPage = 0; + + GetAtomCache (0); // Init Atom cache + + return TRUE; +} + +WORD BSC_API +BSCMaxSymLen() +// return the length of the largest symbol in the database +// +{ + return MaxSymLen; +} + +BOOL BSC_API +FCaseBSC() +// is this database built with a case sensitive language? +// +{ + return fCase; +} + +VOID BSC_API +SetCaseBSC(BOOL fNewCase) +// set case sensitivity of database +// +{ + fCase = (BYTE)!!fNewCase; +} diff --git a/private/utils/mep/browser/bsc/bscdump.c b/private/utils/mep/browser/bsc/bscdump.c new file mode 100644 index 000000000..e4d1ea317 --- /dev/null +++ b/private/utils/mep/browser/bsc/bscdump.c @@ -0,0 +1,114 @@ + +// +// +// DumpBSC - Dump Source Data Base. +// Walk the symbol tree dumping stuff. +// +#include +#include +#if defined(OS2) +#define INCL_NOCOMMON +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#define INCL_DOSMISC +#include +#else +#include +#endif + +#include + +#include "hungary.h" +#include "bsc.h" +#include "bscsup.h" + +VOID BSC_API +DumpBSC() +// Dump the contents of the .BSC file to the Output Function +// +{ + IMOD imod, imodMac; + IMS ims, imsMac; + ISYM isym, isymMac, isymT; + IINST iinst, iinstMac, iinstT; + IDEF idef, idefMac; + IREF iref, irefMac; + IUSE iuse, iuseMac; + IUBY iuby, iubyMac; + WORD wLine, cnt; + LSZ lsz; + + imodMac = ImodMac(); + + BSCPrintf("Modules:\n\n"); + + for (imod = 0; imod < imodMac; imod++) { + BSCPrintf("%s\n", LszNameFrMod(imod)); + + MsRangeOfMod(imod, &ims, &imsMac); + + for ( ;ims < imsMac; ims++) { + BSCPrintf("\t contains "); + DumpInst(IinstOfIms(ims)); + BSCPrintf("\n"); + } + } + + isymMac = IsymMac(); + + BSCPrintf("\nSymbols:\n\n"); + + for (isym = 0; isym < isymMac; isym++) { + + InstRangeOfSym(isym, &iinst, &iinstMac); + + for ( ;iinst < iinstMac; iinst++) { + TYP typ; + ATR atr; + + DumpInst(iinst); + BSCPrintf("\n"); + + InstInfo(iinst, &isymT, &typ, &atr); + + if (isym != isymT) + BSCPrintf("\t ERROR instance points back to wrong symbol!\n"); + + DefRangeOfInst(iinst, &idef, &idefMac); + for (; idef < idefMac; idef++) { + DefInfo(idef, &lsz, &wLine); + BSCPrintf ("\t def'd %s(%d)\n", lsz, wLine); + } + + RefRangeOfInst(iinst, &iref, &irefMac); + for (; iref < irefMac; iref++) { + RefInfo(iref, &lsz, &wLine); + BSCPrintf ("\t ref'd %s(%d)\n", lsz, wLine); + } + + UseRangeOfInst(iinst, &iuse, &iuseMac); + for (; iuse < iuseMac; iuse++) { + BSCPrintf ("\t uses "); + + UseInfo(iuse, &iinstT, &cnt); + DumpInst(iinstT); + if (cnt > 1) BSCPrintf("[%d]", cnt); + BSCPrintf ("\n"); + } + + UbyRangeOfInst(iinst, &iuby, &iubyMac); + for (; iuby < iubyMac; iuby++) { + BSCPrintf ("\t used-by "); + + UbyInfo(iuby, &iinstT, &cnt); + DumpInst(iinstT); + if (cnt > 1) BSCPrintf("[%d]", cnt); + BSCPrintf ("\n"); + } + + BSCPrintf("\n"); + } + } +} diff --git a/private/utils/mep/browser/bsc/calltree.c b/private/utils/mep/browser/bsc/calltree.c new file mode 100644 index 000000000..e26f07b2f --- /dev/null +++ b/private/utils/mep/browser/bsc/calltree.c @@ -0,0 +1,213 @@ +// +// calltree.c +// +// two routines for printing out ascii call tree's +// +#include +#include +#if defined(OS2) +#define INCL_NOCOMMON +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#define INCL_DOSMISC +#include +#else +#include +#endif + +#include + + +#include "hungary.h" +#include "bsc.h" +#include "bscsup.h" + +// forward declarations +static BOOL FUsedInst(IINST iinst); +static VOID dCallTree(IINST iinst, WORD cuse); + + +// static variables +static BYTE *UseBits = NULL; +static WORD cNest = 0; + +VOID BSC_API +CallTreeInst (IINST iinst) +// emit the call tree starting from the given inst +// +{ + WORD iinstMac; + int igrp; + + iinstMac = IinstMac(); + + // allocate memory for bit array + UseBits = LpvAllocCb((WORD)(iinstMac/8 + 1)); + + // no memory -- no call tree + if (!UseBits) return; + + igrp = iinstMac/8+1; + + while (--igrp>=0) + UseBits[igrp] = 0; + + cNest = 0; + + dCallTree(iinst, 1); + + FreeLpv(UseBits); +} + + +static VOID +dCallTree (IINST iinst, WORD cuse) +// emit the call tree starting from the given inst +// +// there are many block variables to keep the stack to a minimum... +{ + { + ISYM isym; + + { + TYP typ; + ATR atr; + + InstInfo(iinst, &isym, &typ, &atr); + + if (typ > INST_TYP_LABEL) + return; + } + + + { + WORD i; + cNest++; + for (i = cNest; i; i--) BSCPrintf ("| "); + } + + if (cuse > 1) + BSCPrintf ("%s[%d]", LszNameFrSym (isym), cuse); + else + BSCPrintf ("%s", LszNameFrSym (isym)); + } + + { + IDEF idef, idefMac; + LSZ lsz; + WORD w; + + DefRangeOfInst(iinst, &idef, &idefMac); + DefInfo(idef, &lsz, &w); + + if (strcmp("", lsz) == 0) { + BSCPrintf ("?\n"); + cNest--; + return; + } + } + + if (FUsedInst(iinst)) { + BSCPrintf ("...\n"); + cNest--; + return; + } + + BSCPrintf ("\n"); + + { + IUSE iuse, iuseMac; + IINST iinstUse; + + UseRangeOfInst(iinst, &iuse, &iuseMac); + + for (; iuse < iuseMac; iuse++) { + UseInfo(iuse, &iinstUse, &cuse); + dCallTree (iinstUse, cuse); + } + } + + cNest--; +} + +BOOL BSC_API +FCallTreeLsz(LSZ lszName) +// print out a call tree based on the given name +// +{ + IMOD imod; + ISYM isym; + + cNest = 0; + + if (!lszName) + return FALSE; + + { + IINST iinstMac; + int igrp; + + iinstMac = IinstMac(); + + // allocate memory for bit array + UseBits = LpvAllocCb((WORD)(iinstMac/8 + 1)); + + // no memory -- no call tree + if (!UseBits) return FALSE; + + igrp = iinstMac/8+1; + + while (--igrp >= 0) + UseBits[igrp] = 0; + } + + if ((imod = ImodFrLsz (lszName)) != imodNil) { + IMS ims, imsMac; + + MsRangeOfMod(imod, &ims, &imsMac); + + BSCPrintf ("%s\n", LszNameFrMod (imod)); + + for ( ; ims < imsMac ; ims++) + dCallTree (IinstOfIms(ims), 1); + + FreeLpv(UseBits); + return TRUE; + } + + if ((isym = IsymFrLsz (lszName)) != isymNil) { + IINST iinst, iinstMac; + + BSCPrintf ("%s\n", LszNameFrSym (isym)); + + InstRangeOfSym(isym, &iinst, &iinstMac); + + for (; iinst < iinstMac; iinst++) + dCallTree (iinst, 1); + + FreeLpv(UseBits); + return TRUE; + } + + FreeLpv(UseBits); + return FALSE; +} + +static BOOL +FUsedInst(IINST iinst) +// return the status bit for this iinst and set it true +// +{ + WORD igrp; + BOOL fOut; + WORD mask; + + igrp = iinst / 8; + mask = (1 << (iinst % 8)); + + fOut = !!(UseBits[igrp] & mask); + UseBits[igrp] |= mask; + return fOut; +} diff --git a/private/utils/mep/browser/bsc/dump.c b/private/utils/mep/browser/bsc/dump.c new file mode 100644 index 000000000..b87f1da29 --- /dev/null +++ b/private/utils/mep/browser/bsc/dump.c @@ -0,0 +1,99 @@ + +// +// support for instance dumping +// +#include +#include +#if defined(OS2) +#define INCL_NOCOMMON +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#define INCL_DOSMISC +#include +#else +#include +#endif + +#include + +#include "hungary.h" +#include "bsc.h" +#include "bscsup.h" + +char *ptyptab[] = { + "undef", // SBR_TYP_UNKNOWN + "function", // SBR_TYP_FUNCTION + "label", // SBR_TYP_LABEL + "parameter", // SBR_TYP_PARAMETER + "variable", // SBR_TYP_VARIABLE + "constant", // SBR_TYP_CONSTANT + "macro", // SBR_TYP_MACRO + "typedef", // SBR_TYP_TYPEDEF + "strucnam", // SBR_TYP_STRUCNAM + "enumnam", // SBR_TYP_ENUMNAM + "enummem", // SBR_TYP_ENUMMEM + "unionnam", // SBR_TYP_UNIONNAM + "segment", // SBR_TYP_SEGMENT + "group", // SBR_TYP_GROUP + "program" // SBR_TYP_PROGRAM +}; + +#define C_ATR 11 + +char *patrtab[] = { + "local", // SBR_ATR_LOCAL + "static", // SBR_ATR_STATIC + "shared", // SBR_ATR_SHARED + "near", // SBR_ATR_NEAR + "common", // SBR_ATR_COMMON + "decl_only", // SBR_ATR_DECL_ONLY + "public", // SBR_ATR_PUBLIC + "named", // SBR_ATR_NAMED + "module", // SBR_ATR_MODULE + "?", "?" // reserved for expansion +}; + +VOID BSC_API +DumpInst(IINST iinst) +// dump a single instance +{ + ISYM isym; + WORD i; + LSZ lsz; + WORD len; + TYP typ; + ATR atr; + + len = BSCMaxSymLen(); + + InstInfo(iinst, &isym, &typ, &atr); + + lsz = LszNameFrSym(isym); + + BSCPrintf("%s", lsz); + + for (i = strlen(lsz); i < len; i++) + BSCPrintf(" "); + + BSCPrintf(" (%s", ptyptab[typ]); + + for (i=0; i < C_ATR; i++) + if (atr & (1< +#if defined(OS2) +#define INCL_NOCOMMON +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#define INCL_DOSMISC +#include +#else +#include +#endif + +#include + +#include "hungary.h" +#include "bsc.h" +#include "bscsup.h" + +BOOL BSC_API +FInstFilter (IINST iinst, MBF mbf) +// return true if the given inst has the required properties +// +{ + ISYM isym; + TYP typ; + ATR atr; + + InstInfo(iinst, &isym, &typ, &atr); + + if (typ <= INST_TYP_LABEL) + return !!(mbf & mbfFuncs); + + if (typ <= INST_TYP_VARIABLE || typ >= INST_TYP_SEGMENT) + return !!(mbf & mbfVars); + + if (typ <= INST_TYP_MACRO) + return !!(mbf & mbfMacros); + + return !!(mbf & mbfTypes); +} diff --git a/private/utils/mep/browser/bsc/format.c b/private/utils/mep/browser/bsc/format.c new file mode 100644 index 000000000..d29228723 --- /dev/null +++ b/private/utils/mep/browser/bsc/format.c @@ -0,0 +1,112 @@ +// +// format.c +// +// simple minded printf replacement +// +// only supports %s and %d but it is *small* +// +#include +#if defined(OS2) +#define INCL_NOCOMMON +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#define INCL_DOSMISC +#include +#else +#include +#endif + +#include + +#include "hungary.h" +#include "bsc.h" +#include "bscsup.h" + +VOID static near pascal _ultoa(DWORD, LSZ); + +VOID BSC_API +BSCFormat(LPCH lpchOut, LSZ lszFormat, va_list va) +// format to lpchOut as specified byh format +// +// this is a very simple minded formatter +{ + LPCH lpch; + WORD i; + DWORD l; + + lpch = lpchOut; + + while (*lszFormat) { + if (*lszFormat == '%') { + switch (lszFormat[1]) { + + case '%': + *lpch++ = '%'; + break; + + case 's': + strcpy(lpch, va_arg(va, LSZ)); + lpch += strlen(lpch); + break; + + case 'd': + i = va_arg(va, WORD); + _ultoa((DWORD)i, lpch); + lpch += strlen(lpch); + break; + + case 'l': + l = va_arg(va, DWORD); + _ultoa(l, lpch); + lpch += strlen(lpch); + break; + + default: + lpch[0] = '%'; + lpch[1] = lszFormat[1]; + lpch += 2; + break; + } + lszFormat += 2; + } + else + *lpch++ = *lszFormat++; + } + *lpch = 0; +} + +VOID BSC_API +BSCSprintf(LPCH lpchOut, LSZ lszFormat, ...) +// sprintf replacement +// +{ + va_list va; + + va_start(va, lszFormat); + + BSCFormat(lpchOut, lszFormat, va); +} + +static DWORD pow10[8] = { + 10L, 100L, 1000L, 10000L, + 100000L , 1000000L, 10000000L, 100000000L + }; + +VOID static near pascal +_ultoa(DWORD dw, LSZ lsz) +{ + int log; + + for (log = 0; log < 8; log++) + if (dw < pow10[log]) + break; + + lsz[++log] = 0; + + while (--log >= 0) { + lsz[log] = (char)(((int)(dw%10)) + '0'); + dw/=10; + } +} diff --git a/private/utils/mep/browser/bsc/listref.c b/private/utils/mep/browser/bsc/listref.c new file mode 100644 index 000000000..c5327c99e --- /dev/null +++ b/private/utils/mep/browser/bsc/listref.c @@ -0,0 +1,185 @@ +// listref.c +// +// list database references +// +#include +#if defined(OS2) +#define INCL_NOCOMMON +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#define INCL_DOSMISC +#include +#else +#include +#endif + +#include + +#include "hungary.h" +#include "bsc.h" +#include "bscsup.h" + +#include + +// forward references +// +static VOID ListRefSym (ISYM isym, MBF mbf); +static VOID ListRefUse (IINST iinst, WORD icol, WORD cuse); +static VOID PutLine(VOID); +static VOID ListRefTitle(LSZ lszType, LSZ lszUsers, MBF mbf); + +// static variables +// +static WORD MaxSymLen; +static LPCH bufg; + + +BOOL BSC_API +ListRefs (MBF mbfReqd) +// scan the database for items which would match the requirements +// and emit their uses and used by lists +// +{ + static char szFunction[] = "FUNCTION"; + static char szVariable[] = "VARIABLE"; + static char szType[] = "TYPE"; + static char szMacro[] = "MACRO"; + static char szCalledBy[] = "CALLED BY LIST"; + static char szUsedBy[] = "USED BY LIST"; + + bufg = LpvAllocCb(1024); + + // no memory.. no reference list + if (!bufg) return FALSE; + + MaxSymLen = BSCMaxSymLen(); + + if (mbfReqd & mbfFuncs) ListRefTitle(szFunction, szCalledBy, mbfFuncs); + if (mbfReqd & mbfVars) ListRefTitle(szVariable, szUsedBy, mbfVars); + if (mbfReqd & mbfMacros) ListRefTitle(szMacro, szUsedBy, mbfMacros); + if (mbfReqd & mbfTypes) ListRefTitle(szType, szUsedBy, mbfTypes); + + FreeLpv(bufg); + return TRUE; +} + +static VOID +ListRefTitle(LSZ lszType, LSZ lszUsers, MBF mbf) +// format a title +// +{ + WORD i,l; + ISYM isym, isymMac; + + isymMac = IsymMac(); + + // format titles + // + + strcpy (bufg, lszType); + for (i=strlen(bufg); i < MaxSymLen+5; i++) bufg[i] = ' '; + strcpy (bufg+i, lszUsers); + PutLine(); + + // underscore titles + // + l = strlen(lszType); + for (i=0; i maxcol) { + csym = 1; + PutLine(); + } + + UbyInfo(iuby, &iinstUby, &cnt); + ListRefUse (iinstUby, (WORD)(csym*icol), cnt); + } + } + if (bufg[0]) PutLine(); +} + +static VOID +ListRefUse (IINST iinst, WORD icol, WORD cuse) +// dump information about the given prop in the location provided +// +{ + WORD i, len; + ISYM isym; + BOOL fVar; + TYP typ; + ATR atr; + LSZ lsz; + + InstInfo(iinst, &isym, &typ, &atr); + + fVar = (typ > INST_TYP_LABEL); + + len = strlen(bufg); + + lsz = LszNameFrSym(isym); + + for (i=len; i 1) + BSCSprintf(bufg+icol, "(%s)[%d] ", lsz, cuse); + else + BSCSprintf(bufg+icol, "(%s) ", lsz); + } + else { + if (cuse > 1) + BSCSprintf(bufg+icol, "%s[%d] ", lsz, cuse); + else + BSCSprintf(bufg+icol, "%s ", lsz); + } +} + +static VOID +PutLine() +// write out a single line from the buffer +{ + BSCPrintf("%s\n", bufg); + *bufg = 0; +} diff --git a/private/utils/mep/browser/bsc/makefile b/private/utils/mep/browser/bsc/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/utils/mep/browser/bsc/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/utils/mep/browser/bsc/outline.c b/private/utils/mep/browser/bsc/outline.c new file mode 100644 index 000000000..097489bda --- /dev/null +++ b/private/utils/mep/browser/bsc/outline.c @@ -0,0 +1,101 @@ +// +// outline.c +// +// these are the file outline routines +// +// +#include +#if defined(OS2) +#define INCL_NOCOMMON +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#define INCL_DOSMISC +#include +#else +#include +#endif + +#include + +#include "hungary.h" +#include "bsc.h" +#include "bscsup.h" + +// forward ref + +VOID BSC_API +OutlineMod(IMOD imod, MBF mbf) +// print the outline for this module +// +{ + IMS ims, imsMac; + IINST iinst; + + BSCPrintf("\n%s\n", LszNameFrMod(imod)); + + MsRangeOfMod(imod, &ims, &imsMac); + for ( ;ims < imsMac; ims++) { + iinst = IinstOfIms(ims); + + if (FInstFilter (iinst, mbf)) { + BSCPrintf(" "); + DumpInst(iinst); + BSCPrintf("\n"); + } + } +} + +BOOL BSC_API +FOutlineModuleLsz (LSZ lszName, MBF mbf) +// generate an outline for all files matching the given name/pattern +// showing only those items which match the required attribute +// +{ + IMOD imod, imodMac; + BOOL fRet = FALSE; + + if (!lszName) + return FALSE; + + imodMac = ImodMac(); + + // we match base names only + + lszName = LszBaseName(lszName); + for (imod = 0; imod < imodMac; imod++) { + if (FWildMatch(lszName, LszBaseName(LszNameFrMod(imod)))) { + OutlineMod (imod, mbf); + fRet = TRUE; + } + } + + return fRet; +} + +LSZ BSC_API +LszBaseName (LSZ lsz) +// return the base name part of a path +// +{ + LSZ lszBase; + + // check for empty string + + if (!lsz || !lsz[0]) return lsz; + + // remove drive + + if (lsz[1] == ':') lsz += 2; + + // remove up to trailing backslash + + if (lszBase = strrchr(lsz, '\\')) lsz = lszBase+1; + + // then remove up to trailing slash + + if (lszBase = strrchr(lsz, '/')) lsz = lszBase+1; + + return lsz; +} diff --git a/private/utils/mep/browser/bsc/printf.c b/private/utils/mep/browser/bsc/printf.c new file mode 100644 index 000000000..4ed12bd8b --- /dev/null +++ b/private/utils/mep/browser/bsc/printf.c @@ -0,0 +1,114 @@ + +// +// printf.c +// +// simple minded printf replacement +// +// only supports %s and %d but it is *small* +// +#include +#include +#include +#if defined(OS2) +#define INCL_NOCOMMON +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#define INCL_DOSMISC +#include +#else +#include +#endif + +#include + +#include "hungary.h" +#include "bsc.h" +#include "bscsup.h" + +static char lpchBuf[1024]; +static LPCH lpchPos = NULL; + +VOID BSC_API +BSCPrintf(LSZ lszFormat, ...) +// printf replacement +// +{ + va_list va; + LPCH lpch; + char ch; + + if (!lpchPos) { + lpchPos = lpchBuf; + } + + va_start(va, lszFormat); + + BSCFormat(lpchPos, lszFormat, va); + + // write out a line at a time + // + for (;;) { + lpch = strchr(lpchPos, '\n'); + if (!lpch) { + lpchPos += strlen(lpchPos); + return; + } + + ch = *++lpch; + *lpch = 0; + BSCOutput(lpchBuf); + *lpch = ch; + strcpy(lpchBuf, lpch); + if (!ch) + lpchPos = lpchBuf; + else + lpchPos = lpchBuf + strlen(lpchBuf); + } +} + +#ifdef DEBUG + +static char lpchDBuf[256]; +static LPCH lpchDPos = NULL; + +VOID BSC_API +BSCDebug(LSZ lszFormat, ...) +// printf clone for debug output +// +{ + va_list va; + LPCH lpch; + char ch; + + if (!lpchDPos) { + lpchDPos = lpchDBuf; + } + + va_start(va, lszFormat); + + BSCFormat(lpchDPos, lszFormat, va); + + // write out a line at a time + // + for (;;) { + lpch = strchr(lpchDPos, '\n'); + if (!lpch) { + lpchDPos += strlen(lpchDPos); + return; + } + + ch = *++lpch; + *lpch = 0; + BSCDebugOut(lpchDBuf); + *lpch = ch; + strcpy(lpchDBuf, lpch); + if (!ch) + lpchDPos = lpchDBuf; + else + lpchDPos = lpchDBuf + strlen(lpchDBuf); + } +} + +#endif diff --git a/private/utils/mep/browser/bsc/query.c b/private/utils/mep/browser/bsc/query.c new file mode 100644 index 000000000..329f22e31 --- /dev/null +++ b/private/utils/mep/browser/bsc/query.c @@ -0,0 +1,575 @@ +// +// query.c +// +// perform database queries +// +#include +#include +#if defined(OS2) +#define INCL_NOCOMMON +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#define INCL_DOSMISC +#include +#else +#include +#endif + +#include + +#include "hungary.h" +#include "bsc.h" +#include "bscsup.h" + +// these keep track of the current query, they are globally visible so +// that users can see how the query is progressing +// +// you may not write on these + +IDX far idxQyStart; +IDX far idxQyCur; +IDX far idxQyMac; + +// this is auxilliary information about the current bob which some +// queries may choose to make available +// + +static BOOL fWorking; +static LSZ lszModLast = NULL; // for removing duplicate modules + +// prototypes for the query worker functions +// + +static BOB BobQyFiles(VOID); +static BOB BobQySymbols (VOID); +static BOB BobQyContains (VOID); +static BOB BobQyCalls (VOID); +static BOB BobQyCalledBy (VOID); +static BOB BobQyUses (VOID); +static BOB BobQyUsedBy (VOID); +static BOB BobQyUsedIn (VOID); +static BOB BobQyDefinedIn(VOID); +static BOB BobQyRefs(VOID); +static BOB BobQyDefs(VOID); + +// current bob worker function +static BOB (*bobFn)(VOID) = NULL; + +BOOL BSC_API +InitBSCQuery (QY qy, BOB bob) +// do the request query on the given bob +// +{ + fWorking = FALSE; + + if (lszModLast == NULL) + lszModLast = LpvAllocCb(1024); // REVIEW -- how much to alloc? [rm] + + // no memory -- no query + if (lszModLast == NULL) + return FALSE; + + strcpy(lszModLast, ""); + + switch (qy) { + + case qyFiles: + bobFn = BobQyFiles; + idxQyStart = (IDX)0; + idxQyMac = (IDX)ImodMac(); + break; + + case qySymbols: + bobFn = BobQySymbols; + idxQyStart = (IDX)0; + idxQyMac = (IDX)IinstMac(); + break; + + case qyContains: + { + IMS ims, imsMac; + + bobFn = BobQyContains; + + if (ClsOfBob(bob) != clsMod) return FALSE; + MsRangeOfMod(ImodFrBob(bob), &ims, &imsMac); + + idxQyStart = (IDX)ims; + idxQyMac = (IDX)imsMac; + + break; + } + + case qyCalls: + { + IUSE iuse, iuseMac; + + bobFn = BobQyCalls; + if (ClsOfBob(bob) != clsInst) return FALSE; + UseRangeOfInst(IinstFrBob(bob), &iuse, &iuseMac); + + idxQyStart = (IDX)iuse; + idxQyMac = (IDX)iuseMac; + + break; + } + + case qyUses: + { + IUSE iuse, iuseMac; + + bobFn = BobQyUses; + if (ClsOfBob(bob) != clsInst) return FALSE; + UseRangeOfInst(IinstFrBob(bob), &iuse, &iuseMac); + + idxQyStart = (IDX)iuse; + idxQyMac = (IDX)iuseMac; + + break; + } + + case qyCalledBy: + { + IUBY iuby, iubyMac; + + bobFn = BobQyCalledBy; + if (ClsOfBob(bob) != clsInst) return FALSE; + UbyRangeOfInst(IinstFrBob(bob), &iuby, &iubyMac); + + idxQyStart = (IDX)iuby; + idxQyMac = (IDX)iubyMac; + + break; + } + + case qyUsedBy: + { + IUBY iuby, iubyMac; + + bobFn = BobQyUsedBy; + if (ClsOfBob(bob) != clsInst) return FALSE; + UbyRangeOfInst(IinstFrBob(bob), &iuby, &iubyMac); + + idxQyStart = (IDX)iuby; + idxQyMac = (IDX)iubyMac; + + break; + } + + case qyUsedIn: + { + IREF iref, irefMac; + + bobFn = BobQyUsedIn; + if (ClsOfBob(bob) != clsInst) return FALSE; + RefRangeOfInst(IinstFrBob(bob), &iref, &irefMac); + + idxQyStart = (IDX)iref; + idxQyMac = (IDX)irefMac; + + break; + } + + case qyDefinedIn: + { + IDEF idef, idefMac; + + bobFn = BobQyDefinedIn; + if (ClsOfBob(bob) != clsInst) return FALSE; + DefRangeOfInst(IinstFrBob(bob), &idef, &idefMac); + + idxQyStart = (IDX)idef; + idxQyMac = (IDX)idefMac; + + break; + } + + case qyRefs: + { + IINST iinst, iinstMac; + + bobFn = BobQyRefs; + + switch (ClsOfBob(bob)) { + + default: + return FALSE; + + case clsSym: + InstRangeOfSym(IsymFrBob(bob), &iinst, &iinstMac); + + idxQyStart = (IDX)iinst; + idxQyMac = (IDX)iinstMac; + break; + + case clsInst: + idxQyStart = (IDX)IinstFrBob(bob); + idxQyMac = idxQyStart+1; + break; + } + + break; + } + + case qyDefs: + { + IINST iinst, iinstMac; + + bobFn = BobQyDefs; + + switch (ClsOfBob(bob)) { + + default: + return FALSE; + + case clsSym: + InstRangeOfSym(IsymFrBob(bob), &iinst, &iinstMac); + + idxQyStart = (IDX)iinst; + idxQyMac = (IDX)iinstMac; + break; + + case clsInst: + idxQyStart = (IDX)IinstFrBob(bob); + idxQyMac = idxQyStart+1; + break; + } + + break; + } + } + + idxQyCur = idxQyStart; + return TRUE; +} + +BOB BSC_API +BobNext() +// return the next Bob in the query +{ + if (idxQyCur < idxQyMac && bobFn != NULL) + return (*bobFn)(); + + return bobNil; +} + +static BOB +BobQyFiles() +// return the next File in a file query +// +{ + BOB bob; + + while (idxQyCur < idxQyMac) { + IMS ims1, ims2; + + MsRangeOfMod((IMOD)idxQyCur, &ims1, &ims2); + if (ims1 != ims2) { + bob = BobFrClsIdx(clsMod, idxQyCur); + idxQyCur++; + return bob; + } + else + idxQyCur++; + } + return bobNil; +} + +static BOB +BobQySymbols () +// get the next symbol in a symbol query +// +{ + BOB bob; + + bob = BobFrClsIdx(clsInst, idxQyCur); + idxQyCur++; + return bob; +} + +static BOB +BobQyContains () +// get the next symbol in a contains query +// +{ + BOB bob; + + bob = BobFrClsIdx(clsInst, IinstOfIms((IMS)idxQyCur)); + idxQyCur++; + return bob; +} + +static BOB +BobQyCalls () +// get the next symbol which query focus calls +// +{ + WORD cuse; + IINST iinst; + ISYM isym; + TYP typ; + ATR atr; + BOB bob; + + for (; idxQyCur < idxQyMac; idxQyCur++) { + + UseInfo((IUSE)idxQyCur, &iinst, &cuse); + InstInfo(iinst, &isym, &typ, &atr); + + if (typ > INST_TYP_LABEL) + continue; + + bob = BobFrClsIdx(clsInst, iinst); + idxQyCur++; + return bob; + } + return bobNil; +} + +static BOB +BobQyCalledBy () +// get the next symbol which query focus is called by +// +{ + WORD cuse; + IINST iinst; + ISYM isym; + TYP typ; + ATR atr; + BOB bob; + + for (; idxQyCur < idxQyMac; idxQyCur++) { + + UbyInfo((IUBY)idxQyCur, &iinst, &cuse); + InstInfo(iinst, &isym, &typ, &atr); + + if (typ > INST_TYP_LABEL) + continue; + + bob = BobFrClsIdx(clsInst, iinst); + idxQyCur++; + return bob; + } + return bobNil; +} + +static BOB +BobQyUses () +// get the next symbol which query focus calls +// +{ + WORD cuse; + IINST iinst; + BOB bob; + + UseInfo((IUSE)idxQyCur, &iinst, &cuse); + bob = BobFrClsIdx(clsInst, iinst); + idxQyCur++; + return bob; +} + +static BOB +BobQyUsedBy () +// get the next symbol which query focus calls +// +{ + WORD cuse; + IINST iinst; + BOB bob; + + UbyInfo((IUBY)idxQyCur, &iinst, &cuse); + bob = BobFrClsIdx(clsInst, iinst); + idxQyCur++; + return bob; +} + +static BOB +BobQyUsedIn () +// get the next module which query focus is used in +// +{ + WORD wLine; + BOB bob; + LSZ lszMod; + + for ( ; idxQyCur < idxQyMac ; idxQyCur++) { + RefInfo((IREF)idxQyCur, &lszMod, &wLine); + + if (strcmp(lszMod, lszModLast) == 0) + continue; + + strcpy(lszModLast, lszMod); + + bob = BobFrClsIdx(clsMod, ImodFrLsz(lszMod)); + idxQyCur++; + return bob; + } + return bobNil; +} + +static BOB +BobQyDefinedIn () +// get the next module which query focus is defined in +// +{ + WORD wLine; + LSZ lszMod; + BOB bob; + + for ( ; idxQyCur < idxQyMac ; idxQyCur++) { + DefInfo((IDEF)idxQyCur, &lszMod, &wLine); + + if (strcmp(lszMod, lszModLast) == 0) + continue; + + strcpy(lszModLast, lszMod); + + bob = BobFrClsIdx(clsMod, ImodFrLsz(lszMod)); + idxQyCur++; + return bob; + } + return bobNil; +} + +LSZ BSC_API +LszNameFrBob(BOB bob) +// return the name of the given bob +// +{ + switch (ClsOfBob(bob)) { + + case clsMod: + return LszNameFrMod(ImodFrBob(bob)); + + case clsSym: + return LszNameFrSym(IsymFrBob(bob)); + + case clsInst: + { + ISYM isym; + TYP typ; + ATR atr; + + InstInfo(IinstFrBob(bob), &isym, &typ, &atr); + return LszNameFrSym(isym); + } + + case clsRef: + { + LSZ lsz; + WORD wLine; + + RefInfo(IrefFrBob(bob), &lsz, &wLine); + return lsz; + } + + case clsDef: + { + LSZ lsz; + WORD wLine; + + DefInfo(IdefFrBob(bob), &lsz, &wLine); + return lsz; + } + + default: + return "?"; + } +} + +BOB BSC_API +BobFrName(LSZ lszName) +// return the best bob we can find from the given name +// +{ + ISYM isym; + IMOD imod, imodMac; + IINST iinst, iinstMac; + + if ((isym = IsymFrLsz(lszName)) != isymNil) { + InstRangeOfSym(isym, &iinst, &iinstMac); + return BobFrClsIdx(clsInst, iinst); + } + + if ((imod = ImodFrLsz(lszName)) != imodNil) { + return BobFrClsIdx(clsMod, imod); + } + + imodMac = ImodMac(); + + // no exact match -- try short names + lszName = LszBaseName(lszName); + for (imod = 0; imod < imodMac; imod++) + if (_stricmp(lszName, LszBaseName(LszNameFrMod(imod))) == 0) + return BobFrClsIdx(clsMod, imod); + + return bobNil; +} + +static BOB +BobQyRefs() +// return the next File in a file query +// +{ + BOB bob; + static IREF iref, irefMac; + + for (;;) { + if (!fWorking) { + for ( ; idxQyCur < idxQyMac ; idxQyCur++) { + + RefRangeOfInst((IINST)idxQyCur, &iref, &irefMac); + if (iref != irefMac) + break; + } + if (idxQyCur >= idxQyMac) + return bobNil; + + fWorking = TRUE; + } + + if (iref < irefMac) { + bob = BobFrClsIdx(clsRef, iref); + iref++; + return bob; + } + + idxQyCur++; + fWorking = FALSE; + } +} + +static BOB +BobQyDefs() +// return the next File in a file query +// +{ + BOB bob; + static IDEF idef, idefMac; + + for (;;) { + if (!fWorking) { + for ( ; idxQyCur < idxQyMac ; idxQyCur++) { + + DefRangeOfInst((IINST)idxQyCur, &idef, &idefMac); + if (idef != idefMac) + break; + } + if (idxQyCur >= idxQyMac) + return bobNil; + + fWorking = TRUE; + } + + if (idef < idefMac) { + bob = BobFrClsIdx(clsDef, idef); + idef++; + return bob; + } + + idxQyCur++; + fWorking = FALSE; + } +} diff --git a/private/utils/mep/browser/bsc/revtree.c b/private/utils/mep/browser/bsc/revtree.c new file mode 100644 index 000000000..45d801553 --- /dev/null +++ b/private/utils/mep/browser/bsc/revtree.c @@ -0,0 +1,198 @@ +// +// revtree.c +// +// two routines for printing out ascii reverse call tree's +// +#include +#include +#if defined(OS2) +#define INCL_NOCOMMON +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#define INCL_DOSMISC +#include +#else +#include +#endif + +#include + + +#include "hungary.h" +#include "bsc.h" +#include "bscsup.h" + +// forward declarations +static BOOL FUsedInst(IINST iinst); +static VOID dRevTree(IINST iinst, WORD cuby); + + +// static variables +static BYTE *UbyBits = NULL; +static WORD cNest = 0; + +VOID BSC_API +RevTreeInst (IINST iinst) +// emit the call tree starting from the given inst +// +{ + WORD iinstMac; + int igrp; + + iinstMac = IinstMac(); + + // allocate memory for bit array + UbyBits = LpvAllocCb((WORD)(iinstMac/8 + 1)); + + // no memory -- no call tree + if (!UbyBits) return; + + igrp = iinstMac/8+1; + + while (--igrp>=0) + UbyBits[igrp] = 0; + + cNest = 0; + + dRevTree(iinst, 1); + + FreeLpv(UbyBits); +} + + +static VOID +dRevTree (IINST iinst, WORD cuby) +// emit the call tree starting from the given inst +// +// there are many block variables to keep the stack to a minimum... +{ + { + ISYM isym; + + { + ATR atr; + TYP typ; + + InstInfo(iinst, &isym, &typ, &atr); + + if (typ > INST_TYP_LABEL) + return; + } + + + { + WORD i; + cNest++; + for (i = cNest; i; i--) BSCPrintf ("| "); + } + + if (cuby > 1) + BSCPrintf ("%s[%d]", LszNameFrSym (isym), cuby); + else + BSCPrintf ("%s", LszNameFrSym (isym)); + } + + if (FUsedInst(iinst)) { + BSCPrintf ("...\n"); + cNest--; + return; + } + + BSCPrintf ("\n"); + + { + IUBY iuby, iubyMac; + IINST iinstUby; + + UbyRangeOfInst(iinst, &iuby, &iubyMac); + + for (; iuby < iubyMac; iuby++) { + UbyInfo(iuby, &iinstUby, &cuby); + dRevTree (iinstUby, cuby); + } + } + + cNest--; +} + +BOOL BSC_API +FRevTreeLsz(LSZ lszName) +// print out a call tree based on the given name +// +{ + IMOD imod; + ISYM isym; + + cNest = 0; + + if (!lszName) + return FALSE; + + { + IINST iinstMac; + int igrp; + + iinstMac = IinstMac(); + + // allocate memory for bit array + UbyBits = LpvAllocCb((WORD)(iinstMac/8 + 1)); + + // no memory -- no call tree + if (!UbyBits) return FALSE; + + igrp = iinstMac/8+1; + + while (--igrp >= 0) + UbyBits[igrp] = 0; + } + + if ((imod = ImodFrLsz (lszName)) != imodNil) { + IMS ims, imsMac; + + MsRangeOfMod(imod, &ims, &imsMac); + + BSCPrintf ("%s\n", LszNameFrMod (imod)); + + for ( ; ims < imsMac ; ims++) + dRevTree (IinstOfIms(ims), 1); + + FreeLpv(UbyBits); + return TRUE; + } + + if ((isym = IsymFrLsz (lszName)) != isymNil) { + IINST iinst, iinstMac; + + BSCPrintf ("%s\n", LszNameFrSym (isym)); + + InstRangeOfSym(isym, &iinst, &iinstMac); + + for (; iinst < iinstMac; iinst++) + dRevTree (iinst, 1); + + FreeLpv(UbyBits); + return TRUE; + } + + FreeLpv(UbyBits); + return FALSE; +} + +static BOOL +FUsedInst(IINST iinst) +// return the status bit for this iinst and set it true +// +{ + WORD igrp; + BOOL fOut; + WORD mask; + + igrp = iinst / 8; + mask = (1 << (iinst % 8)); + + fOut = !!(UbyBits[igrp] & mask); + UbyBits[igrp] |= mask; + return fOut; +} diff --git a/private/utils/mep/browser/bsc/sources b/private/utils/mep/browser/bsc/sources new file mode 100644 index 000000000..81ae33220 --- /dev/null +++ b/private/utils/mep/browser/bsc/sources @@ -0,0 +1,26 @@ +MAJORCOMP=sdktools +MINORCOMP=bsc + +TARGETNAME=bsc +TARGETPATH=obj +TARGETTYPE=LIBRARY + +INCLUDES=.;..\inc;..\..\ztools\inc + +SOURCES= bsc.c \ + bscdump.c \ + calltree.c \ + dump.c \ + filter.c \ + format.c \ + listref.c \ + outline.c \ + printf.c \ + query.c \ + revtree.c \ + stats.c \ + wild.c + + +C_DEFINES=-D_OS2_20_=0 -DNO_EXT_KEYS -Dpascal= -Dfar= -DNOLANMAN -DNT +UMTYPE=console diff --git a/private/utils/mep/browser/bsc/stats.c b/private/utils/mep/browser/bsc/stats.c new file mode 100644 index 000000000..81e2f4267 --- /dev/null +++ b/private/utils/mep/browser/bsc/stats.c @@ -0,0 +1,96 @@ + +// +// stats.c dump statistics about the database +// +#include +#include +#if defined(OS2) +#define INCL_NOCOMMON +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#define INCL_DOSMISC +#include +#else +#include +#endif + +#include + +#include "hungary.h" +#include "bsc.h" +#include "bscsup.h" + +VOID BSC_API +StatsBSC() +// Dump statistics about the BSC using the output function +// +{ + IMOD imod, imodMac; + IMS ims, imsMac; + ISYM isym, isymMac, isymT; + IINST iinst, iinstMac; + IDEF idef, idefMac; + IREF iref, irefMac; + IUSE iuse, iuseMac; + IUBY iuby, iubyMac; + TYP typ; + ATR atr; + + isymMac = IsymMac(); + imodMac = ImodMac(); + MsRangeOfMod((IMOD)(imodMac-1), &ims, &imsMac); + InstRangeOfSym((ISYM)(isymMac-1), &iinst, &iinstMac); + RefRangeOfInst((IINST)(iinstMac-1), &iref, &irefMac); + DefRangeOfInst((IINST)(iinstMac-1), &idef, &idefMac); + UseRangeOfInst((IINST)(iinstMac-1), &iuse, &iuseMac); + UbyRangeOfInst((IINST)(iinstMac-1), &iuby, &iubyMac); + + BSCPrintf("Totals\n------\n"); + BSCPrintf("MOD : %d\n", imodMac); + BSCPrintf("MODSYM : %d\n", imsMac); + BSCPrintf("SYM : %d\n", isymMac); + BSCPrintf("INST : %d\n", iinstMac); + BSCPrintf("REF : %l\n", irefMac); + BSCPrintf("DEF : %d\n", idefMac); + BSCPrintf("USE : %d\n", iuseMac); + BSCPrintf("UBY : %d\n", iubyMac); + + BSCPrintf("\n\nDetail\n\n"); + + for (imod = 0; imod < imodMac; imod++) { + MsRangeOfMod(imod, &ims, &imsMac); + BSCPrintf("%s Modsyms:%d\n", LszNameFrMod(imod), imsMac-ims); + } + + isymMac = IsymMac(); + + for (isym = 0; isym < isymMac; isym++) { + + InstRangeOfSym(isym, &iinst, &iinstMac); + + for ( ;iinst < iinstMac; iinst++) { + + DumpInst(iinst); + BSCPrintf(" "); + + InstInfo(iinst, &isymT, &typ, &atr); + + if (isym != isymT) + BSCPrintf("\t ERROR instance points back to wrong symbol!\n"); + + DefRangeOfInst(iinst, &idef, &idefMac); + BSCPrintf ("DEF %d ", idefMac-idef); + + RefRangeOfInst(iinst, &iref, &irefMac); + BSCPrintf ("REF %d ", irefMac-iref); + + UseRangeOfInst(iinst, &iuse, &iuseMac); + BSCPrintf ("USE %d ", iuseMac-iuse); + + UbyRangeOfInst(iinst, &iuby, &iubyMac); + BSCPrintf ("UBY %d\n", iubyMac-iuby); + } + } +} diff --git a/private/utils/mep/browser/bsc/wild.c b/private/utils/mep/browser/bsc/wild.c new file mode 100644 index 000000000..f07409541 --- /dev/null +++ b/private/utils/mep/browser/bsc/wild.c @@ -0,0 +1,73 @@ +// wild.c +// +// wildcard file matching +// +// +#include +#if defined(OS2) +#define INCL_NOCOMMON +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#define INCL_DOSMISC +#include +#else +#include +#endif + +#include + +#include "hungary.h" +#include "bsc.h" + +BOOL BSC_API +FWildMatch(LSZ pchPat, LSZ pchText) +// return TRUE if pchText matchs pchPat in the dos wildcard sense +// +// REVIEW for 1.2 file name support +// +{ + for (;;) { + switch (*pchPat) { + case '\0': + return *pchText == '\0'; + + case '.': + pchPat++; + switch (*pchText) { + case '.': + pchText++; + break; + + case '\0': + break; + + default: + return FALSE; + } + break; + + case '*': + pchPat++; + while (*pchText != '\0' && *pchText != '.') + pchText++; + while (*pchPat != '\0' && *pchPat != '.') + pchPat++; + break; + + case '?': + pchPat++; + if (*pchText != '\0' && *pchText != '.') + pchText++; + break; + + default: + if (*pchText != *pchPat) + return FALSE; + pchPat++; + pchText++; + break; + } + } +} diff --git a/private/utils/mep/browser/bscdump/bscdump.c b/private/utils/mep/browser/bscdump/bscdump.c new file mode 100644 index 000000000..82ffa3104 --- /dev/null +++ b/private/utils/mep/browser/bscdump/bscdump.c @@ -0,0 +1,324 @@ +/* + * BSCdump - Browser Data Base (.BSC) Dumper + * (C) 1988 By Microsoft + * + * + */ +#include +#include +#define LINT_ARGS +#if defined(OS2) +#define INCL_NOCOMMON +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#define INCL_DOSMISC +#include +#else +#include +#endif + +#include + + +#include "bscdump.h" +#include "version.h" +#include "hungary.h" +#include "bsc.h" +#include "bscsup.h" +#include "sbrvers.h" + +// this is gross but I don't know where these are supposed to come from +// + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +#if defined (DEBUG) +char fDEBUG = FALSE; +#endif + +char *psymbol = NULL; +char *OutlineFileName = NULL; +char far * fname; + +extern char *strdup(); + +void DumpRefsLsz(LSZ); +void DumpDefsLsz(LSZ); +void ListRdds(MBF); + +main (argc, argv) +int argc; +char *argv[]; +{ + unsigned char Cont; + unsigned char fCalltree = FALSE; + unsigned char fSymRefs = FALSE; + unsigned char fSymDefs = FALSE; + unsigned char fRevtree = FALSE; + unsigned char fDumpStats = FALSE; + unsigned char fRedundant = FALSE; + MBF mbf = mbfNil, mbfRef = mbfNil, mbfRdd = mbfNil; + + char *s; + --argc; + ++argv; + while (argc && ((**argv == '-') || (**argv == '-'))) { + Cont = TRUE; + while (Cont && *++*argv) + switch (**argv) { + case 'o': + s = *argv+1; + while (*s) { + switch (*s) { + case 'F': mbf |= mbfFuncs; break; + case 'M': mbf |= mbfMacros; break; + case 'V': mbf |= mbfVars; break; + case 'T': mbf |= mbfTypes; break; + } + s++; + } + + if (mbf == mbfNil) mbf = mbfAll; + if (--argc == 0) + Usage(); + OutlineFileName = *++argv; + Cont = FALSE; + break; + + case 'l': + s = *argv+1; + while (*s) { + switch (*s) { + case 'F': mbfRef |= mbfFuncs; break; + case 'M': mbfRef |= mbfMacros; break; + case 'V': mbfRef |= mbfVars; break; + case 'T': mbfRef |= mbfTypes; break; + } + s++; + } + + if (mbfRef == mbfNil) mbfRef = mbfAll; + Cont = FALSE; + break; + + case 'u': + s = *argv+1; + while (*s) { + switch (*s) { + case 'F': mbfRdd |= mbfFuncs; break; + case 'M': mbfRdd |= mbfMacros; break; + case 'V': mbfRdd |= mbfVars; break; + case 'T': mbfRdd |= mbfTypes; break; + } + s++; + } + + if (mbfRdd == mbfNil) mbfRdd = mbfAll; + Cont = FALSE; + break; + + case 't': + if (--argc == 0) Usage(); + psymbol = *++argv; + fCalltree = TRUE; + Cont = FALSE; + break; + + case 'r': + if (--argc == 0) Usage(); + psymbol = *++argv; + fSymRefs = TRUE; + Cont = FALSE; + break; + + case 'd': + if (--argc == 0) Usage(); + psymbol = *++argv; + fSymDefs = TRUE; + Cont = FALSE; + break; + + case 'b': + if (--argc == 0) Usage(); + psymbol = *++argv; + fRevtree = TRUE; + Cont = FALSE; + break; + + case 's': + fDumpStats = TRUE; + break; + + default: + Usage(); + break; + } + --argc; + ++argv; + } + + if (argc < 1) { + Usage(); + } + + fname = strdup(*argv++); + + if (!FOpenBSC(fname)) { + BSCPrintf("BSCdump: cannot open database %s\n", fname); + exit(4); + } + + if (fDumpStats) + StatsBSC(); + else if (fCalltree) + FCallTreeLsz(psymbol); + else if (fSymRefs) + DumpRefsLsz(psymbol); + else if (fSymDefs) + DumpDefsLsz(psymbol); + else if (fRevtree) + FRevTreeLsz(psymbol); + else if (OutlineFileName) + FOutlineModuleLsz(OutlineFileName, mbf); + else if (mbfRef) + ListRefs(mbfRef); + else if (mbfRdd) + ListRdds(mbfRdd); + else + DumpBSC(); + + CloseBSC(); + + free (fname); +} + +Usage() +{ + BSCPrintf("Microsoft (R) BSCdump Utility "); + BSCPrintf(VERS(rmj, rmm, rup)); + BSCPrintf(CPYRIGHT); + + BSCPrintf("Usage: bscdump [options] file.bsc\n\n"); + BSCPrintf(" -o[FVMT] outline\n"); + BSCPrintf(" -l[FVMT] List References\n"); + BSCPrintf(" -u[FVMT] List Redundant definitions\n"); + BSCPrintf(" -t Calltree \n"); + BSCPrintf(" -b Backwards Calltree \n"); + BSCPrintf(" -s Emit BSC stats\n"); + BSCPrintf(" -r List all references to symbol\n"); + BSCPrintf(" -d List all definitions of symbol\n"); + exit(1); +} + +void DumpDefsLsz(LSZ lszSym) +{ + ISYM isym; + IINST iinst, iinstMac; + IDEF idef, idefMac; + LSZ lsz; + WORD line; + + isym = IsymFrLsz(lszSym); + + if (isym == isymNil) { + BSCPrintf("unknown symbol %s\n", lszSym); + return; + } + + InstRangeOfSym(isym, &iinst, &iinstMac); + + for (;iinst < iinstMac; iinst++) { + + DefRangeOfInst(iinst, &idef, &idefMac); + + for ( ; idef < idefMac; idef++) { + DefInfo(idef, &lsz, &line); + BSCPrintf("%s %d\n", lsz, line); + } + } + +} + +void DumpRefsLsz(LSZ lszSym) +{ + ISYM isym; + IINST iinst, iinstMac; + IREF iref, irefMac; + LSZ lsz; + WORD line; + + isym = IsymFrLsz(lszSym); + + if (isym == isymNil) { + BSCPrintf("unknown symbol %s\n", lszSym); + return; + } + + InstRangeOfSym(isym, &iinst, &iinstMac); + + for (;iinst < iinstMac; iinst++) { + + RefRangeOfInst(iinst, &iref, &irefMac); + + for ( ; iref < irefMac; iref++) { + RefInfo(iref, &lsz, &line); + BSCPrintf("%s %d\n", lsz, line); + } + } + +} + +void ListRdds(MBF mbf) +{ + ISYM isym, isymMac, isymname; + IINST iinst, iinstMac; + IUBY iubyFirst, iubyLast; + LSZ lszsymname; + TYP iinsttyp; + ATR iinstattr; + + isymMac = IsymMac(); + + for (isym = 0 ; isym < isymMac ; isym++) + { + lszsymname = LszNameFrSym(isym); + InstRangeOfSym(isym,&iinst,&iinstMac); + + for ( ; iinst < iinstMac ; iinst++) + { + UbyRangeOfInst(iinst,&iubyFirst,&iubyLast); + + if (iubyFirst == iubyLast) + { + InstInfo(iinst,&isymname, &iinsttyp, &iinstattr); + + // iinstattr &= INST_TYPMASK; + + if (iinsttyp <= INST_TYP_LABEL && !!(mbf & mbfFuncs)) + + BSCPrintf("Function not called : %s\n",lszsymname); + + else if + ((iinsttyp <= INST_TYP_VARIABLE || + iinsttyp >= INST_TYP_SEGMENT ) && !!(mbf & mbfVars)) + + BSCPrintf("Variable not used : %s\n",lszsymname); + + else if + (iinsttyp <= INST_TYP_MACRO && !!(mbf & mbfMacros)) + + BSCPrintf("Macro not referenced : %s\n",lszsymname); + + else if (!!(mbf & mbfTypes)) + + BSCPrintf("Type not referenced : %s\n",lszsymname); + + } + } + } +} diff --git a/private/utils/mep/browser/bscdump/bscdump.h b/private/utils/mep/browser/bscdump/bscdump.h new file mode 100644 index 000000000..da2c4f157 --- /dev/null +++ b/private/utils/mep/browser/bscdump/bscdump.h @@ -0,0 +1,15 @@ +/*** bscdump.h +* +* Copyright 1988, Microsoft Corporation +* +* Revision History: +* +* 28-Jul-1989 dw Removed extraneous defs of TRUE, FALSE +* 05-Jul-1989 mt Added the option to list redundant symbols +* +*************************************************************************/ +#define BUFLEN 251 +#define EXTERNAL near + +typedef char flagType; +typedef char buffer[BUFLEN]; diff --git a/private/utils/mep/browser/bscdump/makefile b/private/utils/mep/browser/bscdump/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/utils/mep/browser/bscdump/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/utils/mep/browser/bscdump/sources b/private/utils/mep/browser/bscdump/sources new file mode 100644 index 000000000..ef27a5200 --- /dev/null +++ b/private/utils/mep/browser/bscdump/sources @@ -0,0 +1,21 @@ +MAJORCOMP=sdktools +MINORCOMP=bscdump + +TARGETNAME=bscdump +TARGETPATH=obj +TARGETTYPE=LIBRARY + + +INCLUDES=.;..\inc;\nt\private\sdktools\ztools\inc + +SOURCES= thunk.c + + + +UMAPPL=bscdump + + + +C_DEFINES=-D_OS2_20_=0 -DNO_EXT_KEYS -Dpascal= -Dfar= -DNOLANMAN -DNT +UMTYPE=console +UMLIBS= obj\*\bscdump.lib ..\bsc\obj\*\bsc.lib \nt\private\sdktools\ztools\src\obj\*\ztools.lib diff --git a/private/utils/mep/browser/bscdump/thunk.c b/private/utils/mep/browser/bscdump/thunk.c new file mode 100644 index 000000000..eb16cd3a4 --- /dev/null +++ b/private/utils/mep/browser/bscdump/thunk.c @@ -0,0 +1,174 @@ +// calback.c +// +// these are the default callbacks for the library +// +#include +#include +#include +#include +#include +#if defined(OS2) +#define INCL_NOCOMMON +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#define INCL_DOSMISC +#include +#else +#include +#endif + +#include + +#include "hungary.h" +#include "bsc.h" + +typedef char bscbuf[2048]; + +// you must define the following callbacks for the library to use + +LPV BSC_API LpvAllocCb(WORD cb) +// allocate a block of memory +// +{ + return malloc(cb); +} + +VOID BSC_API FreeLpv(LPV lpv) +// free a block of memory +// +{ + free(lpv); +} + +VOID BSC_API SeekError(LSZ lszFileName) // do not return! +// error handling +// +{ + BSCPrintf("BSC Library: Error seeking in file '%s'\n", lszFileName); + exit(1); +} + +VOID BSC_API ReadError(LSZ lszFileName) // do not return! +// error handling +// +{ + BSCPrintf("BSC Library: Error reading in file '%s'\n", lszFileName); + exit(1); +} + +VOID BSC_API BadBSCVer(LSZ lszFileName) // do not return! +// error handling +// +{ + BSCPrintf("BSC Library: '%s' not in current .bsc format\n", lszFileName); + exit(1); +} + +FILEHANDLE BSC_API +BSCOpen(LSZ lszFileName, FILEMODE mode) +// open the specified file +// +{ +#if defined (OS2) + bscbuf b; + strcpy(b, lszFileName); + return open(b, mode); +#else + return OpenFile( lszFileName, mode, FALSE, FILE_SHARE_READ); +#endif + +} + +int BSC_API +BSCRead(FILEHANDLE handle, LPCH lpchBuf, WORD cb) +// read in the specified number of bytes +// +{ +#if defined (OS2) + bscbuf b; + + while (cb > sizeof(b)) { + if (read(handle, b, sizeof(b)) == -1) return -1; + memcpy(lpchBuf, b, sizeof(b)); + cb -= sizeof(b); + lpchBuf += sizeof(b); + } + + if (read(handle, b, cb) == -1) return -1; + memcpy(lpchBuf, b, cb); + return cb; +#else + return ReadFile(handle, lpchBuf, cb); +#endif + +} + +int BSC_API +BSCClose(FILEHANDLE handle) +// close the specified handle +// +{ +#if defined (OS2) + return close(handle); +#else + return !CloseHandle( handle ); +#endif + +} + +int BSC_API +BSCSeek(FILEHANDLE handle, long lPos, FILEMODE mode) +// seek on the specified handle +// +{ +#if defined (OS2) + if (lseek(handle, lPos, mode) == -1) + return -1; + else + return 0; +#else + if (SetFilePointer( handle, lPos, 0L, mode) == -1) { + return -1; + } else { + return 0; + } +#endif + +} + +VOID BSC_API +BSCOutput(LSZ lsz) +// write the given string to the standard output +// +{ + bscbuf b; + int cb; + + cb = strlen(lsz); + + while (cb > sizeof(b)) { + memcpy(b, lsz, sizeof(b)); + + if (write(1, b, sizeof(b)) == -1) return; + + cb -= sizeof(b); + lsz += sizeof(b); + } + + memcpy(b, lsz, cb); + write(1, b, cb); + return; +} + +#ifdef DEBUG +VOID BSC_API +BSCDebugOut(LSZ lsz) +// ignore debug output by default +// +{ + // unreferenced lsz + lsz = NULL; +} +#endif diff --git a/private/utils/mep/browser/dirs b/private/utils/mep/browser/dirs new file mode 100644 index 000000000..52fcdbe99 --- /dev/null +++ b/private/utils/mep/browser/dirs @@ -0,0 +1,25 @@ +!IF 0 + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + dirs. + +Abstract: + + This file specifies the subdirectories of the current directory that + contain component makefiles. + + +Author: + + Steve Wood (stevewo) 17-Apr-1990 + + +!ENDIF + +DIRS=bsc \ + mbrmake + +OPTIONAL_DIRS= diff --git a/private/utils/mep/browser/inc/bsc.h b/private/utils/mep/browser/inc/bsc.h new file mode 100644 index 000000000..6286baabd --- /dev/null +++ b/private/utils/mep/browser/inc/bsc.h @@ -0,0 +1,228 @@ + +// bsc.h +// + +#include + +#define BSC_API far + +#if defined (OS2) +typedef int FILEHANDLE; +typedef int FILEMODE; +#else +typedef HANDLE FILEHANDLE; +typedef DWORD FILEMODE; +#endif + +////////////////////////////////////////////////////////////////////// +// you must define the following callbacks for the library to use +// to avoid dependancy on the C standard io library. If you don't +// define these then you accept the defaults which call C runtime +// + +// malloc and free workalikes + +LPV BSC_API LpvAllocCb(WORD cb); +VOID BSC_API FreeLpv(LPV lpv); + +// open, read, close, seek workalikes + +FILEHANDLE BSC_API BSCOpen(LSZ lszFileName, FILEMODE mode); +int BSC_API BSCRead(FILEHANDLE handle, LPCH lpchBuf, WORD cb); +int BSC_API BSCSeek(FILEHANDLE handle, long lPos, FILEMODE mode); +int BSC_API BSCClose(FILEHANDLE handle); + + +// ascii text output routine + +VOID BSC_API BSCOutput(LSZ lsz); + +#ifdef DEBUG +VOID BSC_API BSCDebugOut(LSZ lsz); +VOID BSC_API BSCDebug(LSZ lszFormat, ...); +#endif + +// error handling routines +// +VOID BSC_API SeekError(LSZ lszFileName); // (may choose to not return) +VOID BSC_API ReadError(LSZ lszFileName); // (may choose to not return) +VOID BSC_API BadBSCVer(LSZ lszFileName); // (may choose to not return) + +// end of callbacks +// +/////////////////////////////////////////////////////////////////////// + +// an IDX is guaranteed to be big enough to hold any of the +// database index types, i.e. it is a generic index + +typedef DWORD IDX; + +#define idxNil 0xffffffffL +#define isymNil 0xffffL +#define imodNil 0xffffL + +// definition and prototypes for use with the bsc library +// +typedef WORD IMOD; +typedef WORD IMS; +typedef WORD ISYM; +typedef WORD IINST; +typedef DWORD IREF; +typedef WORD IDEF; +typedef WORD IUSE; +typedef WORD IUBY; +typedef WORD TYP; +typedef WORD ATR; + +// Open the specified data base. +// Return TRUE iff successful, FALSE if database can't be read +// +BOOL BSC_API FOpenBSC (LSZ lszName); + +// close database and free as much memory as possible +// +VOID BSC_API CloseBSC(VOID); + +// return the length of the largest symbol in the database +// +WORD BSC_API BSCMaxSymLen(VOID); + +// is this database built with a case sensitive language? +// +BOOL BSC_API FCaseBSC(VOID); + +// override the case sensitivity of the database, symbol lookups become +// case (in)sensistive as specified +// +VOID BSC_API SetCaseBSC(BOOL fCaseSensitive); + +// do a case insenstive compare qualified by a case sensitive compare +// if fCase is true -- this is the order of symbols in the symbol list +int BSC_API CaseCmp(LSZ lsz1, LSZ lsz2); + +// return the name of the given symbol +// +LSZ BSC_API LszNameFrSym (ISYM isym); + +// return the name of the given module +// +LSZ BSC_API LszNameFrMod (IMOD imod); + +// return the imod with the given name -- imodNil if none +// +IMOD BSC_API ImodFrLsz(LSZ lszModName); + +// return the isym with the given name -- isymNil if none +// +ISYM BSC_API IsymFrLsz(LSZ lszSymName); + +// return the biggest isym in this database, isyms run from 0 to this value - 1 +// +ISYM BSC_API IsymMac(VOID); + +// return the biggest imod in this database, imods run from 0 to this value - 1 +// +IMOD BSC_API ImodMac(VOID); + +// return the biggest iinst in this database, iinsts run from 0 to the value -1 +IINST BSC_API IinstMac(VOID); + +// fill in the range of MS items valid for this module +// +VOID BSC_API MsRangeOfMod(IMOD imod, IMS far *pimsFirst, IMS far *pimsLast); + +// give the instance index of the module symbol (MS) +// +IINST BSC_API IinstOfIms(IMS ims); + +// fill in the range of inst values for this symbol +// +VOID BSC_API InstRangeOfSym(ISYM isym, IINST far *piinstFirst, IINST far *piinstLast); + +// get the information that qualifies this instance +// +VOID BSC_API InstInfo(IINST iinst, ISYM far *pisymInst, TYP far *typ, ATR far *atr); + +// fill in the reference ranges from the inst +// +VOID BSC_API RefRangeOfInst(IINST iinst, IREF far *pirefFirst, IREF far *pirefLast); + +// fill in the definition ranges from the inst +// +VOID BSC_API DefRangeOfInst(IINST iinst, IDEF far *pidefFirst, IDEF far *pidefLast); + +// fill in the use ranges from the inst +// +VOID BSC_API UseRangeOfInst(IINST iinst, IUSE far *piuseFirst, IUSE far *piuseLast); + +// fill in the used by ranges from the inst +// +VOID BSC_API UbyRangeOfInst(IINST iinst, IUBY far *piubyFirst, IUBY far *piubyLast); + +// fill in the information about this things which an inst uses +// +VOID BSC_API UseInfo(IUSE iuse, IINST far *piinst, WORD far *pcnt); + +// fill in the information about this things which an inst is used by +// +VOID BSC_API UbyInfo(IUBY iuby, IINST far *piinst, WORD far *pcnt); + +// fill in the information about this reference +// +VOID BSC_API RefInfo(IREF iref, LSZ far *plszName, WORD far *pline); + +// fill in the information about this definition +// +VOID BSC_API DefInfo(IDEF idef, LSZ far *plszName, WORD far *pline); + +// these are the bit values for the InstInfo() TYP and ATR types +// +// + +// this is the type part of the field, it describes what sort of object +// we are talking about. Note the values are sequential -- the item will +// be exactly one of these things +// + +#define INST_TYP_FUNCTION 0x01 +#define INST_TYP_LABEL 0x02 +#define INST_TYP_PARAMETER 0x03 +#define INST_TYP_VARIABLE 0x04 +#define INST_TYP_CONSTANT 0x05 +#define INST_TYP_MACRO 0x06 +#define INST_TYP_TYPEDEF 0x07 +#define INST_TYP_STRUCNAM 0x08 +#define INST_TYP_ENUMNAM 0x09 +#define INST_TYP_ENUMMEM 0x0A +#define INST_TYP_UNIONNAM 0x0B +#define INST_TYP_SEGMENT 0x0C +#define INST_TYP_GROUP 0x0D + +// this is the attribute part of the field, it describes the storage +// class and/or scope of the instance. Any combination of the bits +// might be set by some language compiler, but there are some combinations +// that done make sense. + +#define INST_ATR_LOCAL 0x001 +#define INST_ATR_STATIC 0x002 +#define INST_ATR_SHARED 0x004 +#define INST_ATR_NEAR 0x008 +#define INST_ATR_COMMON 0x010 +#define INST_ATR_DECL_ONLY 0x020 +#define INST_ATR_PUBLIC 0x040 +#define INST_ATR_NAMED 0x080 +#define INST_ATR_MODULE 0x100 + +// simple minded printf replacements, only %d, %s supported -- SMALL + +VOID BSC_API BSCFormat(LPCH lpchOut, LSZ lszFormat, va_list va); +VOID BSC_API BSCSprintf(LPCH lpchOut, LSZ lszFormat, ...); +VOID BSC_API BSCPrintf(LSZ lszFormat, ...); + + +// rjsa 10/22/90 +// Some runtime library functions are broken, so intrinsics have +// to be used. +// BUGBUG +//#pragma intrinsic (memset, memcpy, memcmp) +//#pragma intrinsic (strset, strcpy, strcmp, strcat, strlen) diff --git a/private/utils/mep/browser/inc/bscsup.h b/private/utils/mep/browser/inc/bscsup.h new file mode 100644 index 000000000..10f6cca24 --- /dev/null +++ b/private/utils/mep/browser/inc/bscsup.h @@ -0,0 +1,106 @@ + +// bscsup.h +// +// BSC high level support functions +// + +VOID BSC_API StatsBSC(VOID); // ascii dump of bsc statistics +VOID BSC_API DumpBSC(VOID); // ascii dump of the .bsc file +VOID BSC_API DumpInst(IINST iinst); // ascii dump of single inst (name + flags) +LSZ BSC_API LszTypInst(IINST iinst); // ascii version of iinst type + +VOID BSC_API CallTreeInst (IINST iinst); // call tree from given inst +BOOL BSC_API FCallTreeLsz(LSZ lszName); // call tree from given name + +VOID BSC_API RevTreeInst (IINST iinst); // reverse call tree from given inst +BOOL BSC_API FRevTreeLsz(LSZ lszName); // reverse call tree from given name + +// Browse OBject + +typedef DWORD BOB; + +#define bobNil 0L + +typedef WORD CLS; + +#define clsMod 1 +#define clsInst 2 +#define clsRef 3 +#define clsDef 4 +#define clsUse 5 +#define clsUby 6 +#define clsSym 7 + +#define BobFrClsIdx(cls, idx) ((((long)(cls)) << 24) | (idx)) +#define ClsOfBob(bob) (CLS)((bob) >> 24) + +#define ImodFrBob(bob) ((IMOD)(bob)) +#define IinstFrBob(bob) ((IINST)(bob)) +#define IrefFrBob(bob) ((IREF)((bob) & 0xffffffL)) +#define IdefFrBob(bob) ((IDEF)(bob)) +#define IuseFrBob(bob) ((IUSE)(bob)) +#define IubyFrBob(bob) ((IUBY)(bob)) +#define IsymFrBob(bob) ((ISYM)(bob)) + +#define BobFrMod(x) (BobFrClsIdx(clsMod, (x))) +#define BobFrSym(x) (BobFrClsIdx(clsSym, (x))) +#define BobFrInst(x) (BobFrClsIdx(clsInst, (x))) +#define BobFrRef(x) (BobFrClsIdx(clsDef, (x))) +#define BobFrDef(x) (BobFrClsIdx(clsRef, (x))) +#define BobFrUse(x) (BobFrClsIdx(clsUse, (x))) +#define BobFrUby(x) (BobFrClsIdx(clsUby, (x))) + +// these are the query types +// +typedef enum _qy_ { + qyFiles, qySymbols, qyContains, + qyCalls, qyCalledBy, qyUses, qyUsedBy, + qyUsedIn, qyDefinedIn, + qyDefs, qyRefs +} QY; + +// these are visible so that you can see how the query is progressing +// you may not write on these -- these values may or may not have anything +// to do with any database indices +// + +extern IDX far idxQyStart; +extern IDX far idxQyCur; +extern IDX far idxQyMac; + +BOOL BSC_API InitBSCQuery (QY qy, BOB bob); +BOB BSC_API BobNext(VOID); + +LSZ BSC_API LszNameFrBob(BOB bob); +BOB BSC_API BobFrName(LSZ lsz); + +// these are the instance types you can filter on +// they are called MBF's for historical reasons which are not clear to me +// + +typedef WORD MBF; + +// these may be or'd together + +#define mbfNil 0 +#define mbfVars 1 +#define mbfFuncs 2 +#define mbfMacros 4 +#define mbfTypes 8 +#define mbfAll 15 + +BOOL BSC_API FInstFilter (IINST iinst, MBF mbf); + +// show outline for the given files (by imod, or by Pattern) +// +VOID BSC_API OutlineMod(IMOD imod, MBF mbfReqd); +BOOL BSC_API FOutlineModuleLsz (LSZ lszPattern, MBF mbfReqd); +LSZ BSC_API LszBaseName(LSZ lsz); + +// list references for all symbols meeting the mbf requirement +// +BOOL BSC_API ListRefs (MBF mbfReqd); + +// DOS style wildcard matching +// +BOOL BSC_API FWildMatch(LSZ lszPat, LSZ lszText); diff --git a/private/utils/mep/browser/inc/hungary.h b/private/utils/mep/browser/inc/hungary.h new file mode 100644 index 000000000..0535ea6b0 --- /dev/null +++ b/private/utils/mep/browser/inc/hungary.h @@ -0,0 +1,31 @@ +// instant hungarian + +// base types +// + +// #define FAR far +// #define NEAR near + +// #define TRUE 1 +// #define FALSE 0 + +// typedef void VOID; +// typedef unsigned char BYTE; +// typedef unsigned short WORD; +// typedef int INT; +// typedef unsigned long DWORD; +// typedef long LONG; +// typedef unsigned short BOOL; + +//typedef USHORT WORD; +//typedef ULONG DWORD; + +// pointer types +// +typedef char NEAR * SZ; +typedef char FAR * LSZ; +typedef void FAR * LPV; +typedef BYTE FAR * LPB; +//typedef char FAR * LPCH; + +#define API NEAR pascal diff --git a/private/utils/mep/browser/inc/mbrcache.h b/private/utils/mep/browser/inc/mbrcache.h new file mode 100644 index 000000000..c0ae3b600 --- /dev/null +++ b/private/utils/mep/browser/inc/mbrcache.h @@ -0,0 +1,7 @@ +#define MAXATOMPAGETBL 32 /* # of Cache Pages */ +#define ATOMALLOC 512 /* Atom Cache page size */ + +typedef struct pgetlb { + unsigned uPage; /* Cache page */ + char far * pfAtomCache; /* Atom Cache loc */ + } CACHEPAGE; diff --git a/private/utils/mep/browser/inc/sbrbsc.h b/private/utils/mep/browser/inc/sbrbsc.h new file mode 100644 index 000000000..26714fab7 --- /dev/null +++ b/private/utils/mep/browser/inc/sbrbsc.h @@ -0,0 +1,43 @@ +#define BSC_MAJ 1 +#define BSC_MIN 0 +#define BSC_UPD 4 + +#pragma pack(1) + +typedef struct { + WORD ModName; // module name symbol index */ + WORD mSymEnd; // last ModSym index */ +} MODLIST; + +typedef struct { + WORD ModSymProp; // sym 1st property index */ +} MODSYMLIST; + +typedef struct { + WORD PropEnd; // last Property index */ + WORD Atom; // Atom cache sym idx */ + WORD Page; // Atom cache sym page */ +} SYMLIST; + +typedef struct { + WORD PropName; // owner name symbol index + WORD PropAttr; // Property attribute + WORD DefEnd; // last Definition index + DWORD RefEnd; // last Reference index + WORD CalEnd; // last Calls/uses index + WORD CbyEnd; // last Calld/used index +} PROPLIST; + +typedef struct { + WORD RefNam; // file name symbol index + WORD RefLin; // reference line number + WORD isbr; // sbr file this item is found in +} REFLIST; + +typedef struct { + WORD UseProp; // symbol called/used (by) + BYTE UseCnt; // symbol called/used (by) cnt + WORD isbr; // sbr file this item is found in +} USELIST; + +#pragma pack() diff --git a/private/utils/mep/browser/inc/sbrfdef.h b/private/utils/mep/browser/inc/sbrfdef.h new file mode 100644 index 000000000..a9ec4be0d --- /dev/null +++ b/private/utils/mep/browser/inc/sbrfdef.h @@ -0,0 +1,65 @@ +// sdbfdef.h Source Browser .SBR file definitions + +#define S_EOF 255 + +#define SBR_L_UNDEF 0 // Undefined +#define SBR_L_BASIC 1 // Basic +#define SBR_L_C 2 // C +#define SBR_L_FORTRAN 3 // Fortran +#define SBR_L_MASM 4 // MASM +#define SBR_L_PASCAL 5 // Pascal +#define SBR_L_COBOL 6 // Cobol + +#define SBR_REC_HEADER 0x00 // Header +#define SBR_REC_MODULE 0x01 // Module definition +#define SBR_REC_LINDEF 0x02 // Line Number +#define SBR_REC_SYMDEF 0x03 // Symbol Definition +#define SBR_REC_SYMREFUSE 0x04 // Symbol Reference +#define SBR_REC_SYMREFSET 0x05 // Symbol Ref and assign +#define SBR_REC_MACROBEG 0x06 // Macro Start +#define SBR_REC_MACROEND 0x07 // Macro End +#define SBR_REC_BLKBEG 0x08 // Block Start +#define SBR_REC_BLKEND 0x09 // Block End +#define SBR_REC_MODEND 0x0A // Module End +#define SBR_REC_OWNER 0x0B // Set owner of current block + + +// Column information is no longer supported in PWB 1.00 (ignored if present) + +#define SBR_REC_NOCOLUMN 1 // Missing column default 1 + +#define SBR_TYPBITS 5 +#define SBR_TYPSHIFT 11 +#define SBR_TYPMASK (0x1f << SBR_TYPSHIFT) + +#define SBR_TYP_FUNCTION (0x01 << SBR_TYPSHIFT) +#define SBR_TYP_LABEL (0x02 << SBR_TYPSHIFT) +#define SBR_TYP_PARAMETER (0x03 << SBR_TYPSHIFT) +#define SBR_TYP_VARIABLE (0x04 << SBR_TYPSHIFT) +#define SBR_TYP_CONSTANT (0x05 << SBR_TYPSHIFT) +#define SBR_TYP_MACRO (0x06 << SBR_TYPSHIFT) +#define SBR_TYP_TYPEDEF (0x07 << SBR_TYPSHIFT) +#define SBR_TYP_STRUCNAM (0x08 << SBR_TYPSHIFT) +#define SBR_TYP_ENUMNAM (0x09 << SBR_TYPSHIFT) +#define SBR_TYP_ENUMMEM (0x0A << SBR_TYPSHIFT) +#define SBR_TYP_UNIONNAM (0x0B << SBR_TYPSHIFT) +#define SBR_TYP_SEGMENT (0x0C << SBR_TYPSHIFT) +#define SBR_TYP_GROUP (0x0D << SBR_TYPSHIFT) +#define SBR_TYP_PROGRAM (0x0E << SBR_TYPSHIFT) + +#define SBR_ATRBITS 11 +#define SBR_ATRSHIFT 0 +#define SBR_ATRMASK (0x3ff << SBR_ATRSHIFT) + +#define SBR_ATR_LOCAL (0x001 << SBR_ATRSHIFT) +#define SBR_ATR_STATIC (0x002 << SBR_ATRSHIFT) +#define SBR_ATR_SHARED (0x004 << SBR_ATRSHIFT) +#define SBR_ATR_NEAR (0x008 << SBR_ATRSHIFT) +#define SBR_ATR_COMMON (0x010 << SBR_ATRSHIFT) +#define SBR_ATR_DECL_ONLY (0x020 << SBR_ATRSHIFT) +#define SBR_ATR_PUBLIC (0x040 << SBR_ATRSHIFT) +#define SBR_ATR_NAMED (0x080 << SBR_ATRSHIFT) +#define SBR_ATR_MODULE (0x100 << SBR_ATRSHIFT) + +#define SBR_VER_MAJOR 1 /* Major version */ +#define SBR_VER_MINOR 1 /* Minor version */ diff --git a/private/utils/mep/browser/inc/sbrvers.h b/private/utils/mep/browser/inc/sbrvers.h new file mode 100644 index 000000000..d1718353d --- /dev/null +++ b/private/utils/mep/browser/inc/sbrvers.h @@ -0,0 +1,7 @@ +/* + * use double macro level to force rup to be turned into string representation + */ +#define VERS(x,y,z) VERS2(x,y,z) +#define VERS2(x,y,z) " Version " #x "." #y "." #z + +#define CPYRIGHT "\nCopyright (c) Microsoft Corp 1990. All rights reserved.\n\n" diff --git a/private/utils/mep/browser/mbrmake/addtolst.c b/private/utils/mep/browser/mbrmake/addtolst.c new file mode 100644 index 000000000..056bb7a89 --- /dev/null +++ b/private/utils/mep/browser/mbrmake/addtolst.c @@ -0,0 +1,1004 @@ +// +// ADDTOLST.C - Add each record from the .SBR file to the approprate list. +// + +#define LINT_ARGS + +#include "sbrfdef.h" +#include "mbrmake.h" +#include + +// local types + +typedef struct _mstk { + struct _mstk FAR *pmstkPrev; // next module stack entry + VA vaCurMod; // saved current module + BOOL fDupMod; // saved dup module flag + BOOL fExclMod; // saved exclude module flag +} MSTK, FAR * PMSTK; + +typedef struct _bstk { + struct _bstk FAR *pbstkPrev; // next block stack entry + VA vaOwnerProp; // saved current owner +} BSTK, FAR * PBSTK; + +// static variables + +BOOL near fDupSym = FALSE; // TRUE if adding duplicate atom +BOOL near cMacroDepth = 0; // depth of MACROBEG records +WORD near ModCnt; // count of modules +WORD near isbrCur; // current SBR file index + +VA near vaUnknownSym = vaNil; // Unknown symbol +VA near vaUnknownMod = vaNil; // Unknown module + +static VA near vaOwnerProp = vaNil; // ptr to current procedure +static BOOL near fDupMod = FALSE; // duplicate module +static BOOL near fExclMod = FALSE; // exclude this module +static BOOL near fFirstMod = TRUE; // this is 1st module of file + +static PMSTK pmstkRoot; // root of module stack +static PBSTK pbstkRoot; // root of block stack + +// forward references + +static BOOL FSkipMacro(void); +static VOID PushMstk(VOID); +static VOID PushBstk(VOID); +static VOID PopMstk(VOID); +static VOID PopBstk(VOID); +static VOID CheckStacksEmpty(VOID); + +VOID +SBRCorrupt (char *psz) +// sbr file corrupt -- print message +// +{ + +#ifdef DEBUG + printf("Info = %s\n", psz); +#else + // to make /W3 happy + psz; +#endif + + Error(ERR_SBR_CORRUPT, lszFName); +} + +static VOID +PushMstk (VOID) +// stack the current module context -- occurs before SBR_REC_MODULE +// +{ + PMSTK pmstk; + + pmstk = LpvAllocCb(sizeof(*pmstk)); + + pmstk->vaCurMod = vaCurMod; // current module + pmstk->fDupMod = fDupMod; // dup module + pmstk->fExclMod = fExclMod; // exclude module + pmstk->pmstkPrev = pmstkRoot; // make stack links + pmstkRoot = pmstk; // root <- new +} + +static VOID +PushBstk (VOID) +// stack the current block context -- occurs before SBR_REC_BLKBEG +// +{ + PBSTK pbstk; + + pbstk = LpvAllocCb(sizeof(*pbstk)); + + pbstk->vaOwnerProp = vaOwnerProp; // current owner + pbstk->pbstkPrev = pbstkRoot; // make stack links + pbstkRoot = pbstk; // root <- new +} + +static VOID +PopMstk (VOID) +// restore previous module context -- occurs on SBR_REC_MODEND +// +{ + PMSTK pmstk; + + if (pmstkRoot == NULL) { +#ifdef DEBUG + SBRCorrupt("Module stack empty but MODEND was found"); +#else + SBRCorrupt(""); +#endif + } + + vaCurMod = pmstkRoot->vaCurMod; // get previous current module + fDupMod = pmstkRoot->fDupMod; // get previous dup mod flag + fExclMod = pmstkRoot->fExclMod; // get previous excl mod flag + + pmstk = pmstkRoot; + pmstkRoot = pmstkRoot->pmstkPrev; + + FreeLpv(pmstk); +} + +static VOID +PopBstk (VOID) +// restore previous block context -- occurs on SBR_REC_BLKEND +// +{ + PBSTK pbstk; + + if (pbstkRoot == NULL) { +#ifdef DEBUG + SBRCorrupt("Block stack empty but BLKEND was found"); +#else + SBRCorrupt(""); +#endif + } + + vaOwnerProp = pbstkRoot->vaOwnerProp; // get previous current proc + + pbstk = pbstkRoot; + pbstkRoot = pbstkRoot->pbstkPrev; + + FreeLpv(pbstk); +} + +static VOID +CheckStacksEmpty(VOID) +// check to make sure that both stacks are empty at the .sbr file EOF +// +{ + if (pmstkRoot != NULL) { +#ifdef DEBUG + SBRCorrupt("Module stack not empty at EOF"); +#else + SBRCorrupt(""); +#endif + } + + if (pbstkRoot != NULL) { +#ifdef DEBUG + SBRCorrupt("Block stack not empty at EOF"); +#else + SBRCorrupt(""); +#endif + } +} + +BOOL +FInExcList (LSZ lszName) +// Is the module name in the exclude file list? +// +{ + EXCLINK FAR * px; + LSZ lszAbs; + + if (OptEs && !fFirstMod) { + if (lszName[0] == '\0') return FALSE; + + if (lszName[0] == '/' || lszName[0] == '\\') return TRUE; + if (lszName[1] == ':' && lszName[2] == '/') return TRUE; + if (lszName[1] == ':' && lszName[2] == '\\') return TRUE; + } + + px = pExcludeFileList; + + // this name is relative to the path given in the header file + lszAbs = ToAbsPath(lszName, r_cwd); + + while (px) { + if ((FWildMatch (px->pxfname, lszAbs))) + return TRUE; + px = px->xnext; + } + return FALSE; +} + +static BOOL +FSkipMacro() +// return TRUE if this record should be skipped given that we are inside +// of a macro definition (i.e cMacroDepth is known to be non-zero) +// +{ + if (!OptEm) + return FALSE; + + if ((r_rectyp == SBR_REC_BLKBEG) || + (r_rectyp == SBR_REC_BLKEND) || + (r_rectyp == SBR_REC_MACROEND)) + return FALSE; + + return TRUE; +} + +VOID +InstallSBR() +// Read the next .sbr file and add all the defs/refs/cals/cbys etc to +// the various lists +// +{ + WORD nlen; + + VA vaCurSym; // current symbol + VA vaProp; // current property + VA vaOrd; // current property temp + + BOOL fSymSet = FALSE; // TRUE if symbol set reference + + r_lineno = 0; + + fExclMod = FALSE; + fFirstMod = TRUE; // we haven't seen the first MODULE record yet + + vaUnknownSym = MbrAddAtom ("", TRUE); // unknown module name + + if (vaUnknownMod == vaNil) { + + vaUnknownMod = VaAllocGrpCb(grpMod, sizeof(MOD)); + + vaCurMod = vaUnknownMod; + + gMOD(vaCurMod).csyms = 0; + cMOD.vaNameSym = vaUnknownSym; + pMOD(vaCurMod); + + gSYM(vaUnknownSym).vaFirstProp = vaCurMod; // store pointer back to MOD + pSYM(vaUnknownSym); + ModCnt++; + } + else + fDupMod = (vaUnknownMod != 0); + + vaCurMod = vaUnknownMod; + + if (vaRootMod == vaNil) + vaRootMod = vaCurMod; + + while (GetSBRRec() != S_EOF) { + + #ifdef DEBUG + if (OptD & 1) DecodeSBR (); + #endif + + if (cMacroDepth != 0) // skip SYMBOLS in macros if true + if (FSkipMacro ()) + continue; + + if (fExclMod) { + if ((r_rectyp == SBR_REC_MODULE) || + (r_rectyp == SBR_REC_SYMDEF) || + (r_rectyp == SBR_REC_MODEND)) { + ; + } + else + continue; + } + + switch(r_rectyp) { + + case SBR_REC_MODULE: + PushMstk (); // save state + + r_lineno = 0; // reset line no. + + fDupMod = FALSE; // go to a known state + fExclMod = FALSE; + + if (fExclMod = FInExcList (r_bname)) { + #ifdef DEBUG + if (OptD & 256) + printf (" module excluded = %s\n", r_bname); + #endif + vaCurMod = vaUnknownMod; + } + else if ((vaCurMod = VaSearchModule (r_bname)) != vaNil) { + if (gMOD(vaCurMod).csyms == 0) { + fDupMod = TRUE; + #ifdef DEBUG + if (OptD & 256) + printf (" module redef = %s\n", r_bname); + #endif + } + else { + cMOD.csyms = 0; + pMOD(vaCurMod); + + #ifdef DEBUG + if (OptD & 256) + printf (" module subst = %s\n", r_bname); + #endif + } + } + else { + SetVMClient(VM_ADD_MOD); + ModCnt++; + vaCurMod = VaAllocGrpCb(grpMod, sizeof(MOD)); + gMOD(vaCurMod); + cMOD.vaFirstModSym = vaNil; + cMOD.csyms = 0; + cMOD.vaNameSym = + MbrAddAtom (ToCanonPath(r_bname, r_cwd, c_cwd), TRUE); + cMOD.vaNextMod = vaRootMod; + pMOD(vaCurMod); + + vaRootMod = vaCurMod; + + gSYM(cMOD.vaNameSym).vaFirstProp = vaCurMod; // ptr to MOD + pSYM(cMOD.vaNameSym); + + SetVMClient(VM_MISC); + } + + fFirstMod = FALSE; + break; + + case SBR_REC_LINDEF: + break; + + case SBR_REC_SYMDEF: + + // if module is being excluded then just make the ord and prop entry + // in case it is referred to later. + + // REVIEW For FORTRAN if ordinal is already defined + // REVIEW then this is a refined definition -- we + // REVIEW override the old definition with the new + // REVIEW one at this time -Rico + + nlen = strlen (r_bname); + if (nlen > MaxSymLen) MaxSymLen = (BYTE)nlen; + + vaCurSym = MbrAddAtom (r_bname, FALSE); + vaOrd = VaOrdAdd (); // add sym ord to ord list + gORD(vaOrd).vaOrdProp = VaPropAddToSym(vaCurSym); + pORD(vaOrd); + + break; + + case SBR_REC_OWNER: + if (!(vaProp = VaOrdFind(r_ordinal))) { + // emit error message in case of forward reference + // try to continue + // + #ifdef DEBUG + if (OptD & 4) + printf ("mbrmake: Owner Forward Reference(%d)\n", + r_ordinal); + #endif + break; + } + vaOwnerProp = vaProp; + break; + + case SBR_REC_SYMREFSET: + fSymSet = TRUE; + // fall through + + case SBR_REC_SYMREFUSE: + + if (!(vaProp = VaOrdFind(r_ordinal))) { + // emit error message in case of forward reference + // try to continue + // + #ifdef DEBUG + if (OptD & 4) + printf ("mbrmake: Forward Reference(%d)\n", r_ordinal); + #endif + break; + } + + AddRefProp (vaProp); + break; + + case SBR_REC_BLKBEG: + PushBstk(); // save state + break; + + case SBR_REC_MACROBEG: + cMacroDepth++; + break; + + case SBR_REC_MACROEND: + cMacroDepth--; + break; + + case SBR_REC_BLKEND: + PopBstk(); + break; + + case SBR_REC_MODEND: + PopMstk(); + break; + + default: + SBRCorrupt ("unknown rec type"); + Fatal (); + break; + + } + } + + CheckStacksEmpty(); +} + +VOID +AddCalProp(VA vaCurProp) +// Add a symbol reference to the calling procedure's Calls/Uses list. +// +{ + CAL cal; + + SetVMClient(VM_SEARCH_CAL); + + ENM_LIST (gPROP(vaOwnerProp).vaCalList, CAL) // proc call list + + if (cCAL.vaCalProp == vaCurProp) { + cCAL.isbr = isbrCur; + cCAL.calcnt++; // multiple calls + ENM_PUT(CAL); + return; + } + + ENM_END + + cal.isbr = isbrCur; + cal.vaCalProp = vaCurProp; // symbol called or used + cal.calcnt = 1; + + SetVMClient(VM_ADD_CAL); + + VaAddList(&cPROP.vaCalList, &cal, sizeof(cal), grpCal); + + pPROP(vaOwnerProp); + + SetVMClient(VM_MISC); + +#ifdef DEBUG + if (OptD & 8) { + printf("New CAL for: "); + DebugDumpProp(vaOwnerProp); + } +#endif +} + +VOID +AddCbyProp(VA vaCurProp) +// Add a symbol reference to it's property Called/Used by list. +// +{ + CBY cby; + + SetVMClient(VM_SEARCH_CBY); + + ENM_LIST (gPROP(vaCurProp).vaCbyList, CBY) // prop called/used by list + + if (cCBY.vaCbyProp == vaOwnerProp) { + cCBY.isbr = isbrCur; + cCBY.cbycnt++; + ENM_PUT(CBY); + return; + } + + ENM_END + + cby.isbr = isbrCur; + cby.vaCbyProp = vaOwnerProp; // symbol we are called or used by + cby.cbycnt = 1; + + SetVMClient(VM_ADD_CBY); + + VaAddList(&cPROP.vaCbyList, &cby, sizeof(cby), grpCby); + + pPROP(vaCurProp); + + SetVMClient(VM_MISC); + +#ifdef DEBUG + if (OptD & 8) { + printf("New CBY for: "); + DebugDumpProp(vaCurProp); + } +#endif +} + +VOID +AddRefProp(VA vaCurProp) +// Add a symbol reference to it's property reference list. +// +{ + VA vaRef, vaFileSym; + + SetVMClient(VM_SEARCH_REF); + + vaFileSym = gMOD(vaCurMod).vaNameSym; + + gPROP(vaCurProp); + + if (fDupMod) { + // try looking at the hint for this PROP if there is one, if there + // isn't then we're stuck -- we must search the whole REF list + // + + if (vaRef = cPROP.vaHintRef) { + gREF(vaRef); + + if (cREF.reflin == r_lineno) { + cREF.isbr = isbrCur; + pREF(vaRef); + SetVMClient(VM_MISC); + return; + } + + vaRef = VaFrVp(cREF.vpNextRef); + if (vaRef) { + gREF(vaRef); + if (cREF.reflin == r_lineno) { + cREF.isbr = isbrCur; + pREF(vaRef); + cPROP.vaHintRef = vaRef; + pPROP(vaCurProp); + SetVMClient(VM_MISC); + return; + } + } + } + + vaRef = VaFrVp(cPROP.vpFirstRef); + + while (vaRef) { + gREF(vaRef); + if ((VaFrVp(cREF.vpFileSym) == vaFileSym) && // ignore multiple + (cREF.reflin == r_lineno)) { // references to same file & line + cREF.isbr = isbrCur; + pREF(vaRef); + cPROP.vaHintRef = vaRef; + pPROP(vaCurProp); + SetVMClient(VM_MISC); + return; + } + vaRef = VaFrVp(cREF.vpNextRef); + } + } + else { + if (vaRef = VaFrVp(cPROP.vpLastRef)) { + gREF(vaRef); + if (cREF.reflin == r_lineno && + vaFileSym == VaFrVp(cREF.vpFileSym)) { + SetVMClient(VM_MISC); + return; + } + } + } + + SetVMClient(VM_ADD_REF); + + vaRef = VaAllocGrpCb(grpRef, sizeof(REF)); + + gREF(vaRef); + cREF.isbr = isbrCur; + cREF.reflin = r_lineno; + + MkVpVa(cREF.vpFileSym, vaFileSym); + + pREF(vaRef); + + gPROP(vaCurProp); + + AddTail (Ref, REF); + + cPROP.cref++; // count references + cPROP.vaHintRef = vaRef; + + pPROP(vaCurProp); + +#ifdef DEBUG + if (OptD & 8) { + printf("New REF for: "); + DebugDumpProp(vaCurProp); + } +#endif + + SetVMClient(VM_MISC); + + if (vaOwnerProp) { + AddCbyProp (vaCurProp); // add to called/used by + AddCalProp (vaCurProp); // add to call/uses + } +} + +VOID +AddDefProp(VA vaCurProp) +// Add a symbol definition to it's property definition list. +// -Set vaOwnerProp if symbol is an internal function. +{ + DEF def; + VA vaFileSym; + +#if 0 + + // if current symbol is FUNCTION and formally declared + // (block stack not empty), then remember it. + // Subsequent symbols are called by or used by this function. + // + // this is going away when all compilers support SBR_REC_OWNER + + if ((r_attrib & SBR_TYPMASK) == SBR_TYP_FUNCTION) + if (pfblkstack != NULL && !(r_attrib & SBR_ATR_DECL_ONLY)) + vaOwnerProp = vaCurProp; +#endif + + vaFileSym = gMOD(vaCurMod).vaNameSym; + + ENM_LIST (gPROP(vaCurProp).vaDefList, DEF) // proc def list + + if ((cDEF.vaFileSym == vaFileSym) && // ignore multiple + (cDEF.deflin == r_lineno)) { // references to same file & line + cDEF.isbr = isbrCur; + ENM_PUT(DEF); + SetVMClient(VM_MISC); + return; + } + + ENM_END + + def.isbr = isbrCur; + def.deflin = r_lineno; + def.vaFileSym = vaFileSym; + + SetVMClient(VM_ADD_DEF); + + gPROP(vaCurProp); + + VaAddList(&cPROP.vaDefList, &def, sizeof(def), grpDef); + + pPROP(vaCurProp); + + SetVMClient(VM_MISC); + +#ifdef DEBUG + if (OptD & 8) { + printf("New DEF for: "); + DebugDumpProp(vaCurProp); + } +#endif + + // don't count the definitions of the current proc as uses + + if (vaOwnerProp && vaCurProp != vaOwnerProp) { + AddCbyProp (vaCurProp); // add to called/used by + AddCalProp (vaCurProp); // add to call/uses + } +} + + +VA +VaPropBestOfSym(VA vaSym) +// +// Returns property pointer if: +// 1). symbol is already defined, +// 2). attributes match (except for possibly ATR_DECL_ONLY) +// +// Idea is to recognize the definition of an external. +// +{ + VA vaProp; + WORD sattr; + + SetVMClient(VM_SEARCH_PROP); + + vaProp = gSYM(vaSym).vaFirstProp; + + while (vaProp) { + sattr = gPROP(vaProp).sattr; + + if ((r_attrib & (~SBR_ATR_DECL_ONLY)) + == (sattr & (~SBR_ATR_DECL_ONLY))) { + SetVMClient(VM_MISC); + return (vaProp); + } + + vaProp = cPROP.vaNextProp; + } + + SetVMClient(VM_MISC); + + return vaNil; +} + +VA +VaPropAddToSym(VA vaCurSym) +// Add a property node for the given symbol. +// +{ + char fDupProp = FALSE; + VA vaCurProp; + + if (vaCurProp = VaPropBestOfSym (vaCurSym)) { + if ( (cPROP.sattr & SBR_ATR_DECL_ONLY) && + !(r_attrib & SBR_ATR_DECL_ONLY)) { + cPROP.sattr = r_attrib; + pPROP(vaCurProp); + } + fDupProp = TRUE; + } + else { + SetVMClient(VM_ADD_PROP); + + vaCurProp = VaAllocGrpCb(grpProp, sizeof(PROP)); + gPROP(vaCurProp); + cPROP.vaNameSym = vaCurSym; + cPROP.sattr = r_attrib; + + if (gSYM(vaCurSym).vaFirstProp) + cPROP.vaNextProp = cSYM.vaFirstProp; + + pPROP(vaCurProp); + + cSYM.vaFirstProp = vaCurProp; + cSYM.cprop++; + pSYM(vaCurSym); + + SetVMClient(VM_MISC); + } + + if (!fExclMod) { + if (r_attrib & SBR_ATR_DECL_ONLY) + AddRefProp (vaCurProp); // treat extern as ref + else + AddDefProp (vaCurProp); // define others + } + + return (vaCurProp); +} + +VOID +BldModSymList () +// Build each module's symbol list +// +{ + WORD i; + VA vaMod, vaModSym, vaSym, vaProp; + + SetVMClient(VM_BUILD_MODSYM); + + // zero out module symbol counts + vaMod = vaRootMod; + while (vaMod) { + gMOD(vaMod); + cMOD.csyms = 0; + pMOD(vaMod); + vaMod = cMOD.vaNextMod; + } + + for (i=0; i < cSymbolsMac; i++) { + vaSym = rgvaSymSorted[i]; + + if (!vaSym) continue; + + vaProp = gSYM(vaSym).vaFirstProp; + + while (vaProp) { + ENM_LIST(gPROP(vaProp).vaDefList, DEF) + + vaMod = vaRootMod; // look at defs for each mod */ + while (vaMod) { + if (cDEF.vaFileSym == gMOD(vaMod).vaNameSym) { + + if (cMOD.vaLastModSym && + gMODSYM(cMOD.vaLastModSym).vaFirstProp == vaProp) + goto break2; // duplicate + + // belongs to this mod + cMOD.csyms++; + + vaModSym = VaAllocGrpCb(grpModSym, sizeof(MODSYM)); + gMODSYM(vaModSym); + cMODSYM.vaFirstProp = vaProp; + cMODSYM.vaNextModSym = 0; + pMODSYM(vaModSym); + + if (!cMOD.vaFirstModSym) + cMOD.vaFirstModSym = cMOD.vaLastModSym = vaModSym; + else { + gMODSYM(cMOD.vaLastModSym).vaNextModSym = vaModSym; + pMODSYM(cMOD.vaLastModSym); + cMOD.vaLastModSym = vaModSym; + } + pMOD(vaMod); + break; + } + vaMod = cMOD.vaNextMod; + } + break2: ; // duplicate Modsyms will cause goto here + ENM_END + + vaProp = cPROP.vaNextProp; + } + } + + SetVMClient(VM_MISC); +} + +VOID +CleanUp() +// 1. Remove symbols that have no references. +// 2. Remove symbols that have only references +// 3. Connect used symbols with no definition to +// +{ + WORD i; + VA vaSym, vaProp, vaPropNext, vaPropPrev = vaNil; + DEF def; + BOOL fDelete; + + #define FExternAttr(attr) (!!(attr & SBR_ATR_DECL_ONLY)) + #define FFunctionAttr(attr) ((attr & SBR_TYPMASK) == SBR_TYP_FUNCTION) + + def.vaFileSym = vaUnknownSym; + def.deflin = 0; + def.isbr = 0xffff; + + SetVMClient(VM_CLEAN_REFS); + + for (i=0; i < cSymbolsMac; i++) { + vaSym = rgvaSymSorted[i]; + + vaPropPrev = vaNil; + + vaProp = gSYM(vaSym).vaFirstProp; + + while (vaProp) { + vaPropNext = gPROP(vaProp).vaNextProp; + fDelete = FALSE; + + // figure out what to delete here + + // if the symbol is used by anyone or uses anyone we must keep it + // regardless of all other considerations + // + if (((!cPROP.vaCalList) && (!cPROP.vaCbyList)) && ( + // at this point we know there are only refs & defs + + // if it is totally unreferenced & undefined it can go + (cPROP.cref == 0 && (!cPROP.vaDefList)) + || + // if we're allowed to remove "useless" symbols then we try + ((!OptIu) && + // if there are only prototypes we can delete it + (((!cPROP.vaDefList) && FExternAttr(cPROP.sattr)) + || + // or if it is unreferenced and is not a function + (cPROP.cref == 0 && (!FFunctionAttr(cPROP.sattr))))))) { + fDelete = TRUE; // nuke it + } + else if (!cPROP.vaDefList) { + + // if we couldn't get rid of the thing, and there are no + // definitions for it then we must make a fake definition + // in the file. This will happen (in particular) + // for library functions that are called by someone + // + // library functions that are not called would fall under + // the case of a symbol with only prototypes above + + VaAddList(&cPROP.vaDefList, &def, sizeof(def), grpDef); + pPROP(vaProp); + + #ifdef DEBUG + if (OptD & 32) + printf ("PROP unknown: %s\n", GetAtomStr (vaSym)); + #endif + } + + if (fDelete) { + #ifdef DEBUG + if (OptD & 32) + printf ("PROP deleted: %s\n", GetAtomStr (vaSym)); + #endif + + cSYM.cprop--; + + if (vaPropPrev == vaNil) { + cSYM.vaFirstProp = vaPropNext; + } + else { + gPROP(vaPropPrev); + cPROP.vaNextProp = vaPropNext; + pPROP(vaPropPrev); + } + + pSYM(vaSym); + } + else + vaPropPrev = vaProp; // prev = current + + vaProp = vaPropNext; + } + + if (!cSYM.cprop) { + #ifdef DEBUG + if (OptD & 32) + printf ("SYM deleted: %s\n", GetAtomStr (vaSym)); + #endif + rgvaSymSorted[i] = vaNil; + } + } + + SetVMClient(VM_MISC); +} + +BOOL +FWildMatch(char *pchPat, char *pchText) +// return TRUE if pchText matchs pchPat in the dos wildcard sense +// +// REVIEW FWildMatch for 1.2 file name support +// +{ + char chText, chPat; + + for (;;) { + switch (*pchPat) { + + case '\0': + return *pchText == '\0'; + + case '/': + case '\\': + if (*pchText != '/' && *pchText != '\\') + return FALSE; + + pchText++; + pchPat++; + break; + + case '.': + pchPat++; + switch (*pchText) { + + case '.': + pchText++; + break; + + case '\0': case '/': case '\\': + break; + + default: + return FALSE; + } + break; + + case '*': + pchText += strcspn(pchText, ":./\\"); + pchPat += strcspn(pchPat, ":./\\"); + break; + + case '?': + pchPat++; + switch (*pchText) { + + case '\0': case '.': case '/': case '\\': + break; + + default: + pchText++; + break; + } + + break; + + default: + chText = *pchText; + chPat = *pchPat; + + if (islower(chText)) chText = (char)toupper(chText); + if (islower(chPat)) chPat = (char)toupper(chPat); + + if (chText != chPat) + return FALSE; + + pchPat++; + pchText++; + break; + } + } +} diff --git a/private/utils/mep/browser/mbrmake/casts.h b/private/utils/mep/browser/mbrmake/casts.h new file mode 100644 index 000000000..1d55b9e29 --- /dev/null +++ b/private/utils/mep/browser/mbrmake/casts.h @@ -0,0 +1,22 @@ +/* casts.h - define useful casts for calling DOS 5 API routines +** +*/ + +#define FALSE 0 +#define TRUE 1 + +typedef unsigned char byte; +typedef unsigned int word; +typedef unsigned long dword; + +typedef char * NPC; +typedef int * NPI; +typedef long * NPL; +typedef unsigned int * NPU; +typedef unsigned long * NPUL; + +typedef char far * FPC; +typedef int far * FPI; +typedef long far * FPL; +typedef unsigned int far * FPU; +typedef unsigned long far * FPUL; diff --git a/private/utils/mep/browser/mbrmake/convert.c b/private/utils/mep/browser/mbrmake/convert.c new file mode 100644 index 000000000..917c2e8a8 --- /dev/null +++ b/private/utils/mep/browser/mbrmake/convert.c @@ -0,0 +1,266 @@ +// filename conversion/canonicalization facility +// + +#include "mbrmake.h" +#include +#include + +LSZ ToCanonPath(LSZ lszPath, LSZ lszCwd, LSZ lszCanon); +VOID ToRelativePath(LSZ lszPath, LSZ lszCwd); +VOID ToBackSlashes(LSZ lsz); + +#ifdef STANDALONE + +#include +main() +{ + static char s[PATH_BUF]; + static char canon[PATH_BUF]; + static char cwd[PATH_BUF]; + + getcwd(cwd, PATH_BUF); + printf("Current Dir is %s\n", cwd); + printf("Canonical path?\n"); + gets(canon); + while (gets(s)) { + printf("%s\n", ToCanonPath(s, cwd, canon)); + } +} + +#endif + +LSZ +ToCanonPath(LSZ lszPath, LSZ lszCwd, LSZ lszCanon) +// canonicalize the given path +// +{ + LSZ p; + static char buf[PATH_BUF]; + + strcpy(buf, lszPath); + + ToBackSlashes(buf); + + if (buf[0] == 0 || buf[0] == '\\' || buf[0] == '<') + return buf; + + if (buf[1] == ':') { + // different drive is assumed invariant + if (buf[0] != lszCwd[0] || '\\' == buf[2]) + return buf; + + strcpy(buf, lszCwd); + strcat(buf, "/"); + strcat(buf, lszPath+2); + } + else { + strcpy(buf, lszCwd); + strcat(buf, "/"); + strcat(buf, lszPath); + } + + ToBackSlashes(buf); + + p = buf; + for (;;) { + p = strchr(p, '\\'); + if (!p) { + ToRelativePath(buf, lszCanon); + return buf; + } + + switch (p[1]) { + + case '\0': + *p = 0; + ToRelativePath(buf, lszCanon); + return buf; + + case '\\': + strcpy(p, p+1); + break; + + case '.': + + if (p[2] == '\\' || p[2] == 0) { + strcpy(p, p+2); + break; + } + if (p[2] == '.' && (p[3] == '\\' || p[3] == 0)) { + LSZ s; + + s = p; + + while (--s >= buf) { + if (*s == '\\') { + strcpy(s+1,p+3); + p = s; + break; + } + } + + if (s < buf) + p++; + } + break; + + default: + p++; + } + } +} + +VOID +ToRelativePath(LSZ lszPath, LSZ lszCwd) +// convert absolute path to relative +// +{ + WORD ich, ichOK; + int c1, c2; + char buf[PATH_BUF]; + + ich = ichOK = 0; + + for (ich = 0; lszPath[ich] && lszCwd[ich]; ich++) { + + c1 = lszPath[ich]; + c2 = lszCwd[ich]; + + if (c1 == c2) { + if (c1 == '\\') ichOK = ich+1; + continue; + } + + if (isupper(c1) && islower(c2) && tolower(c1) == c2) + continue; + + if (isupper(c2) && islower(c1) && tolower(c2) == c1) + continue; + + break; + } + + if (ich == 0) // not on the same drive, we can't do the conversion + return; + + if (lszCwd[ich] == 0 && lszPath[ich] == '\\') { + ichOK = ich+1; + c2 = 0; + } + else { + c2 = 1; + c1 = ichOK; + for (c1 = ichOK; lszCwd[c1]; c1++) + if (lszCwd[c1] == '\\') + c2++; + } + + buf[0] = 0; + for (c1 = 0; c1 < c2; c1++) + strcat(buf, "..\\"); + + strcat(buf, lszPath+ichOK); + strcpy(lszPath, buf); +} + +LSZ +ToAbsPath(LSZ lszPath, LSZ lszCwd) +// canonicalize the given path +// +{ + LSZ p; + static char buf[PATH_BUF]; + + strcpy(buf, lszPath); + + ToBackSlashes(buf); + + if (buf[0] == '<') + return buf; + + if (buf[0] == 0) { + strcpy(buf, lszCwd); + ToBackSlashes(lszCwd); + return buf; + } + + if (buf[0] == '\\') { + buf[0] = lszCwd[0]; + buf[1] = ':'; + strcpy(buf+2, lszPath); + ToBackSlashes(buf); + return buf; + } + + if (buf[1] == ':') { + // different drive is assumed invariant + if (buf[0] != lszCwd[0] || buf[2] == '\\') + return buf; + + strcpy(buf, lszCwd); + strcat(buf, "/"); + strcat(buf, lszPath+2); + } + else { + strcpy(buf, lszCwd); + strcat(buf, "/"); + strcat(buf, lszPath); + } + + ToBackSlashes(buf); + + p = buf; + for (;;) { + p = strchr(p, '\\'); + if (!p) return buf; + + switch (p[1]) { + + case '\0': + *p = 0; + return buf; + + case '\\': + strcpy(p, p+1); + break; + + case '.': + + if (p[2] == '\\' || p[2] == 0) { + strcpy(p, p+2); + break; + } + if (p[2] == '.' && (p[3] == '\\' || p[3] == 0)) { + LSZ s; + + s = p; + + while (--s >= buf) { + if (*s == '\\') { + strcpy(s+1,p+3); + p = s; + break; + } + } + + if (s < buf) + p++; + } + break; + + default: + p++; + } + } +} + +VOID +ToBackSlashes(LSZ lsz) +// convert forward slashes to backslashes +// +{ + while (*lsz) { + if (*lsz == '/') *lsz = '\\'; + lsz ++; + } +} diff --git a/private/utils/mep/browser/mbrmake/dcodesbr.c b/private/utils/mep/browser/mbrmake/dcodesbr.c new file mode 100644 index 000000000..eff86b6ab --- /dev/null +++ b/private/utils/mep/browser/mbrmake/dcodesbr.c @@ -0,0 +1,148 @@ +// +// +// DCODESBR.C - dumps a human readable version of the current .sbr file +// record from the r_... variables +// +// + +#include "sbrfdef.h" +#include "mbrmake.h" + +char * near prectab[] = { + "HEADER", // SBR_REC_HEADER + "MODULE", // SBR_REC_MODULE + "LINDEF", // SBR_REC_LINDEF + "SYMDEF", // SBR_REC_SYMDEF + "SYMREFUSE", // SBR_REC_SYMREFUSE + "SYMREFSET", // SBR_REC_SYMREFSET + "MACROBEG", // SBR_REC_MACROBEG + "MACROEND", // SBR_REC_MACROEND + "BLKBEG", // SBR_REC_BLKBEG + "BLKEND", // SBR_REC_BLDEND + "MODEND", // SBR_REC_MODEND + "OWNER" // SBR_REC_OWNER +}; + +char * near plangtab[] = { + "UNDEF", // SBR_L_UNDEF + "BASIC", // SBR_L_BASIC + "C", // SBR_L_C + "FORTRAN", // SBR_L_FORTRAN + "MASM", // SBR_L_MASM + "PASCAL", // SBR_L_PASCAL + "COBOL" // SBR_L_COBOL +}; + +char * near ptyptab[] = { + "UNDEF", // SBR_TYP_UNKNOWN + "FUNCTION", // SBR_TYP_FUNCTION + "LABEL", // SBR_TYP_LABEL + "PARAMETER", // SBR_TYP_PARAMETER + "VARIABLE", // SBR_TYP_VARIABLE + "CONSTANT", // SBR_TYP_CONSTANT + "MACRO", // SBR_TYP_MACRO + "TYPEDEF", // SBR_TYP_TYPEDEF + "STRUCNAM", // SBR_TYP_STRUCNAM + "ENUMNAM", // SBR_TYP_ENUMNAM + "ENUMMEM", // SBR_TYP_ENUMMEM + "UNIONNAM", // SBR_TYP_UNIONNAM + "SEGMENT", // SBR_TYP_SEGMENT + "GROUP", // SBR_TYP_GROUP + "PROGRAM" // SBR_TYP_PROGRAM +}; + +char * near patrtab[] = { + "LOCAL", // SBR_ATR_LOCAL + "STATIC", // SBR_ATR_STATIC + "SHARED", // SBR_ATR_SHARED + "NEAR", // SBR_ATR_NEAR + "COMMON", // SBR_ATR_COMMON + "DECL_ONLY", // SBR_ATR_DECL_ONLY + "PUBLIC", // SBR_ATR_PUBLIC + "NAMED", // SBR_ATR_NAMED + "MODULE", // SBR_ATR_MODULE + "?", "?" // reserved for expansion +}; + +VOID +DecodeSBR () +{ + int i; + static indent; + + switch(r_rectyp) { + case SBR_REC_MACROEND: + case SBR_REC_BLKEND: + case SBR_REC_MODEND: + indent--; + break; + + case SBR_REC_HEADER: + case SBR_REC_MODULE: + case SBR_REC_LINDEF: + case SBR_REC_SYMDEF: + case SBR_REC_SYMREFUSE: + case SBR_REC_SYMREFSET: + case SBR_REC_MACROBEG: + case SBR_REC_BLKBEG: + case SBR_REC_OWNER: + break; + + default: + fprintf(streamOut, "invalid record type %0xh", r_rectyp); + SBRCorrupt(""); + return; + } + + for (i = indent; i; i--) + fprintf (streamOut, " "); + + fprintf (streamOut, "%s: (", prectab[r_rectyp]); + + switch(r_rectyp) { + + case SBR_REC_HEADER: + fprintf (streamOut, "%1d:%1d (%s) %1d)", + r_majv, r_minv, plangtab[r_lang], r_fcol); + fprintf (streamOut, " in %s", r_cwd); + break; + + case SBR_REC_MODULE: + fprintf (streamOut, "%s", r_bname); + indent++; + break; + + case SBR_REC_LINDEF: + fprintf (streamOut, "%d", r_lineno); + break; + + case SBR_REC_SYMDEF: + { + WORD attr, type; + + type = (r_attrib & SBR_TYPMASK) >> SBR_TYPSHIFT; + attr = (r_attrib & SBR_ATRMASK) >> SBR_ATRSHIFT; + + fprintf (streamOut, "%s", ptyptab[type]); + + for (i = 0 ; i < SBR_ATRBITS; i++) + if (attr & (1 << i)) + fprintf (streamOut, "|%s", patrtab[i]); + + fprintf (streamOut, " o:%d %s", r_ordinal, r_bname); + } + break; + + case SBR_REC_SYMREFUSE: + case SBR_REC_SYMREFSET: + case SBR_REC_OWNER: + fprintf (streamOut, "o:%d", r_ordinal); + break; + + case SBR_REC_MACROBEG: + case SBR_REC_BLKBEG: + indent++; + break; + } + fprintf (streamOut, ")\n"); +} diff --git a/private/utils/mep/browser/mbrmake/errors.h b/private/utils/mep/browser/mbrmake/errors.h new file mode 100644 index 000000000..e684211d4 --- /dev/null +++ b/private/utils/mep/browser/mbrmake/errors.h @@ -0,0 +1,20 @@ + +#define WARN_UNKNOWN_WARNING 0 +#define WARN_OPTION_IGNORED 1 +#define WARN_SBR_TRUNC 2 + +#define ERR_UNKNOWN_ERROR 0 +#define ERR_UNKNOWN_OPTION 1 +#define ERR_MISSING_OPTION 2 +#define ERR_WRITE_FAILED 3 +#define ERR_SEEK_FAILED 4 +#define ERR_READ_FAILED 5 +#define ERR_OPEN_FAILED 6 +#define ERR_TEMP_FAILED 7 +#define ERR_DELETE_FAILED 8 +#define ERR_OUT_OF_MEMORY 9 +#define ERR_SBR_CORRUPT 10 +#define ERR_BAD_RESPONSE 11 +#define ERR_CAPACITY_EXCEEDED 12 +#define ERR_NO_INCREMENTAL 13 +#define ERR_ALL_SBR_TRUNC 14 diff --git a/private/utils/mep/browser/mbrmake/extern.h b/private/utils/mep/browser/mbrmake/extern.h new file mode 100644 index 000000000..44fe56cbe --- /dev/null +++ b/private/utils/mep/browser/mbrmake/extern.h @@ -0,0 +1,83 @@ + +// pointers to resident pages of virtual memory of the given object type + +extern MOD FAR * near modRes; +extern MODSYM FAR * near modsymRes; +extern SYM FAR * near symRes; +extern PROP FAR * near propRes; +extern DEF FAR * near defRes; +extern REF FAR * near refRes; +extern CAL FAR * near calRes; +extern CBY FAR * near cbyRes; +extern ORD FAR * near ordRes; +extern SBR FAR * near sbrRes; +extern char FAR * near textRes; +extern OCR FAR * near ocrRes; + +// global variables for communication with getsbrec.c + +extern BYTE near r_rectyp; // current record type +extern BYTE near r_fcol; // read column #'s +extern BYTE near r_majv; // major version # +extern BYTE near r_minv; // minor version # +extern BYTE near r_lang; // current language +extern WORD near r_lineno; // current line number +extern WORD near r_ordinal; // symbol ordinal +extern WORD near r_attrib; // symbol attribute +extern char near r_bname[]; // symbol or filename +extern char near r_cwd[]; // current working directory +extern BYTE near r_rectyp; // current record type +extern BYTE near r_fcol; // read column #'s +extern WORD near r_lineno; // current line number +extern WORD near r_ordinal; // symbol ordinal +extern WORD near r_attrib; // symbol attribute +extern char near r_bname[]; // symbol or filename +extern char near r_cwd[]; // this .sbr files current dir +extern char near c_cwd[]; // pwbrmake's actual current dir + +// option variables + +extern BOOL near OptEm; // TRUE = exclude macro bodies +extern BOOL near OptEs; // TRUE = exclude system files +extern BOOL near OptIu; // TRUE = exclude unused syms +extern BOOL near OptV; // Verbose switch +#if DEBUG +extern WORD near OptD; // debug bits +#endif + +// others that I haven't classified yet + +extern BYTE near MaxSymLen; // longest symbol len +extern VA near vaSymHash[]; // symbol list +extern LPEXCL near pExcludeFileList; // exclude file list +extern LSZ near lszFName; // name of current .sbr file +extern FILE * near streamOut; // .bsc output stream +extern int near fhCur; // file handle for the current .sbr file +extern LSZ near prectab[]; // record types table +extern LSZ near plangtab[]; // language types table +extern LSZ near ptyptab[]; // prop types table +extern LSZ near patrtab[]; // prop attributes table +extern WORD near isbrCur; // current SBR file index +extern FILE * near OutFile; // .BSC file handle +extern WORD near ModCnt; // count of modules +extern WORD near SbrCnt; // count of sbr files +extern BYTE near fCase; // TRUE for case compare +extern BYTE near MaxSymLen; // longest symbol len +extern BOOL near fOutputBroken; // TRUE while database is incomplete +extern VA near vaUnknownSym; // ptr to 'UNKNOWN' Symbol +extern VA near vaUnknownMod; // unknown module +extern BOOL near fDupSym; // TRUE if adding duplicate atom +extern VA near vaRootMod; // Module list +extern VA near rgVaSym[]; // Symbol list +extern FILE * near streamCur; // Current .sbr handle +extern LSZ near OutputFileName; // Output file name +extern VA FAR * near rgvaSymSorted; +extern VA near vaRootMod; +extern VA near vaCurMod; +extern VA near vaCurSym; +extern VA near vaRootOrd; +extern VA near vaRootSbr; +extern WORD near cAtomsMac; +extern WORD near cModulesMac; +extern WORD near cSymbolsMac; +extern LSZ near lszFName; // current .sbr file name diff --git a/private/utils/mep/browser/mbrmake/getsbrec.c b/private/utils/mep/browser/mbrmake/getsbrec.c new file mode 100644 index 000000000..6fed1778e --- /dev/null +++ b/private/utils/mep/browser/mbrmake/getsbrec.c @@ -0,0 +1,165 @@ +// +// +// GETSBREC.C - Reads records from the .SBR file and stores the fields +// in the appropriate r_.. buffers. +// + +#include "sbrfdef.h" +#include "..\mbrmake\mbrmake.h" + +// globals for communicating with clients + +BYTE near r_rectyp; // current record type +BYTE near r_majv; // major version num +BYTE near r_minv; // minor version num +BYTE near r_lang; // source language +BYTE near r_fcol; // read column #'s +WORD near r_lineno; // current line number +BYTE near r_column = 0; // def/ref column num +WORD near r_ordinal; // symbol ordinal +WORD near r_attrib; // symbol attribute +char near r_bname[PATH_BUF]; // symbol or filename +char near r_cwd[PATH_BUF]; // .sbr file working directory + +int near fhCur; // Current input handle + +#pragma intrinsic(memcpy) +#pragma intrinsic(strcpy) +#pragma intrinsic(strlen) + +#define MY_BUF_SIZE 16384 + +static char sbrBuf[MY_BUF_SIZE + 1]; +static char *pchBuf; +static int cchBuf; + +#define GetByte(X) \ +{ \ + if (!cchBuf) { \ + cchBuf = read(fhCur, sbrBuf, MY_BUF_SIZE); \ + sbrBuf[cchBuf] = 0; \ + pchBuf = sbrBuf; \ + \ + if (cchBuf == 0) \ + SBRCorrupt("premature EOF"); \ + } \ + \ + cchBuf--; \ + (X) = (unsigned char)*pchBuf++; \ +} + +#define GetWord(X) \ +{ \ + \ + GetByte(((char *)&(X))[0]); \ + GetByte(((char *)&(X))[1]); \ +} + +void +GetStr(char *buf) +// get null terminated string from current .sbr file +// +{ + register int l; + + for (;;) { + // there is always a NULL after the real buffer + l = strlen(pchBuf); + + if (l++ < cchBuf) { + strcpy(buf, pchBuf); + cchBuf -= l; + pchBuf += l; + return; + } + + memcpy(buf, pchBuf, cchBuf); + buf += cchBuf; + + cchBuf = read(fhCur, sbrBuf, MY_BUF_SIZE); + sbrBuf[cchBuf] = 0; + pchBuf = sbrBuf; + + if (cchBuf == 0) + SBRCorrupt("premature EOF"); + } +} + +BYTE +GetSBRRec() +// read the next record from the current .sbr file +// +{ + static fFoundHeader; + BYTE col; + + // read rectype, check for EOF as we go + + + if (!cchBuf) { + cchBuf = read(fhCur, sbrBuf, MY_BUF_SIZE); + sbrBuf[cchBuf] = 0; + pchBuf = sbrBuf; + + if (cchBuf == 0) { + fFoundHeader = 0; // this is in case we are reinitialized + return S_EOF; + } + } + + cchBuf--; + r_rectyp = (unsigned char)*pchBuf++; + + switch(r_rectyp) { + case SBR_REC_HEADER: + if (fFoundHeader) + SBRCorrupt("Multiple Headers"); + + fFoundHeader = 1; + GetByte(r_majv); + GetByte(r_minv); + GetByte(r_lang); + GetByte(r_fcol); + + if (r_majv != 1 || r_minv != 1) + break; + + GetStr (r_cwd); + break; + + case SBR_REC_MODULE: + GetStr (r_bname); + break; + + case SBR_REC_LINDEF: + GetWord (r_lineno); + if (r_lineno) + r_lineno--; + break; + + case SBR_REC_SYMDEF: + GetWord (r_attrib); + GetWord (r_ordinal); + if (r_fcol) GetByte (col); + GetStr (r_bname); + break; + + case SBR_REC_OWNER: + GetWord (r_ordinal); + break; + + case SBR_REC_SYMREFUSE: + case SBR_REC_SYMREFSET: + GetWord (r_ordinal); + if (r_fcol) GetByte (col); + break; + + case SBR_REC_MACROBEG: + case SBR_REC_MACROEND: + case SBR_REC_BLKBEG: + case SBR_REC_BLKEND: + case SBR_REC_MODEND: + break; + } + return (r_rectyp); +} diff --git a/private/utils/mep/browser/mbrmake/list.c b/private/utils/mep/browser/mbrmake/list.c new file mode 100644 index 000000000..a2b634904 --- /dev/null +++ b/private/utils/mep/browser/mbrmake/list.c @@ -0,0 +1,284 @@ +// list.c +// +// a VM growable array package + +#include "mbrmake.h" + +typedef struct _list { + WORD cItems; +} SLIST; + +typedef struct _biglist { + WORD cItems; + VA vaNext; +} BLIST; + +typedef union _mixlist { + SLIST sml; + BLIST big; +} GLIST; + +// this are the two VM lock numbers for the list package +// +#define LIST_LOCK 10 +#define LIST_LOCK2 11 + +// Beware! For the system to work properly this number must +// be small enough that the VM free lists won't overflow +// i.e. C_ITEMS_MAX * sizeof(biggest_thing_stored) <= C_FREE_LIST_MAX +// +#define C_ITEMS_MAX 16 + +#pragma intrinsic(memcpy) + +#define cBlock 1 + +VA +VaAddList(VA far *pvaList, LPV lpvData, WORD cbData, WORD grp) +// add the given item to the list; create if necessary +// return the virtual address of the most recently added item +// +{ + VA vaListNew; + VA vaDirtyOnExit = vaNil; + + WORD cbBlock, cItems, cAlloc; + + GLIST far *lpList, *lpListNew; + +#ifdef SWAP_INFO + iVMGrp = grp; +#endif + +#if cBlock != 1 + if (cBlock == 0) cBlock = C_ITEMS_MAX; +#endif + +top: // for tail recursion... + + // current list is empty -- create a new list with one thing in it + + if (*pvaList == vaNil) { + if (cBlock == C_ITEMS_MAX) { + *pvaList = VaAllocGrpCb(grp, cbData*cBlock + sizeof(BLIST)); + lpList = LpvFromVa(*pvaList, LIST_LOCK); + lpList->big.vaNext = vaNil; + lpList->big.cItems = 1; + memcpy(((LPCH)lpList) + sizeof(BLIST), lpvData, cbData); + if (vaDirtyOnExit) { + DirtyVa(vaDirtyOnExit); + UnlockW(LIST_LOCK+1); + } + DirtyVa(*pvaList); + UnlockW(LIST_LOCK); + return (PBYTE)*pvaList + sizeof(BLIST); + } + else { + *pvaList = VaAllocGrpCb(grp, cbData*cBlock + sizeof(SLIST)); + lpList = LpvFromVa(*pvaList, LIST_LOCK); + lpList->sml.cItems = 1; + memcpy(((LPCH)lpList) + sizeof(SLIST), lpvData, cbData); + if (vaDirtyOnExit) { + DirtyVa(vaDirtyOnExit); + UnlockW(LIST_LOCK+1); + } + DirtyVa(*pvaList); + UnlockW(LIST_LOCK); + return (PBYTE)*pvaList + sizeof(SLIST); + } + } + + lpList = LpvFromVa(*pvaList, LIST_LOCK); + cItems = lpList->sml.cItems; + + // if current list has extension blocks, recursively add to the + // tail of this list + + if (cItems >= C_ITEMS_MAX) { + vaDirtyOnExit = *pvaList; + lpList->big.cItems++; + DirtyVa(*pvaList); + LpvFromVa(*pvaList, LIST_LOCK+1); // lock in mem so address stays good + pvaList = &lpList->big.vaNext; + UnlockW(LIST_LOCK); + goto top; + } + + cbBlock = cItems * cbData; + cAlloc = cItems % cBlock; + cAlloc = cItems - cAlloc + ( cAlloc ? cBlock : 0 ); + + // do we need to reallocate? If not do a fast insert + // + if (cItems < cAlloc) { + if (cAlloc >= C_ITEMS_MAX) { + memcpy(((LPCH)lpList) + cbBlock + sizeof(BLIST), lpvData, cbData); + lpList->big.cItems++; + DirtyVa(*pvaList); + UnlockW(LIST_LOCK); + return (PBYTE)*pvaList + cbBlock + sizeof(BLIST); + } + else { + memcpy(((LPCH)lpList) + cbBlock + sizeof(SLIST), lpvData, cbData); + lpList->sml.cItems++; + DirtyVa(*pvaList); + UnlockW(LIST_LOCK); + return (PBYTE)*pvaList + cbBlock + sizeof(SLIST); + } + } + + // test if the next block will fit without turning the current list into + // a chained list... allocate a new block & copy the old data + + if (cItems + cBlock < C_ITEMS_MAX) { + vaListNew = VaAllocGrpCb(grp, cbBlock + cbData*cBlock + sizeof(SLIST)); + lpListNew = LpvFromVa(vaListNew, 0); + memcpy((LPCH)lpListNew, lpList, cbBlock + sizeof(SLIST)); + memcpy((LPCH)lpListNew + cbBlock + sizeof(SLIST), lpvData, cbData); + lpListNew->sml.cItems++; + DirtyVa(vaListNew); + FreeGrpVa(grp, *pvaList, cbBlock + sizeof(SLIST)); + *pvaList = vaListNew; + if (vaDirtyOnExit) { + DirtyVa(vaDirtyOnExit); + UnlockW(LIST_LOCK+1); + } + UnlockW(LIST_LOCK); + return (PBYTE)vaListNew + cbBlock + sizeof(SLIST); + } + + // this is the last item that will go into this block, + // allocate a new block c/w link field & copy the old data + // set the link field to 0 for now + +#if cBlock != 1 + cBlock = C_ITEMS_MAX - cItems; +#endif + + vaListNew = VaAllocGrpCb(grp, cbBlock + cbData*cBlock + sizeof(BLIST)); + lpListNew = LpvFromVa(vaListNew, 0); + memcpy(lpListNew + 1 , ((SLIST FAR *)lpList) + 1, cbBlock); + memcpy(((LPCH)lpListNew) + cbBlock + sizeof(BLIST), lpvData, cbData); + lpListNew->big.cItems = lpList->sml.cItems + 1; + lpListNew->big.vaNext = vaNil; + DirtyVa(vaListNew); + FreeGrpVa(grp, *pvaList, cbBlock + sizeof(SLIST)); + *pvaList = vaListNew; + if (vaDirtyOnExit) { + DirtyVa(vaDirtyOnExit); + UnlockW(LIST_LOCK+1); + } + UnlockW(LIST_LOCK); + return (PBYTE)vaListNew + cbBlock + sizeof(BLIST); +} + +WORD +CItemsList(VA vaList) +// return total number of items in array +// +{ + if (vaList == vaNil) + return 0; + +#ifdef SWAP_INFO + iVMGrp = grpList; +#endif + + return ((SLIST FAR *)LpvFromVa(vaList, 0))->cItems; +} + +// to use the following iterator say something like +// +// vaPropList = cSYM.vaPropList; +// while (cprop = CItemsIterate(&vaProps, &vaPropList, cBlock)) { +// gPROP(vaProps); +// for (;--cprop >= 0; cPROP++) { +// cPROP.etc = ; +// +// } +// } +// +// +// The ENM_LIST, ENM_END, ENM_BREAK macros "do the right thing" with +// these lists. +// + +WORD +CItemsIterate(VA FAR *vaData, VA FAR *vaNext) +// give number of elements in current block and pointer to next block +// +{ + GLIST FAR *lpgList; + WORD cItems, cAlloc; + + if (*vaNext == vaNil) + return 0; + +#ifdef SWAP_INFO + iVMGrp = grpList; +#endif + +#if cBlock != 1 + if (cBlock == 0) cBlock = C_ITEMS_MAX; +#endif + + lpgList = LpvFromVa(*vaNext, 0); + + cItems = lpgList->sml.cItems; + + if (cItems >= C_ITEMS_MAX) { + *vaData = (PBYTE)*vaNext + sizeof(BLIST); + *vaNext = lpgList->big.vaNext; + return C_ITEMS_MAX; + } + + if (cBlock == 0) + cAlloc = C_ITEMS_MAX; + else { + cAlloc = cItems % cBlock; + cAlloc = cItems - cAlloc + ( cAlloc ? cBlock : 0 ); + } + + if (cAlloc >= C_ITEMS_MAX) + *vaData = (PBYTE)*vaNext + sizeof(BLIST); + else + *vaData = (PBYTE)*vaNext + sizeof(SLIST); + + *vaNext = 0; + return cItems; +} + +VOID +FreeList(VA vaList, WORD cbData) +// free up all the memory associated with this list +// +{ + (PBYTE)vaList + cbData; + printf("FreeList is currently not working\n"); + +#if 0 + + GLIST FAR * lpgList; + VA vaNextList; + + + if (vaList == vaNil) + return; + +top: // tail recursion + + lpgList = LpvFromVa(vaList, 0); + + if (lpgList->sml.cItems >= C_ITEMS_MAX) { + + vaNextList = lpgList->big.vaNext; + FreeVa(vaList, C_ITEMS_MAX * cbData + sizeof(BLIST)); + + vaList = vaNextList; + goto top; // tail recursion + } + + FreeVa(vaList, lpgList->sml.cItems * cbData + sizeof(SLIST)); + return; +#endif +} diff --git a/private/utils/mep/browser/mbrmake/list.h b/private/utils/mep/browser/mbrmake/list.h new file mode 100644 index 000000000..ceee6a9c0 --- /dev/null +++ b/private/utils/mep/browser/mbrmake/list.h @@ -0,0 +1,41 @@ +// list.h +// +// a VM growable array package + +VA VaAddList(VA far *vaList, LPV lpvData, WORD cbData, WORD grp); +WORD CItemsList(VA vaList); +WORD CItemsIterate(VA FAR *vaData, VA FAR *vaNext); + + +#define ENM_LIST(start, type) \ +{ \ + VA va##type##list = (start); \ + VA va##type##s; \ + int cnt##type, idx##type; \ + while (cnt##type = CItemsIterate(&va##type##s, &va##type##list)) {\ + g##type(va##type##s); \ + for (idx##type = 0; idx##type < cnt##type; idx##type++, (&c##type)++) { + +#define ENM_END } } } + +#define ENM_PUT(type) DirtyVa(va##type##s) + +#define ENM_VA(type) (va##type##s + sizeof(c##type)*idx##type) + +#define ENM_BREAK(type) va##type##list = 0; break; + + +// +// example use of ENM_LIST +// +// + +// ENM_LIST (vaPropList, PROP) { +// +// ... some things using CPROP (like below) .. +// +// printf("%s\n", GetAtomStr(cPROP.vaNameSym)); +// +// ... other things using cPROP... +// +// } ENM_END diff --git a/private/utils/mep/browser/mbrmake/makefile b/private/utils/mep/browser/mbrmake/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/utils/mep/browser/mbrmake/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/utils/mep/browser/mbrmake/mbrhash.c b/private/utils/mep/browser/mbrmake/mbrhash.c new file mode 100644 index 000000000..269322941 --- /dev/null +++ b/private/utils/mep/browser/mbrmake/mbrhash.c @@ -0,0 +1,41 @@ +#include "mbrmake.h" +WORD HashAtomStr (char *pStr) { + + WORD hash = 0; + while (*pStr) + hash += (hash << 5) + *pStr++; + + return (hash % (MAXSYMPTRTBLSIZ-1)); +} + +#if rjsa +HashAtomStr PROC NEAR USES DS SI, npsz:DWORD + xor ax,ax ; (ax) = byte-extended-to-word + mov cx,ax ; (cx) = hash + mov dx,ax ; (dx) = high part for later div + cld + lds si,npsz ; (si) = pointer to string + align 4 +hfs1: lodsb ; get next byte + or al,al ; are we at end of string? + jz hfs2 ; yes, compute div and we're done + mov bx,cx + shl bx,1 + shl bx,1 + shl bx,1 + shl bx,1 + shl bx,1 + add cx,bx ; (newcx) = (oldcx) + (oldcx) << 5 + add cx,ax ; (cx) += (cx) << 5 + (ax) + jmp hfs1 + +hfs2: mov ax,4094 ; magic divider + xchg ax,cx ; (dx:ax) = number, (cx) = dividend + div cx + mov ax,dx + ret +HashAtomStr ENDP + +end + +#endif diff --git a/private/utils/mep/browser/mbrmake/mbrmake.c b/private/utils/mep/browser/mbrmake/mbrmake.c new file mode 100644 index 000000000..170ecb695 --- /dev/null +++ b/private/utils/mep/browser/mbrmake/mbrmake.c @@ -0,0 +1,756 @@ +// +// mbrmake - Source Browser Source Data Base builder +// (C) 1988 By Microsoft +// +// 29-Aug-1989 dw Minor fixes to aid in C 6 conversion +// +// + +#define LINT_ARGS + +// rjsa #include +#include +#include +#include + +// get version.h from mb + +#include "..\..\inc\version.h" + +#include "sbrvers.h" +#include "sbrfdef.h" +#include "mbrmake.h" + +#include +#include +#include + +// this fixes the bogosity in config.h that gets included by tools.h +// it will set DEBUG = 0 for a non-debug version... +// +// -rm + +#ifdef DEBUG +#if DEBUG == 0 +#undef DEBUG +#endif +#endif + +static VOID TruncateSBR(char *lszName); +static VOID ProcessSBR(char *lszName); +static VOID MarkNewSBR(char *lszName); + +#ifdef DEBUG +WORD near OptD = 0; +#endif + +FILE * near streamOut = stdout; + +BOOL near OptEs = FALSE; // exclude system files +BOOL near OptEm = FALSE; // exclude macro expansions +BOOL near OptIu = FALSE; // include unreference symbols +BOOL near OptV = FALSE; // verbose output +BOOL near OptN = FALSE; // no incremental behaviour + +char near c_cwd[PATH_BUF]; // current working directory +char near patbuf[PATH_BUF]; + +MOD FAR * near modRes; // VM cache +MODSYM FAR * near modsymRes; +SYM FAR * near symRes; +PROP FAR * near propRes; +DEF FAR * near defRes; +REF FAR * near refRes; +CAL FAR * near calRes; +CBY FAR * near cbyRes; +ORD FAR * near ordRes; +SBR FAR * near sbrRes; +char FAR * near textRes; +OCR FAR * near ocrRes; + +BYTE near fCase = FALSE; // TRUE for case compare +BYTE near MaxSymLen = 0; // longest symbol len + +LSZ near lszFName; // Current input file + +LSZ near OutputFileName = NULL; // output file name +FILE * near OutFile; // output file handle +BOOL near fOutputBroken = FALSE; // we have dirtied the database + +VA near vaRootMod = vaNil; // module list +VA near vaCurMod = vaNil; // current module + +VA near rgVaSym[MAXSYMPTRTBLSIZ]; // symbol list array + +EXCLINK FAR * near pExcludeFileList = NULL; // exclude file list + +struct mlist { + int erno; + char *text; +}; + +struct mlist WarnMsg[] = { + 4500, "UNKNOWN WARNING\n\tContact Microsoft Product Support Services", + 4501, "ignoring unknown option '%s'", + 4502, "truncated .SBR file '%s' not in database", +}; + +struct mlist ErrorMsg[] = { + 1500, "UNKNOWN ERROR\n\tContact Microsoft Product Support Services", + 1501, "unknown character '%c' in option '%s'", + 1502, "incomplete specification for option '%s'", + 1503, "cannot write to file '%s'", + 1504, "cannot position in file '%s'", + 1505, "cannot read from file '%s'", + 1506, "cannot open file '%s'", + 1507, "cannot open temporary file '%s'", + 1508, "cannot delete temporary file '%s'", + 1509, "out of heap space", + 1510, "corrupt .SBR file '%s'", + 1511, "invalid response file specification", + 1512, "database capacity exceeded", + 1513, "nonincremental update requires all .SBR files", + 1514, "all .SBR files truncated and not in database", +}; + +VOID +Error (int imsg, char *parg) +// print error number and message +// +{ + printf ("mbrmake: error U%d : ",ErrorMsg[imsg].erno); + printf (ErrorMsg[imsg].text, parg); + printf ("\n"); + Fatal(); +} + +VOID +Error2 (int imsg, char achar, char *parg) +// print error number and message with argument +// +{ + printf ("mbrmake: error U%d : ",ErrorMsg[imsg].erno); + printf (ErrorMsg[imsg].text, achar, parg); + printf ("\n"); + Fatal(); +} + +VOID +Warning (int imsg, char *parg) +// print warning number and message +// +{ + printf ("mbrmake: warning U%d : ",WarnMsg[imsg].erno); + printf (WarnMsg[imsg].text, parg); + printf ("\n"); +} + +VOID +Fatal () +// fatal error, attempt to shut down and exit +// if we already tried to shut down -- just abort without doing anything +{ + static BOOL fTwice; + if (!fTwice) { + fTwice = TRUE; + if (fOutputBroken) { + if (OutFile) fclose(OutFile); + if (OutputFileName != NULL) unlink(OutputFileName); + } + CloseVM(); + } + exit(4); +} + +VOID +sigint () +{ + // signal(SIGBREAK, sigint); + // signal(SIGINT, sigint); + Fatal (); +} + +LSZ +LszDup(LSZ lsz) +// like strdup only using LpvAllocCb to get the memory +// +{ + LSZ lszDup; + + lszDup = LpvAllocCb(strlen(lsz)+1); + strcpy(lszDup, lsz); + return lszDup; +} + +LSZ +LszDupNewExt(LSZ pname, LSZ pext) +// duplicate the given filename changing the extension to be the given +// +{ + int i, len, elen; + LSZ lsz; + + len = strlen(pname); + elen = strlen(pext); + + // I know this looks like I should be doing a runtime call but nothing + // does quite what I want here and I know that C6 will make great + // code for this loop [rm] + + // find the first '.' starting from the back + + for (i=len; --i >= 0; ) + if (pname[i] == '.') + break; + + + // check to make sure we've got a real base name and not just all extension + // + + if (i > 0) { + // replace the extension with what's in pext + + lsz = LpvAllocCb(i + 1 + elen + 1); // base + dot + ext + nul + memcpy(lsz, pname, i+1); + strcpy(lsz+i+1, pext); + } + else { + // just stick the extension on the end... + + lsz = LpvAllocCb(len + 1 + elen + 1); // fullname + dot + ext + nul + strcpy(lsz, pname); + strcat(lsz, "."); + strcat(lsz, pext); + } + + return lsz; +} + +VOID +AddExcludeFileList(LSZ pname) +// add the specifed filename to the exclusion list +// +{ + EXCLINK FAR *pexc; + + pexc = (EXCLINK FAR *)LpvAllocCb(sizeof(EXCLINK)); + pexc->pxfname = LszDup(ToAbsPath(pname, c_cwd)); + + if (pExcludeFileList == NULL) + pexc->xnext = NULL; + else + pexc->xnext = pExcludeFileList; + + pExcludeFileList = pexc; +} + +BOOL +FValidHeader() +// Read in the header of a .sbr file -- return TRUE if it is valid +// +{ + // test if this is a truncated (i.e. already installed) .sbr file + // + if (GetSBRRec() == S_EOF) + return FALSE; + + if (r_rectyp != SBR_REC_HEADER) + SBRCorrupt("header not correct record type"); + + if (r_lang == SBR_L_C) + fCase = TRUE; + + if (r_majv != 1 || r_minv != 1) + SBRCorrupt("incompatible .sbr format\n"); + + #ifdef DEBUG + if (OptD & 1) DecodeSBR(); + #endif + + return TRUE; +} + +#ifdef PROFILE + +// profile prototypes and typedefs + +#include "casts.h" +#include "profile.h" + +#endif + +VOID _CRTAPI1 +main (argc, argv) +int argc; +char *argv[]; +{ + int i; + char *parg; + long lArgPosn; + +#ifdef PROFILE + PROFINIT(PT_USER|PT_USEKP, (FPC)NULL); + PROFCLEAR(PT_USER); + PROFON(PT_USER); +#endif + + // signal(SIGBREAK, sigint); + // signal(SIGINT, sigint); + + printf("Microsoft (R) mbrmake Utility "); + printf(VERS(rmj, rmm, rup)); + printf(CPYRIGHT); + + if (argc == 1) Usage(); + + getcwd(c_cwd, sizeof(c_cwd)); + ToBackSlashes(c_cwd); + + parg = ParseArgs(argc, argv); + + if (!parg) + Usage(); + + InitVM(); + + for (i=0; i < MAXSYMPTRTBLSIZ; i++) // init symbol lists + rgVaSym[i] = vaNil; + + lArgPosn = GetArgPosn(); + + do { + ToBackSlashes(parg); + + if (forfile(parg, A_ALL, MarkNewSBR, NULL) == 0) + Error(ERR_OPEN_FAILED, parg); + } + while (parg = NextArg()); + + if (!OptN && FOpenBSC(OutputFileName)) { + InstallBSC(); + CloseBSC(); + } + else + NumberSBR(); + + SetArgPosn(lArgPosn); + parg = NextArg(); + + do { + if (forfile(parg, A_ALL, ProcessSBR, NULL) == 0) + Error(ERR_OPEN_FAILED, parg); + } + while (parg = NextArg()); + + // this sort must happen before all the other calls below as they + // use the sorted version of the list and not the raw symbols + + SortAtoms(); // create a sorted version of the atoms + +#ifdef DEBUG + if (OptD & 128) DebugDump(); +#endif + + CleanUp (); // General cleaning + +#ifdef DEBUG + if (OptD & 16) DebugDump(); +#endif + + WriteBSC (OutputFileName); // write .bsc Source Data Base + +#ifdef PROFILE + PROFOFF(PT_USER); + PROFDUMP(PT_USER, (FPC)"mbrmake.pro"); + PROFFREE(PT_USER); +#endif + + if (!OptN) { + // truncate the .sbr files now + SetArgPosn(lArgPosn); + parg = NextArg(); + + do { + if (forfile(parg, A_ALL, TruncateSBR, NULL) == 0) + Error(ERR_OPEN_FAILED, parg); + } + while (parg = NextArg()); + + // touch the .bsc file so it has a date later than all the .sbrs + + { + FILE *fh; + int buf = 0; + + if (!(fh = fopen(OutputFileName, "ab"))) { + Error(ERR_OPEN_FAILED, OutputFileName); + } + if (fwrite(&buf, 1, 1, fh)==0) { + Error(ERR_WRITE_FAILED, OutputFileName); + } + + fclose(fh); + } + } + + CloseVM(); + exit (0); +} + +static VOID +ProcessSBR(char *lszName) +// process one .sbr file with the given name +// +{ + + lszFName = LszDup(lszName); + if ((fhCur = open(lszFName, O_BINARY|O_RDONLY)) == -1) { + Error(ERR_OPEN_FAILED, lszFName); + } + + isbrCur = gSBR(VaSbrFrName(lszFName)).isbr; + + if (OptV) + printf("Processing: %s ..\n", lszFName); + + if (!FValidHeader()) { + FreeLpv (lszFName); + close(fhCur); + return; + } + + // Add .SBR data to lists + InstallSBR (); + + FreeOrdList (); // free ordinal aliases + close(fhCur); + + FreeLpv (lszFName); +} + +static VOID +TruncateSBR(char *lszName) +// once the .sbr file is used -- truncate it +// +{ + int fh; + + if (unlink(lszName) == -1) { + Error(ERR_OPEN_FAILED, lszFName); + } + + if ((fh = open(lszName, O_CREAT|O_BINARY, S_IREAD|S_IWRITE)) == -1) { + Error(ERR_OPEN_FAILED, lszFName); + } + + close(fh); +} + +VOID +Usage() +{ +#ifdef DEBUG + printf("usage: mbrmake [-Emu] [-Ei ...] [-vd] [-help] [-o <.BSC>] [@] <.sbr>...\n\n"); +#else + printf("usage: mbrmake [-Emu] [-Ei ...] [-v] [-help] [-o <.BSC>] [@] <.sbr>...\n\n"); +#endif + printf(" @ Get arguments from specified file\n"); + printf(" /E... Exclude:\n"); + printf(" s system files\n"); + printf(" i named include file \n"); + printf(" i ( ) named include file list \n"); + printf(" m macro expanded symbols\n"); + printf(" /I... Include:\n"); + printf(" u unreferenced symbols\n"); + printf(" /o output source database name\n"); + printf(" /n no incremental (full builds, .sbr's preserved)\n"); + printf(" /v verbose output\n"); + printf(" /help Quick Help\n"); +#ifdef DEBUG + printf(" /d show debugging information\n"); + printf(" 1 sbrdump .sbr files as they come in\n"); + printf(" 2 show every duplicate MbrAddAtom\n"); + printf(" 4 emit warning on forward referenced ordinal\n"); + printf(" 8 show prop data as new items are added\n"); + printf(" 16 bscdump database after cleanup\n"); + printf(" 32 emit information about what cleanup is doing\n"); + printf(" 64 emit list of sorted modules after sorting\n"); + printf(" 128 bscdump database before cleanup\n"); + printf(" 256 give info about duplicate/excluded modules\n"); +#endif + exit(1); +} + +FILE *fileResp; +int cargs; +char ** vargs; +int iarg = 1; +long lFilePosnLast; + +LONG +GetArgPosn() +// save the current position on the command line +// +{ + if (fileResp) + return lFilePosnLast; + else + return (LONG)iarg - 1; +} + +VOID +SetArgPosn(LONG lArgPosn) +// restore the command line parsing position +// +{ + if (fileResp) { + fseek(fileResp, lArgPosn, SEEK_SET); + iarg = 0; + } + else + iarg = (int)lArgPosn; +} + +char * +NextArg() +// get the next argument from the response file or the command line +// +{ + static char buf[PATH_BUF]; + char *pch; + int c; + BOOL fQuote = FALSE; + + if (iarg >= cargs) + return NULL; + + if (fileResp) { + pch = buf; + + lFilePosnLast = ftell(fileResp); + + for (;;) { + c = getc(fileResp); + switch (c) { + + case '"': + if (fQuote) { + *pch = '\0'; + return buf; + } + else { + fQuote = TRUE; + continue; + } + + case EOF: + iarg = cargs; + if (pch == buf) + return NULL; + + *pch = '\0'; + return buf; + + case ' ': + case '\t': + case '\r': + case '\f': + case '\n': + if (fQuote) + goto quoted; + + if (pch == buf) + continue; + + *pch = '\0'; + return buf; + + default: + quoted: + if (pch < buf + sizeof(buf) - 1) + *pch++ = (char)c; + break; + } + } + } + else + return vargs[iarg++]; +} + +char * +ParseArgs(int argc, char **argv) +// parse the command line or response file +// +{ + char *respName; + char *pchWord; + int len; + + cargs = argc; + vargs = argv; + + for (;;) { + pchWord = NextArg(); + + if (pchWord == NULL) + return pchWord; + + if (pchWord[0] == '@') { + + if (fileResp) + Error(ERR_BAD_RESPONSE, ""); + else if (pchWord[1]) + respName = pchWord+1; + else if (!(respName = NextArg())) + Error(ERR_BAD_RESPONSE, ""); + + fileResp = fopen(respName, "r"); + + if (!fileResp) + Error(ERR_OPEN_FAILED, respName); + + cargs++; + + continue; + } + + if (pchWord[0] != '-' && pchWord[0] != '/') + return pchWord; + + switch (pchWord[1]) { + + case 'n': + OptN = TRUE; + break; + + case 'o': + if (pchWord[2]) + pchWord += 2; + else if (!(pchWord = NextArg())) + Usage(); + + OutputFileName = LszDupNewExt (pchWord, "bsc"); + break; + + #ifdef DEBUG + case 'd': + OptD = 1; + if (pchWord[2]) OptD = atoi(pchWord+2); + break; + #endif + + case 'E': + switch (pchWord[2]) { + + case 0: + Error (ERR_MISSING_OPTION, pchWord); + break; + + case 'm': + OptEm = TRUE; + break; + + case 's': + OptEs = TRUE; + break; + + default: + Error2 (ERR_UNKNOWN_OPTION, pchWord[2], pchWord); + break; + + case 'i': + if (pchWord[3]) + pchWord += 3; + else + pchWord = NextArg(); + + if (!pchWord) + Error (ERR_MISSING_OPTION, "-Ei"); + + if (pchWord[0] != '(') { + AddExcludeFileList(pchWord); + break; + } + + if (pchWord[1]) + pchWord++; + else + pchWord = NextArg(); + + for ( ;pchWord != NULL; pchWord = NextArg()) { + len = strlen(pchWord); + if (pchWord[len-1] != ')') { + AddExcludeFileList(pchWord); + } + else if (len > 1) { + pchWord[len-1] = 0; + AddExcludeFileList(pchWord); + break; + } + else + break; + } + if (pchWord == NULL) + Error (ERR_MISSING_OPTION, "-Ei (..."); + } + break; + + case 'I': + switch (pchWord[2]) { + case 'u': + OptIu = TRUE; + break; + + default: + Error2 (ERR_UNKNOWN_OPTION, pchWord[2], pchWord); + break; + } + break; + + case 'H': + case 'h': + if ((strcmpi (pchWord+1, "help")) == 0) { + if (spawnlp (P_WAIT, "qh", "-u", "mbrmake.exe", NULL)) + Usage(); + exit (0); + } + break; + + case 'v': + OptV = TRUE; + break; + + default: + Warning (WARN_OPTION_IGNORED, pchWord); + break; + } + } +} + + +static VOID +MarkNewSBR(char *lszName) +// mark the specified SBR file as requiring update +// +{ + int fh; + char ch; + + if (!OutputFileName) + OutputFileName = LszDupNewExt (lszName, "bsc"); + + if ((fh = open(lszName, O_BINARY|O_RDONLY)) == -1) { + Error(ERR_OPEN_FAILED, lszFName); + } + + // if the file has non zero length then it is being updated -- else + // it is just a stub that will not affect the database this time around + // + if (read(fh, &ch, 1) != 1) + VaSbrAdd(SBR_NEW, lszName); // to remain in .bsc + else + VaSbrAdd(SBR_NEW|SBR_UPDATE, lszName); // to be re-installed in .bsc + + close (fh); +} + diff --git a/private/utils/mep/browser/mbrmake/mbrmake.h b/private/utils/mep/browser/mbrmake/mbrmake.h new file mode 100644 index 000000000..904ee8dfb --- /dev/null +++ b/private/utils/mep/browser/mbrmake/mbrmake.h @@ -0,0 +1,246 @@ +#define MAXSYMPTRTBLSIZ 4095 // max symbol pointer table size +#define PATH_BUF 512 // path buffer size + + +#include +#include +#include +#include +#include + +#if defined (OS2) +#define INCL_NOCOMMON +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#define INCL_DOSMISC +#include +#else +#include +#endif + + +#include "hungary.h" +#include "vm.h" +#include "list.h" +#include "errors.h" + + + +// rjsa 10/22/90 +// Some runtime library functions are broken, so intrinsics have +// to be used. +// BUGBUG +//#pragma intrinsic (memset, memcpy, memcmp) +//#pragma intrinsic (strset, strcpy, strcmp, strcat, strlen) + +#ifndef LINT_PROTO +#include "sbrproto.h" +#endif + +#pragma pack(1) + +#if rjsa +extern void far * cdecl _fmalloc(unsigned int); +extern void cdecl _ffree(void far *); +extern char * cdecl getenv(const char *); +extern char * cdecl mktemp(char *); +extern char * cdecl strdup(const char *); +#endif + +// typedef char flagType; + +typedef struct { + VA vaNextMod; // next module + VA vaNameSym; // name Symbol + VA vaFirstModSym; // first ModSym for this file + VA vaLastModSym; // last ModSym for this file + WORD csyms; // symbol count +} MOD; + +typedef struct { + VA vaNextModSym; // next symbol + VA vaFirstProp; // first prop entry for this symbol +} MODSYM; + +typedef struct { + VA vaNextSym; // next symbol + VA vaFirstProp; // first prop entry for this symbol + VA vaNameText; // the text of this symbol + WORD cprop; // Property count + WORD isym; // this symbol index +} SYM; + +typedef struct { + VA vaNextProp; // next property + WORD iprp; // this property index + WORD sattr; // attribute + WORD cref; + VA vaNameSym; // symbol name ptr + VA vaDefList; // def chain + VP vpFirstRef; // ref head + VP vpLastRef; // ref tail + VA vaCalList; // cal chain + VA vaCbyList; // cby chain + VA vaHintRef; // last ref we found by searching +} PROP; + +typedef struct { + VA vaFileSym; // file name Symbol ptr + WORD deflin; // def line # + WORD isbr; // sbr file owning this DEF +} DEF; + +typedef struct { + VP vpNextRef; // next ref in list + VP vpFileSym; // file name Symbol ptr + WORD reflin; // ref line # + WORD isbr; // sbr file owning this REF +} REF; + +typedef struct { + VA vaCalProp; // prop called/used + WORD calcnt; // times called + WORD isbr; // sbr file owning this CAL +} CAL; + +typedef struct { + VA vaCbyProp; // prop calling/using + WORD cbycnt; // times calling/using + WORD isbr; // sbr file owning this CBY +} CBY; + +typedef struct { + VA vaNextOrd; // next ord + VA vaOrdProp; // prop item alias goes to + WORD aliasord; // ordinal +} ORD; + +typedef struct { + VA vaNextSbr; // next sbr + WORD isbr; // index for this SBR file + BOOL fUpdate; // is this SBR file being updated? + char szName[1]; // name +} SBR; + +typedef struct { + VA vaOcrProp; // prop occurring + WORD isbr; // SBR file it occurs in +} OCR; + +typedef struct exclink { + struct exclink FAR *xnext; // next exclusion + LPCH pxfname; // exclude file name +} EXCLINK, FAR *LPEXCL; + +#include "extern.h" + +// macros to 'g'et an item of the specified type from VM space + +#ifdef SWAP_INFO + +#define gMOD(va) (*(iVMGrp = grpMod, modRes = LpvFromVa(va,1))) +#define gMODSYM(va) (*(iVMGrp = grpModSym, modsymRes = LpvFromVa(va,2))) +#define gSYM(va) (*(iVMGrp = grpSym, symRes = LpvFromVa(va,3))) +#define gPROP(va) (*(iVMGrp = grpProp, propRes = LpvFromVa(va,4))) +#define gDEF(va) (*(iVMGrp = grpDef, defRes = LpvFromVa(va,5))) +#define gREF(va) (*(iVMGrp = grpRef, refRes = LpvFromVa(va,6))) +#define gCAL(va) (*(iVMGrp = grpCal, calRes = LpvFromVa(va,7))) +#define gCBY(va) (*(iVMGrp = grpCby, cbyRes = LpvFromVa(va,8))) +#define gORD(va) (*(iVMGrp = grpOrd, ordRes = LpvFromVa(va,9))) +#define gSBR(va) (*(iVMGrp = grpSbr, sbrRes = LpvFromVa(va,13))) +#define gTEXT(va) ((iVMGrp = grpText, textRes = LpvFromVa(va,12))) +#define gOCR(va) (*(iVMGrp = grpOcr, ocrRes = LpvFromVa(va,14))) + +#else + +#define gMOD(va) (*(modRes = LpvFromVa(va,1))) +#define gMODSYM(va) (*(modsymRes = LpvFromVa(va,2))) +#define gSYM(va) (*(symRes = LpvFromVa(va,3))) +#define gPROP(va) (*(propRes = LpvFromVa(va,4))) +#define gDEF(va) (*(defRes = LpvFromVa(va,5))) +#define gREF(va) (*(refRes = LpvFromVa(va,6))) +#define gCAL(va) (*(calRes = LpvFromVa(va,7))) +#define gCBY(va) (*(cbyRes = LpvFromVa(va,8))) +#define gORD(va) (*(ordRes = LpvFromVa(va,9))) +#define gSBR(va) (*(sbrRes = LpvFromVa(va,13))) +#define gTEXT(va) ((textRes = LpvFromVa(va,12))) +#define gOCR(va) (*(ocrRes = LpvFromVa(va,14))) + +#endif + +// macros to 'p'ut an item of the specified type to VM space + +#define pMOD(va) DirtyVa(va) +#define pMODSYM(va) DirtyVa(va) +#define pSYM(va) DirtyVa(va) +#define pPROP(va) DirtyVa(va) +#define pDEF(va) DirtyVa(va) +#define pREF(va) DirtyVa(va) +#define pCAL(va) DirtyVa(va) +#define pCBY(va) DirtyVa(va) +#define pORD(va) DirtyVa(va) +#define pSBR(va) DirtyVa(va) +#define pTEXT(va) DirtyVa(va) +#define pOCR(va) DirtyVa(va) + +// these macros allow access to the 'c'urrent visible item + +#define cMOD (*modRes) +#define cMODSYM (*modsymRes) +#define cSYM (*symRes) +#define cPROP (*propRes) +#define cDEF (*defRes) +#define cREF (*refRes) +#define cCAL (*calRes) +#define cCBY (*cbyRes) +#define cORD (*ordRes) +#define cSBR (*sbrRes) +#define cTEXT (textRes) +#define cOCR (*ocrRes) + +#define grpSym 0 +#define grpMod 1 +#define grpOrd 2 +#define grpProp 3 +#define grpModSym 4 +#define grpDef 5 +#define grpRef 6 +#define grpCal 7 +#define grpCby 8 +#define grpList 9 +#define grpText 10 +#define grpSbr 11 +#define grpOcr 12 + +#define SBR_OLD (1<<0) // this .sbr file used to exist +#define SBR_NEW (1<<1) // this .sbr file currently exists +#define SBR_UPDATE (1<<2) // this .sbr file is to be updated + +// +// this is used to add items to the tail of the lists in a property group +// +// things being added type m +// ------------------ ---- --- +// Refs Ref REF +// Defs Def DEF +// Calls/Uses Cal CAL +// Called by/Used By Cby CBY +// + +#define AddTail(type, m) \ +{ \ + VP vpT; \ + VA vaT; \ + MkVpVa(vpT, va##type); \ + vaT = VaFrVp(cPROP.vpLast##type); \ + if (vaT) { \ + g##m(vaT).vpNext##type = vpT; \ + p##m(vaT); \ + } \ + else { \ + cPROP.vpFirst##type = vpT; \ + } \ + cPROP.vpLast##type = vpT; \ +} diff --git a/private/utils/mep/browser/mbrmake/mbrwbsc.c b/private/utils/mep/browser/mbrmake/mbrwbsc.c new file mode 100644 index 000000000..a63e6a520 --- /dev/null +++ b/private/utils/mep/browser/mbrmake/mbrwbsc.c @@ -0,0 +1,782 @@ +// +// +// mbRWBSC.C - Write .BSC Source Data Base file from various lists. +// +// + +#define LINT_ARGS + +#include +#include +#include + +#include "sbrfdef.h" +#include "mbrmake.h" +#include "sbrbsc.h" +#include "mbrcache.h" + +// prototypes +// + +static void pascal WriteBSCHeader (void); +static void pascal WriteAtoms (void); +static void pascal WriteMods (void); +static void pascal WriteModSyms (void); +static void pascal WriteSyms (void); +static void pascal WriteProps (void); +static void pascal WriteRefs (void); +static void pascal WriteDefs (void); +static void pascal WriteCals (void); +static void pascal WriteCbys (void); +static void pascal WriteSbrInfo (void); +static void pascal IndexTree (void); +static void pascal BSCWrite (LPV lpv, WORD cch); +static void pascal BSCWriteLsz (LSZ lsz); + +// + +#define BSCOut(v) BSCWrite(&(v), sizeof(v)) + +static WORD CntAtomPage; // count of Atom pages +static WORD AtomCnt = 0; + +static WORD unknownModName; // UNKNOWN module idx + +static WORD ModSymCnt = 0; // count of modsyms +static WORD SymCnt = 0; // count of symbols +static WORD PropCnt = 0; // count of props +static DWORD RefCnt = 0; // count of refs +static WORD DefCnt = 0; // count of defs +static WORD CbyCnt = 0; // count of use half of above +static WORD CalCnt = 0; // count of used by half of above + +static DWORD lbModList; // offset to Module list +static DWORD lbModSymList; // offset to ModSym list +static DWORD lbSymList; // offset to Symbol list +static DWORD lbPropList; // offset to Property list +static DWORD lbRefList; // offset to Reference list +static DWORD lbDefList; // offset to Definition list +static DWORD lbCalList; // offset to Call/used list +static DWORD lbCbyList; // offset to Call/used list +static DWORD lbAtomCache; // offset to Sym Atom cache +static DWORD lbSbrList; // offset to Sbr file names + +extern char far *GetAtomCache (WORD); + +void +WriteBSC (char *OutputFileName) +// Write .BSC Source Data Base +// +{ + OutFile = fopen(OutputFileName, "wb"); + if (OutFile == NULL) { + Error(ERR_OPEN_FAILED, OutputFileName); + } + + // + // no backing out from here -- if we fail we must delete the database + // + + fOutputBroken = TRUE; + + WriteBSCHeader(); // save space for header + + WriteAtoms(); // sort and write atom cache + + IndexTree(); // xlate pointers to indices + + BldModSymList(); // Build module symbol list + + SetVMClient(VM_EMIT_TREE); + + unknownModName = gSYM(vaUnknownSym).isym; // record UNKNOWN index + + WriteMods(); // output modules + WriteModSyms(); // output module symbol lists + WriteSyms(); // output all symbols + WriteProps(); // output all prop headers + WriteRefs(); // output all refs + WriteDefs(); // output all defs + WriteCals(); // output all uses/calls + WriteCbys(); // output all UBY/CBY + WriteSbrInfo(); // output the SBR file names + + if (fseek(OutFile, 0L, SEEK_SET)) // Beginning of file + SeekError (OutputFileName); + + WriteBSCHeader (); // output .BSC header + + fclose(OutFile); + + // + // we're all done --- it's a keeper! + // + + fOutputBroken = FALSE; + + SetVMClient(VM_MISC); + + if (OptV) { + printf ("%u\tModules\n", ModCnt); + printf ("%u\tSymbols\n", SymCnt); + printf ("%u\tDefinitions\n", DefCnt); + printf ("%u\tReferences\n", RefCnt); + printf ("%u\tCalls/Uses\n", CalCnt); + printf ("%u\tCalled by/Used by\n", CbyCnt); +#ifdef DEBUG + printf ("\n"); + printf ("%u\tTotal ModSyms\n", ModSymCnt); + printf ("%u\tTotal Properties\n", PropCnt); + printf ("%u\tLast Atom page \n", AtomCnt); + printf ("\n"); + printf ("%lu\tBase of AtomCache\n", lbAtomCache); + printf ("%lu\tBase of ModList\n", lbModList); + printf ("%lu\tBase of ModSymList\n", lbModSymList); + printf ("%lu\tBase of SymList\n", lbSymList); + printf ("%lu\tBase of PropList\n", lbPropList); + printf ("%lu\tBase of RefList\n", lbRefList); + printf ("%lu\tBase of DefList\n", lbDefList); + printf ("%lu\tBase of CalList\n", lbCalList); + printf ("%lu\tBase of CbyList\n", lbCbyList); +#endif + } +} + +static void pascal +WriteBSCHeader () +// Write .BSC header, counts, and table offsets. +// +{ + BYTE ver; // version num + + // output BSC version (major and minor) + + ver = BSC_MAJ; + BSCOut(ver); // major ver + + ver = BSC_MIN; + BSCOut(ver); // minor ver + + ver = BSC_UPD; + BSCOut(ver); // update ver + + BSCOut(fCase); // case sensitive + BSCOut(MaxSymLen); // biggest symbol allowed + + BSCOut(unknownModName); // UNKNOWN idx + + // output counts (sizes) of each data area + + BSCOut(ModCnt); + BSCOut(ModSymCnt); + BSCOut(SymCnt); + BSCOut(PropCnt); + BSCOut(RefCnt); + BSCOut(DefCnt); + BSCOut(CalCnt); + BSCOut(CbyCnt); + + // last page # + + BSCOut(CntAtomPage); + + // last page size + + BSCOut(AtomCnt); + + // output BSC data area offsets + + BSCOut(lbModList); + BSCOut(lbModSymList); + BSCOut(lbSymList); + BSCOut(lbPropList); + BSCOut(lbRefList); + BSCOut(lbDefList); + BSCOut(lbCalList); + BSCOut(lbCbyList); + BSCOut(lbAtomCache); + BSCOut(lbSbrList); +} + +static void pascal +WriteAtoms () +// Write a sorted version of the symbol Atom Cache to the .BSC file by walking +// the sorted symbol subscript array +// +{ + WORD i; + int Atomlen; + LPCH lpchAtoms; + LSZ lszAtom; + + VA vaSym; + + SetVMClient(VM_EMIT_ATOMS); + + lpchAtoms = LpvAllocCb(ATOMALLOC); + + lbAtomCache = ftell(OutFile); // offset to text of symbols + + for (i=0; i < cAtomsMac; i++) { + vaSym = rgvaSymSorted[i]; + if (vaSym == vaNil) continue; + + gSYM(vaSym); + lszAtom = gTEXT(cSYM.vaNameText); + + Atomlen = strlen(lszAtom); + + // write Atom page if not enough room + // + if (Atomlen + AtomCnt + 1 > ATOMALLOC) { + if (AtomCnt < ATOMALLOC) + memset(lpchAtoms + AtomCnt, 0, ATOMALLOC - AtomCnt); + + if ((fwrite (lpchAtoms, ATOMALLOC, 1, OutFile)) != 1) + WriteError (OutputFileName); + + CntAtomPage++; + AtomCnt = 0; + } + + strcpy(lpchAtoms + AtomCnt, lszAtom); // copy Atom + + cSYM.vaNameText = (PVOID)(((long)CntAtomPage << 16) | (AtomCnt)); + + pSYM(vaSym); + + AtomCnt += Atomlen + 1; + + // force to even value + if (AtomCnt & 1) lpchAtoms[AtomCnt++] = 0; + } + + // write last Atom page + // + if (AtomCnt) + if ((fwrite (lpchAtoms, AtomCnt, 1, OutFile)) != 1) + WriteError (OutputFileName); + + // free all the memory for the atom cache, we no longer need it + + fflush (OutFile); + + FreeLpv(lpchAtoms); + + SetVMClient(VM_MISC); +} + +static void pascal +WriteMods() +// write out the list of modules +// +// compute the MODSYM indices as we do this +// +{ + MODLIST bmod; + VA vaMod; + WORD i; + + ModSymCnt = 0; + lbModList = ftell(OutFile); // offset to Module list + + for (i = cSymbolsMac; i < cAtomsMac; i++) { + gSYM(rgvaSymSorted[i]); + vaMod = cSYM.vaFirstProp; // points back to module, honest! + gMOD(vaMod); + + bmod.ModName = gSYM(cMOD.vaNameSym).isym; // module name idx + ModSymCnt += cMOD.csyms; + bmod.mSymEnd = ModSymCnt; // last ModSym idx +1 + BSCOut(bmod); + } +} + +static void pascal +WriteModSyms() +// write out the list of modsyms +// +{ + MODSYMLIST bmodsym; + VA vaMod, vaModSym; + WORD i; + + lbModSymList = ftell(OutFile); // offset to ModSym list + + for (i = cSymbolsMac; i < cAtomsMac; i++) { + gSYM(rgvaSymSorted[i]); + vaMod = cSYM.vaFirstProp; // points back to module, honest! + gMOD(vaMod); + + vaModSym = cMOD.vaFirstModSym; + while (vaModSym) { + gMODSYM(vaModSym); + + // Symbol Property idx + bmodsym.ModSymProp = gPROP(cMODSYM.vaFirstProp).iprp; + + BSCOut(bmodsym); + + vaModSym = cMODSYM.vaNextModSym; + } + } +} + +static void pascal +WriteSyms() +// write out the list of SYMs +// +{ + SYMLIST bsym; + VA vaSym; + WORD i; + + lbSymList = ftell(OutFile); // offset to Symbol list + + PropCnt = 0; + for (i=0; i < cAtomsMac; i++) { + vaSym = rgvaSymSorted[i]; + if (vaSym == vaNil) continue; + + gSYM(vaSym); + + PropCnt += cSYM.cprop; + + bsym.PropEnd = PropCnt; // last Prop idx +1 + bsym.Atom = (WORD)((long)cSYM.vaNameText & 0xffff); // Atom cache offset + bsym.Page = (WORD)((long)cSYM.vaNameText >> 16); // Atom cache page + + BSCOut(bsym); + } +} + +static void pascal +WriteProps () +// write out the list of PROPS to the database +// +// the number of definitions (DefCnt), references (RefCnt), +// calls (CalCnt) and called-by (CbyCnt) items are computed at this time +// +// Each PROP is assigned numbers for its associated objects +// +{ + PROPLIST bprop; + VA vaSym, vaProp; + WORD i; + + lbPropList = ftell(OutFile); // offset to Property list + + DefCnt = 0; + RefCnt = 0L; + CalCnt = 0; + CbyCnt = 0; + + for (i=0; i < cSymbolsMac; i++) { + vaSym = rgvaSymSorted[i]; + if (vaSym == vaNil) continue; + + vaProp = gSYM(vaSym).vaFirstProp; + + while (vaProp) { + gPROP(vaProp); + gSYM(cPROP.vaNameSym); + + bprop.PropName = cSYM.isym; // Symbol idx + bprop.PropAttr = cPROP.sattr; // Property Attribute + + DefCnt += CItemsList(cPROP.vaDefList); + + bprop.DefEnd = DefCnt; // last Definition idx +1 + + RefCnt += cPROP.cref; + + bprop.RefEnd = RefCnt; // last Reference idx +1 + + CalCnt += CItemsList(cPROP.vaCalList); + + bprop.CalEnd = CalCnt; // last Calls/uses idx +1 + + CbyCnt += CItemsList(cPROP.vaCbyList); + + bprop.CbyEnd = CbyCnt; // last Called by/used by idx +1 + + BSCOut(bprop); + + vaProp = cPROP.vaNextProp; + } + } +} + +static void pascal +WriteRefs() +// write out the list of references +// +{ + REFLIST bref; + VA vaSym, vaProp, vaRef; + WORD i; + + lbRefList = ftell(OutFile); // offset to Reference list + + for (i=0; i < cSymbolsMac; i++) { + vaSym = rgvaSymSorted[i]; + if (vaSym == vaNil) continue; + + vaProp = gSYM(vaSym).vaFirstProp; + + while (vaProp) { + gPROP(vaProp); + + vaRef = VaFrVp(cPROP.vpFirstRef); + while (vaRef) { + gREF(vaRef); + + gSYM(VaFrVp(cREF.vpFileSym)); + + bref.RefNam = cSYM.isym; // Symbol idx + bref.RefLin = cREF.reflin; // Symbol lin + bref.isbr = cREF.isbr; // owner + + BSCOut(bref); + + vaRef = VaFrVp(cREF.vpNextRef); + } + + vaProp = cPROP.vaNextProp; + } + } +} + +static void pascal +WriteDefs() +// write out the list of defintions +// +{ + REFLIST bdef; + WORD i; + VA vaProp, vaSym; + + lbDefList = ftell(OutFile); // offset to Definition list + + for (i=0; i < cSymbolsMac; i++) { + vaSym = rgvaSymSorted[i]; + if (vaSym == vaNil) continue; + + vaProp = gSYM(vaSym).vaFirstProp; + + while (vaProp) { + gPROP(vaProp); + + ENM_LIST (cPROP.vaDefList, DEF) + + gSYM(cDEF.vaFileSym); + + bdef.RefNam = cSYM.isym; // Symbol idx + bdef.RefLin = cDEF.deflin; // Symbol lin + bdef.isbr = cDEF.isbr; // owner + + BSCOut(bdef); + + ENM_END + + vaProp = cPROP.vaNextProp; + } + } +} + +static void pascal +WriteCals() +// write out the list of uses (CALs) items +// +{ + USELIST buse; + PROP prop; + VA vaSym, vaProp; + WORD i; + + lbCalList = ftell(OutFile); // offset to CAL list + + for (i=0; i < cSymbolsMac; i++) { + vaSym = rgvaSymSorted[i]; + if (vaSym == vaNil) continue; + + vaProp = gSYM(vaSym).vaFirstProp; + + while (vaProp) { + prop = gPROP(vaProp); + + ENM_LIST(prop.vaCalList, CAL) + + gPROP(cCAL.vaCalProp); + + buse.UseProp = cPROP.iprp; // property idx + buse.UseCnt = (BYTE) cCAL.calcnt; // use count + buse.isbr = cCAL.isbr; // owner + + BSCOut(buse); + + ENM_END + + vaProp = prop.vaNextProp; + } + } + BSCOut(buse); // Pad +} + +static void pascal +WriteCbys() +// write out the list of used-by (CBY) items +// +{ + USELIST buse; + PROP prop; + VA vaSym, vaProp; + WORD i; + + lbCbyList = ftell(OutFile); // offset to CBY list + + for (i=0; i < cSymbolsMac; i++) { + vaSym = rgvaSymSorted[i]; + if (vaSym == vaNil) continue; + + vaProp = gSYM(vaSym).vaFirstProp; + + while (vaProp) { + prop = gPROP(vaProp); + + ENM_LIST(prop.vaCbyList, CBY) + + gPROP(cCBY.vaCbyProp); + + buse.UseProp = cPROP.iprp; // property idx + buse.UseCnt = (BYTE) cCBY.cbycnt; // use count + buse.isbr = cCBY.isbr; // owner + + BSCOut(buse); + + ENM_END + + vaProp = prop.vaNextProp; + } + } + BSCOut(buse); // Pad +} + +static void pascal +WriteSbrInfo() +// write out the names of the .sbr files in the correct order +// +{ + VA vaSbr; + WORD isbr; + VA *rgVaSbr; + + lbSbrList = ftell(OutFile); + + rgVaSbr = (VA *)LpvAllocCb(SbrCnt * (WORD)sizeof(VA)); + + for (isbr = 0; isbr < SbrCnt; isbr++) + rgVaSbr[isbr] = vaNil; + + vaSbr = vaRootSbr; + while (vaSbr) { + gSBR(vaSbr); + if (cSBR.isbr != -1) + rgVaSbr[cSBR.isbr] = vaSbr; + + vaSbr = cSBR.vaNextSbr; + } + + for (isbr = 0; isbr < SbrCnt; isbr++) { + if (rgVaSbr[isbr] != vaNil) { + gSBR(rgVaSbr[isbr]); + BSCWriteLsz(cSBR.szName); + } + } + BSCWriteLsz(""); +} + +static void pascal +IndexTree () +// Walk all the list of all symbols and index each prop as we find it +// at this point we also count the total number of defs + refs to +// make sure that we can actually create this database +// +{ + VA vaSym, vaProp; + DWORD cdefs = 0; + DWORD crefs = 0; + DWORD ccals = 0; + DWORD ccbys = 0; + WORD i; + + SetVMClient(VM_INDEX_TREE); + + SymCnt = 0; + PropCnt = 0; + + for (i=0; i < cAtomsMac; i++) { + vaSym = rgvaSymSorted[i]; + if (vaSym == vaNil) continue; + + gSYM(vaSym); + cSYM.isym = SymCnt++; // Symbol index + pSYM(vaSym); + + // the vaFirstProp field is used for something else in module symbols + if (cSYM.cprop) + vaProp = cSYM.vaFirstProp; + else + vaProp = vaNil; + + while (vaProp) { + gPROP(vaProp); + + cPROP.iprp = PropCnt++; // Property index + + cdefs += CItemsList(cPROP.vaDefList); + crefs += cPROP.cref; + ccals += CItemsList(cPROP.vaCalList); + ccbys += CItemsList(cPROP.vaCbyList); + + pPROP(vaProp); + + vaProp = cPROP.vaNextProp; + } + } + SymCnt -= ModCnt; // Subtract module names + + if (cdefs > 0xffffL || + crefs > 0xffffffL || + ccals > 0xffffL || + ccbys > 0xffffL) { + if (OptV) { + printf ("%u\tModules\n", ModCnt); + printf ("%u\tSymbols\n", SymCnt); + printf ("%lu\tDefinitions\n", cdefs); + printf ("%lu\tReferences\n", crefs); + printf ("%lu\tCalls/Uses\n", ccals); + printf ("%lu\tCalled by/Used by\n", ccbys); + } + Error(ERR_CAPACITY_EXCEEDED, ""); + } + + SetVMClient(VM_MISC); +} + +static void pascal +BSCWrite(LPV lpv, WORD cch) +// write block to the .bsc file +// +{ + if (fwrite(lpv, cch, 1, OutFile) != 1) + WriteError (OutputFileName); +} + +static void pascal +BSCWriteLsz(LSZ lsz) +// write a null terminated string to the BSC file +// +{ + BSCWrite(lsz, (WORD)(strlen(lsz)+1)); +} + + +#ifdef DEBUG + +void +DebugDump() +{ + VA vaMod, vaProp, vaSym; + WORD i; + + vaMod = vaRootMod; + printf("Modules:\n"); + while (vaMod) { + gMOD(vaMod); + printf ("\t%s\n", GetAtomStr (cMOD.vaNameSym)); + vaMod = cMOD.vaNextMod; + } + printf ("\nAll Symbols:\n"); + + for (i=0; i < cAtomsMac; i++) { + vaSym = rgvaSymSorted[i]; + if (vaSym == vaNil) continue; + + gSYM(vaSym); + + // the vaFirstProp field is used for something else in module symbols + if (cSYM.cprop) + vaProp = cSYM.vaFirstProp; + else + vaProp = vaNil; + + while (vaProp) { + gPROP(vaProp); + + DebugDumpProp(vaProp); + + vaProp = gPROP(vaProp).vaNextProp; + } + } +} + +void +DebugDumpProp(VA vaProp) +{ + PROP prop; + VA vaRef; + + gPROP(vaProp); + prop = cPROP; + + printf ("%s ", GetAtomStr (prop.vaNameSym)); + printf ("\t\t[%d %d %d %d]\n", + CItemsList(prop.vaDefList), + prop.cref, + CItemsList(prop.vaCalList), + CItemsList(prop.vaCbyList) + ); + + ENM_LIST(prop.vaDefList, DEF) + + printf ("\tdefined in %s(%d) <%d>\n", + GetAtomStr (cDEF.vaFileSym), + cDEF.deflin, + cDEF.isbr + ); + ENM_END + + vaRef = VaFrVp(prop.vpFirstRef); + while (vaRef) { + gREF(vaRef); + + printf ("\trefer'd in %s(%d) <%d>\n", + GetAtomStr ( VaFrVp(cREF.vpFileSym) ), + cREF.reflin, + cREF.isbr + ); + + vaRef = VaFrVp(cREF.vpNextRef); + } + + ENM_LIST(prop.vaCalList, CAL) + + printf ("\tcalls/uses %s[%d] <%d>\n", + GetAtomStr (gPROP(cCAL.vaCalProp).vaNameSym), + cCAL.calcnt, + cCAL.isbr + ); + ENM_END + + ENM_LIST(prop.vaCbyList, CBY) + + printf ("\tc-by/u-by %s[%d] <%d>\n", + GetAtomStr (gPROP(cCBY.vaCbyProp).vaNameSym), + cCBY.cbycnt, + cCBY.isbr + ); + ENM_END + +} +#endif diff --git a/private/utils/mep/browser/mbrmake/ord.c b/private/utils/mep/browser/mbrmake/ord.c new file mode 100644 index 000000000..ea0d8c44d --- /dev/null +++ b/private/utils/mep/browser/mbrmake/ord.c @@ -0,0 +1,116 @@ +// +// ORD.C - Keep track of ordinals in the current .sbr file +// +// + +#include "mbrmake.h" + +static WORD near cOrdFree; // number of free ords in this block +static VA near vaOrdNext; // the next free ord +static VA near vaOrdBase; // the first ord in this block +static VA near vaOrdRoot; // the first ord block + +// ordinals may be sparse so they are hashed +// +// number of hash buckets + +#define PORD_MAX 512 +#define HASH_ORD(ord) ((ord)&511) + +static VA near rgvaOrd[PORD_MAX]; // array of linked-lists + +// allocation blocking (ORD_BLOCK objects per alloc) +#define ORD_BLOCK 128 + +VOID +FreeOrdList() +// free the ordinal alias list +// +{ + int i; + + // clean the hash table + for (i=0; i 1988, Microsoft Corporation +// +// Revision History: +// +// 13-Aug-1989 rm Extracted from mbrapi.c +// + +#define LINT_ARGS + +#include "mbrmake.h" + +#include + +#include "mbrcache.h" + +#include "sbrfdef.h" // sbr attributes +#include "sbrbsc.h" + +typedef struct _sbrinfo { + WORD fUpdate; + WORD isbr; +} SI, far *LPSI; // sbr info + +#define LISTALLOC 50 // Browser max list size + +typedef WORD IDX; + +// these will be initialized by the reading of the .bsc file +// +// fCase; TRUE for case compare +// MaxSymLen; longest symbol length +// ModCnt; count of modules +// SbrCnt; count of sbr files +// vaUnknownSym; unknown symbol +// vaUnknownMod; unknown module +// + +// static data + +static BOOL fIncremental; // update will be incremental +static BOOL fFoundSBR; // at least .sbr file matched + +static int fhBSC = 0; // .BSC file handle + +static IDX Unknown; // UNKNOWN symbol index + +static WORD ModSymCnt; // count of modsyms +static WORD SymCnt; // count of symbols +static WORD PropCnt; // count of properties +static DWORD RefCnt; // count of references +static WORD DefCnt; // count of definitions +static WORD CalCnt; // count of calls +static WORD CbyCnt; // count of called bys +static WORD lastAtomPage; // last atom page # +static WORD lastAtomCnt; // last atom page size + +static WORD cbModSymCnt; // size of list of modsyms +static WORD cbSymCnt; // size of list of symbols +static WORD cbPropCnt; // size of list of properties +static WORD cbRefCnt; // size of list of references +static WORD cbDefCnt; // size of list of definitions +static WORD cbCalCnt; // size of list of calls +static WORD cbCbyCnt; // size of list of called bys + +static WORD MaxModSymCnt; // max list of modsyms +static WORD MaxSymCnt; // max list of symbols +static WORD MaxPropCnt; // max list of properties +static WORD MaxRefCnt; // max list of references +static WORD MaxDefCnt; // max list of definitions +static WORD MaxCalCnt; // max list of calls +static WORD MaxCbyCnt; // max list of called bys + +static DWORD lbModSymList; // modsym list file start +static DWORD lbSymList; // symbol list file start +static DWORD lbPropList; // property list file start +static DWORD lbRefList; // reference list file start +static DWORD lbDefList; // defintion list file start +static DWORD lbCalList; // call list file start +static DWORD lbCbyList; // called by list file start +static DWORD lbSbrList; // sbr list file start +static DWORD lbAtomCache; // atom cache file start + +static WORD CurModSymPage = 0; // Current page of modsyms +static WORD CurSymPage = 0; // Current page of symbols +static WORD CurPropPage = 0; // Current page of properties +static WORD CurRefPage = 0; // Current page of references +static WORD CurDefPage = 0; // Current page of defintions +static WORD CurCalPage = 0; // Current page of calls +static WORD CurCbyPage = 0; // Current page of called bys + +static LSZ lszBSCName = NULL; // name of .bsc file + +static MODLIST far *pfModList; // module list cache start +static MODSYMLIST far *pfModSymList; // modsym list cache start +static SYMLIST far *pfSymList; // symbol list cache start +static PROPLIST far *pfPropList; // property list cache start +static REFLIST far *pfRefList; // reference list cache start +static REFLIST far *pfDefList; // def'n list cache start +static USELIST far *pfCalList; // calls list cache start +static USELIST far *pfCbyList; // call bys list cache start + +static WORD AtomPageTblMac; // last cache page used +static CACHEPAGE AtomPageTbl[MAXATOMPAGETBL]; // Atom Cache table + +#define bMOD(imod) (pfModList[imod]) +#define bMODSYM(isym) (pfModSymList[ModSymPAGE(isym)]) +#define bSYM(isym) (pfSymList[SymPAGE(isym)]) +#define bPROP(iprop) (pfPropList[PropPAGE(iprop)]) + +#define bREF(iref) (pfRefList[RefPAGE(iref)]) +#define bDEF(idef) (pfDefList[DefPAGE(idef)]) + +#define bCAL(iuse) (pfCalList[CalPAGE(iuse)]) +#define bCBY(iuse) (pfCbyList[CbyPAGE(iuse)]) +#define bUSE(iuse) (pfCalList[CalPAGE(iuse)]) +#define bUBY(iuse) (pfCbyList[CbyPAGE(iuse)]) + +#define BSCIn(v) ReadBSC(&v, sizeof(v)) + +// prototypes +// + +static VOID GetBSCLsz(LSZ lsz); +static VOID GetBSC (DWORD lpos, LPV lpv, WORD cb); +static VOID ReadBSC(LPV lpv, WORD cb); +static IDX SwapPAGE (DWORD, LPV, WORD, WORD, WORD *, DWORD); +static LPCH GetAtomCache (WORD); +static WORD ModSymPAGE(WORD idx); +static WORD SymPAGE(WORD idx); +static WORD PropPAGE(WORD idx); +static WORD RefPAGE(DWORD idx); +static WORD DefPAGE(WORD idx); +static WORD CalPAGE(WORD idx); +static WORD CbyPAGE(WORD idx); +static LSZ LszNameFrIsym(WORD isym); +static LPSI LpsiCreate(VOID); + +static VOID +GetBSCLsz(LSZ lsz) +// read a null terminated string from the current position in the BSC file +// +{ + for (;;) { + if (read(fhBSC, lsz, 1) != 1) + ReadError(lszBSCName); + if (*lsz++ == 0) return; + } +} + +static VOID +ReadBSC(LPV lpv, WORD cb) +// read a block of data from the BSC file +// +// the requested number of bytes MUST be present +// +{ + if (read(fhBSC, lpv, cb) != (int)cb) + ReadError(lszBSCName); +} + +static VOID +GetBSC(DWORD lpos, LPV lpv, WORD cb) +// Read a block of the specified size from the specified position +// +// we have to be tolerant of EOF here because the swapper might ask +// for a whole block when only block when only part of a block is actually +// is actually present +// +{ + if (lseek(fhBSC, lpos, SEEK_SET) == -1) + SeekError(lszBSCName); + + if (read(fhBSC, lpv, cb) == -1) + ReadError(lszBSCName); +} + +static IDX +SwapPAGE (DWORD lbuflist, LPV pfTABLE, WORD tblsiz, +/* */ WORD lstsiz, WORD * pcurpage, DWORD idx) +// SwapPAGE - Swap in the table page for the table pfTABLE[idx] +// and return the table's new index in the page. +{ + WORD page; + IDX newidx; + + page = (WORD)(idx / lstsiz); + newidx = (WORD)(idx % lstsiz); + + if (page == *pcurpage) + return newidx; + + GetBSC(lbuflist+((long)tblsiz*(long)page), pfTABLE, tblsiz); + + *pcurpage = page; + return newidx; +} + +static IDX +ModSymPAGE (IDX idx) +// Swap in the ModSym page for ModSym[idx] +// return the ModSym's index in the page. +// +{ + return SwapPAGE (lbModSymList, pfModSymList, + cbModSymCnt, MaxModSymCnt, &CurModSymPage, (DWORD)idx); +} + +static IDX +SymPAGE (IDX idx) +// Swap in the Symbol page for symbol[idx] +// return the Symbol's index in the page. +// +{ + return SwapPAGE (lbSymList, pfSymList, + cbSymCnt, MaxSymCnt, &CurSymPage, (DWORD)idx); +} + +static IDX +PropPAGE (IDX idx) +// Swap in the Property page for Property[idx] +// return the Property's index in the page. +// +{ + return SwapPAGE (lbPropList, pfPropList, + cbPropCnt, MaxPropCnt, &CurPropPage, (DWORD)idx); +} + +static IDX +RefPAGE (DWORD idx) +// Swap in the Reference page for Reference[idx] (ref/def) +// return the Reference's index in the page. +// +{ + return SwapPAGE (lbRefList, pfRefList, + cbRefCnt, MaxRefCnt, &CurRefPage, idx); +} + +static IDX +DefPAGE (IDX idx) +// Swap in the Reference page for Defintions[idx] (ref/def) +// return the Reference's index in the page. +// +{ + return SwapPAGE (lbDefList, pfDefList, + cbDefCnt, MaxDefCnt, &CurDefPage, (DWORD)idx); +} + +static IDX +CalPAGE (IDX idx) +// Swap in the Usage page for Usage[idx] (cal/cby) +// and return the Usage's index in the page. +// +{ + return SwapPAGE (lbCalList, pfCalList, + cbCalCnt, MaxCalCnt, &CurCalPage, (DWORD)idx); +} + +static IDX +CbyPAGE (IDX idx) +// Swap in the Usage page for Usage[idx] (cal/cby) +// and return the Usage's index in the page. +// +{ + return SwapPAGE (lbCbyList, pfCbyList, + cbCbyCnt, MaxCbyCnt, &CurCbyPage, (DWORD)idx); +} + +static LPCH +GetAtomCache (WORD Page) +// load the requested page into the cache +// +{ + WORD ipg; + WORD pagesize; + LPCH pfAtomCsave; + + for (ipg = 0; ipg < AtomPageTblMac; ipg++) { + if (AtomPageTbl[ipg].uPage == Page) + return AtomPageTbl[ipg].pfAtomCache; + } + if (ipg == AtomPageTblMac && ipg != MAXATOMPAGETBL) + AtomPageTblMac++; + + pfAtomCsave = AtomPageTbl[MAXATOMPAGETBL-1].pfAtomCache; + for (ipg = MAXATOMPAGETBL-1; ipg; ipg--) + AtomPageTbl[ipg] = AtomPageTbl[ipg-1]; // move up + + AtomPageTbl[0].pfAtomCache = pfAtomCsave; + AtomPageTbl[0].uPage = Page; + + if (Page == lastAtomPage) + pagesize = lastAtomCnt; + else + pagesize = ATOMALLOC; + + GetBSC(lbAtomCache+ATOMALLOC*(long)Page, + AtomPageTbl[0].pfAtomCache, pagesize); + + return AtomPageTbl[0].pfAtomCache; +} + +static LSZ +LszNameFrIsym (IDX isym) +// Swap in the Atom page for the symbol isym +// return the atom's address in the page. +// +{ + SYMLIST sym; + + sym = bSYM(isym); + return GetAtomCache (sym.Page) + sym.Atom; +} + +VOID +CloseBSC() +// close database and free as much memory as possible +// return TRUE iff successful. +// +{ + int i; + + if (fhBSC) { // if open then close, & free memory + + FreeLpv (pfModList); // module table + FreeLpv (pfModSymList); // modsym table + FreeLpv (pfSymList); // symbol table + FreeLpv (pfPropList); // property table + FreeLpv (pfRefList); // reference table + FreeLpv (pfDefList); // definition table + FreeLpv (pfCalList); // call table + FreeLpv (pfCbyList); // called by table + + for (i=0; i < MAXATOMPAGETBL; i++) + FreeLpv (AtomPageTbl[i].pfAtomCache); // dispose Atom Cache + + close (fhBSC); + } +} + + +BOOL +FOpenBSC (LSZ lszName) +// Open the specified data base. +// Allocate buffers for cache areas +// Initialize the data cache from the data base. +// +// Return TRUE iff successful, FALSE if database can't be read +// +{ + int i; + WORD pagesize; + + BYTE MajorVer; // .bsc version (major) + BYTE MinorVer; // .bsc version (minor) + BYTE UpdatVer; // .bsc version (updat) + + WORD MaxModCnt; // max list of modules + WORD cbModCnt; // size of list of modules + DWORD lbModList; // module list file start + + lszBSCName = lszName; + + fhBSC = open(lszBSCName, O_BINARY|O_RDONLY); + + // if the .bsc file doesn't exist then we don't do any work + // this is the cold compile case + // + + if (fhBSC == -1) + return FALSE; + + // read and check BSC version (major, minor and update) + + BSCIn(MajorVer); + BSCIn(MinorVer); + BSCIn(UpdatVer); + +#ifdef DEBUG + printf("Browser Data Base: %s ver %d.%d.%d\n\n", + lszBSCName, MajorVer, MinorVer, UpdatVer); +#endif + + if ((MajorVer != BSC_MAJ) || + (MinorVer != BSC_MIN) || + (UpdatVer != BSC_UPD)) + return FALSE; + + + // we will be attempting an incremental update + + fIncremental = TRUE; + + // read Case sense switch, max symbol length and Unknown module id + + BSCIn(fCase); + BSCIn(MaxSymLen); + BSCIn(Unknown); + + // read counts (sizes) of each data area + + BSCIn(ModCnt); + BSCIn(ModSymCnt); + BSCIn(SymCnt); + BSCIn(PropCnt); + BSCIn(RefCnt); + BSCIn(DefCnt); + BSCIn(CalCnt); + BSCIn(CbyCnt); + BSCIn(lastAtomPage); + BSCIn(lastAtomCnt); + + // read BSC data area offsets + + BSCIn(lbModList); + BSCIn(lbModSymList); + BSCIn(lbSymList); + BSCIn(lbPropList); + BSCIn(lbRefList); + BSCIn(lbDefList); + BSCIn(lbCalList); + BSCIn(lbCbyList); + BSCIn(lbAtomCache); + BSCIn(lbSbrList); + + // determine data cache area sizes + + #define MIN(a,b) ((a)>(b) ? (b) : (a)) + + MaxModCnt = ModCnt; // max list of modules + MaxModSymCnt = MIN(ModSymCnt , LISTALLOC); // max list of modsyms + MaxSymCnt = MIN(SymCnt+ModCnt, LISTALLOC); // max list of symbols + MaxPropCnt = MIN(PropCnt , LISTALLOC); // max list of props + MaxRefCnt = (WORD)MIN(RefCnt, (long)LISTALLOC); // max list of refs + MaxDefCnt = MIN(DefCnt , LISTALLOC); // max list of defs + MaxCalCnt = MIN(CalCnt , LISTALLOC); // max list of cals + MaxCbyCnt = MIN(CbyCnt , LISTALLOC); // max list of cbys + + cbModCnt = sizeof (MODLIST) * MaxModCnt; // size of mods list + cbModSymCnt = sizeof (MODSYMLIST) * MaxModSymCnt; // size of modsyms list + cbSymCnt = sizeof (SYMLIST) * MaxSymCnt; // size of syms list + cbPropCnt = sizeof (PROPLIST) * MaxPropCnt; // size of props list + cbRefCnt = sizeof (REFLIST) * MaxRefCnt; // size of refs list + cbDefCnt = sizeof (REFLIST) * MaxDefCnt; // size of defs list + cbCalCnt = sizeof (USELIST) * MaxCalCnt; // size of cals list + cbCbyCnt = sizeof (USELIST) * MaxCbyCnt; // size of cbys list + + // Allocate data cache + + pfModList = LpvAllocCb(cbModCnt); + pfModSymList = LpvAllocCb(cbModSymCnt); + pfSymList = LpvAllocCb(cbSymCnt); + pfPropList = LpvAllocCb(cbPropCnt); + pfRefList = LpvAllocCb(cbRefCnt); + pfDefList = LpvAllocCb(cbDefCnt); + pfCalList = LpvAllocCb(cbCalCnt); + pfCbyList = LpvAllocCb(cbCbyCnt); + + for (i=0; i < MAXATOMPAGETBL; i++) { + AtomPageTbl[i].uPage = 0; + AtomPageTbl[i].pfAtomCache = LpvAllocCb(ATOMALLOC); + } + AtomPageTblMac = 0; // last cache page used + AtomPageTbl[0].uPage = 65535; + + // read data areas + + if (lastAtomPage == 0) + pagesize = lastAtomCnt; + else + pagesize = ATOMALLOC; + + GetBSC(lbModList, pfModList, cbModCnt); // Init Mod cache + GetBSC(lbModSymList, pfModSymList, cbModSymCnt); // Init ModSym cache + GetBSC(lbSymList, pfSymList, cbSymCnt); // Init Sym cache + GetBSC(lbPropList, pfPropList, cbPropCnt); // Init Prop cache + GetBSC(lbRefList, pfRefList, cbRefCnt); // Init Ref cache + GetBSC(lbDefList, pfDefList, cbDefCnt); // Init Def cache + GetBSC(lbCalList, pfCalList, cbCalCnt); // Init Cal cache + GetBSC(lbCbyList, pfCbyList, cbCbyCnt); // Init Cby cache + + GetAtomCache (0); // Init Atom cache + + return TRUE; +} + +VOID +InstallBSC() +// Install the currently open BSC into the mbrmake lists +// +{ + IDX iprop, imod, isym, idef, ical, icby, isbr, iFirstFileSym; + VA vaSym, vaProp, vaRef, vaFileSym, vaMod; + DWORD iref; + + PROPLIST prop, prop0; + MODLIST mod; + + DEF def; + CAL cal; + CBY cby; + VA *rgVaProp; // preallocated array of PROPs + VA *rgVaFileSym; // cached SYMs for the filenames + BYTE *rgFModUsed; // is this module used? + + SI *mpIsbrSi; + + rgVaProp = (VA *)LpvAllocCb(PropCnt * sizeof(VA)); + rgVaFileSym = (VA *)LpvAllocCb(ModCnt * sizeof(VA)); + rgFModUsed = (BYTE *)LpvAllocCb(ModCnt * sizeof(BYTE)); + + // make the SBR info for this BSC file + mpIsbrSi = LpsiCreate(); + + // this relies on the fact that all the SYMs for the files are together + // (they're after all the SYMs for the variables) + iFirstFileSym = bMOD(0).ModName; + + for (iprop = 0; iprop < PropCnt; iprop++) + rgVaProp[iprop] = VaAllocGrpCb(grpProp, sizeof(PROP)); + + for (imod = 0; imod < ModCnt; imod++) { + mod = bMOD(imod); + + vaCurMod = VaAllocGrpCb(grpMod, sizeof(MOD)); + + gMOD(vaCurMod); + cMOD.vaFirstModSym = vaNil; + cMOD.csyms = 0; + cMOD.vaNameSym = MbrAddAtom (LszNameFrIsym (mod.ModName), TRUE); + cMOD.vaNextMod = vaRootMod; + pMOD(vaCurMod); + + rgVaFileSym[imod] = cMOD.vaNameSym; + rgFModUsed[imod] = 0; + + vaRootMod = vaCurMod; + + if (Unknown == mod.ModName) { + vaUnknownSym = cMOD.vaNameSym; + vaUnknownMod = vaCurMod; + } + + gSYM(cMOD.vaNameSym).vaFirstProp = vaCurMod; // store ptr to MOD + pSYM(cMOD.vaNameSym); + } + + for (isym = 0; isym < SymCnt; isym++) { + + vaSym = MbrAddAtom(LszNameFrIsym(isym), FALSE); + + iprop = isym ? bSYM((IDX)(isym-1)).PropEnd : 0; + for (; iprop < bSYM(isym).PropEnd; iprop++) { + + prop = bPROP(iprop); + + if (iprop) + prop0 = bPROP((IDX)(iprop-1)); + else { + prop0.DefEnd = 0L; + prop0.RefEnd = 0; + prop0.CalEnd = 0; + prop0.CbyEnd = 0; + } + + // the properties were preallocated + vaProp = rgVaProp[iprop]; + + gSYM(vaSym); + if (cSYM.vaFirstProp == vaNil) + cSYM.vaFirstProp = vaProp; + else + cPROP.vaNextProp = vaProp; + + cSYM.cprop++; + pSYM(vaSym); + + gPROP(vaProp); + cPROP.vaNameSym = vaSym; + cPROP.sattr = prop.PropAttr; + + +#ifdef DEBUG +if (isym != prop.PropName) + printf("\t ERROR property points back to wrong symbol!\n"); // DEBUG +#endif + + for (idef = prop0.DefEnd; idef < prop.DefEnd; idef++) { + isbr = bDEF(idef).isbr; + + // this SBR file is being updated -- ignore incoming info + if (isbr == 0xffff || mpIsbrSi[isbr].fUpdate) continue; + + imod = bDEF(idef).RefNam - iFirstFileSym; + def.isbr = mpIsbrSi[isbr].isbr; + def.deflin = bDEF(idef).RefLin; + def.vaFileSym = rgVaFileSym[imod]; + + rgFModUsed[imod] = 1; + + VaAddList(&cPROP.vaDefList, &def, sizeof(def), grpDef); + } + + for (iref = prop0.RefEnd; iref < prop.RefEnd; iref++) { + isbr = bREF(iref).isbr; + + // this SBR file is being updated -- ignore incoming info + if (mpIsbrSi[isbr].fUpdate) continue; + + vaRef = VaAllocGrpCb(grpRef, sizeof(REF)); + + gREF(vaRef); + imod = bREF(iref).RefNam - iFirstFileSym; + cREF.isbr = mpIsbrSi[isbr].isbr; + cREF.reflin = bREF(iref).RefLin; + vaFileSym = rgVaFileSym[imod]; + + rgFModUsed[imod] = 1; + + MkVpVa(cREF.vpFileSym, vaFileSym); + + pREF(vaRef); + + AddTail (Ref, REF); + + cPROP.cref++; // count references + } + + for (ical = prop0.CalEnd; ical < prop.CalEnd; ical++) { + isbr = bCAL(ical).isbr; + + // this SBR file is being updated -- ignore incoming info + if (mpIsbrSi[isbr].fUpdate) continue; + + cal.isbr = mpIsbrSi[isbr].isbr; + cal.vaCalProp = rgVaProp[bCAL(ical).UseProp]; + cal.calcnt = bCAL(ical).UseCnt; + + VaAddList(&cPROP.vaCalList, &cal, sizeof(cal), grpCal); + } + + for (icby = prop0.CbyEnd; icby < prop.CbyEnd; icby++) { + isbr = bCBY(icby).isbr; + + // this SBR file is being updated -- ignore incoming info + if (mpIsbrSi[isbr].fUpdate) continue; + + cby.isbr = mpIsbrSi[isbr].isbr; + cby.vaCbyProp = rgVaProp[bCBY(icby).UseProp]; + cby.cbycnt = bCBY(icby).UseCnt; + + VaAddList(&cPROP.vaCbyList, &cby, sizeof(cby), grpCby); + } + + pPROP(vaProp); + } + } + + for (imod = 0; imod < ModCnt; imod++) { + vaMod = gSYM(rgVaFileSym[imod]).vaFirstProp; + gMOD(vaMod); + if (rgFModUsed[imod] == 0) { + cMOD.csyms = 1; // mark this MOD as empty + pMOD(vaMod); + } + } + + FreeLpv(mpIsbrSi); + FreeLpv(rgFModUsed); + FreeLpv(rgVaFileSym); + FreeLpv(rgVaProp); +} + +static LPSI +LpsiCreate() +// create the SBR info records for this .BSC file +// +{ + SI FAR *mpIsbrSi; + LSZ lszSbrName; + VA vaSbr; + WORD isbr, isbr2; + WORD fUpdate; + + // add the files that are current in the database to the list of .SBR files + // + lszSbrName = LpvAllocCb(PATH_BUF); + lseek(fhBSC, lbSbrList, SEEK_SET); + for (isbr = 0;;isbr++) { + GetBSCLsz(lszSbrName); + if (*lszSbrName == '\0') + break; + + vaSbr = VaSbrAdd(SBR_OLD, lszSbrName); + + cSBR.isbr = isbr; + pSBR(vaSbr); + } + FreeLpv(lszSbrName); + + mpIsbrSi = LpvAllocCb(SbrCnt * sizeof(SI)); + + // allocate and fill in the new table with the base numbers + // mark files that are staying and those that are going away + // number any new sbr files that we find while doing this. + + vaSbr = vaRootSbr; + while (vaSbr) { + gSBR(vaSbr); + + if (cSBR.isbr == (WORD)-1) { + cSBR.isbr = isbr++; + pSBR(vaSbr); + } + + if (cSBR.fUpdate == SBR_NEW) + Warning(WARN_SBR_TRUNC, cSBR.szName); + else if (cSBR.fUpdate & SBR_NEW) + fFoundSBR = TRUE; + + mpIsbrSi[cSBR.isbr].fUpdate = cSBR.fUpdate; + + vaSbr = cSBR.vaNextSbr; + } + + if (!fFoundSBR) { + // all SBR files were not in the database and were truncated. ERROR! + Error(ERR_ALL_SBR_TRUNC, ""); + } + + isbr2 = 0; + for (isbr = 0; isbr < SbrCnt; isbr++) { + fUpdate = mpIsbrSi[isbr].fUpdate; + + if (fUpdate & SBR_NEW) + mpIsbrSi[isbr].isbr = isbr2++; + else + mpIsbrSi[isbr].isbr = (WORD)-1; + + if ((fUpdate & SBR_UPDATE) || + (fUpdate & SBR_OLD) && (~fUpdate & SBR_NEW)) + mpIsbrSi[isbr].fUpdate = TRUE; + else + mpIsbrSi[isbr].fUpdate = FALSE; + + } + + return mpIsbrSi; +} + +VOID +NumberSBR() +// stub version of LpsiCreate --- call this if FOpenBSC fails to just +// assign new numbers to all the .sbr files that are in the list +// +{ + VA vaSbr; + WORD isbr; + + // number new sbr files + + vaSbr = vaRootSbr; + isbr = 0; + while (vaSbr) { + gSBR(vaSbr); + + #ifdef DEBUG + if (cSBR.isbr != (WORD)-1) { + printf("Non initialized SBR file encountered\n"); //DEBUG + } + #endif + + // if this file is truncated then and there is no + // old version of the file then emit a warning about the file + // and then an error stating that we are not in incremental mode + + if (cSBR.fUpdate == SBR_NEW) { + Warning(WARN_SBR_TRUNC, cSBR.szName); + Error(ERR_NO_INCREMENTAL, ""); + } + + cSBR.isbr = isbr++; + + pSBR(vaSbr); + + vaSbr = cSBR.vaNextSbr; + } +} diff --git a/private/utils/mep/browser/mbrmake/sbrproto.h b/private/utils/mep/browser/mbrmake/sbrproto.h new file mode 100644 index 000000000..bdeb8c1f6 --- /dev/null +++ b/private/utils/mep/browser/mbrmake/sbrproto.h @@ -0,0 +1,61 @@ +void SBRCorrupt(char *psz); +void FreeOrdList(void); +PVOID VaOrdFind(unsigned short ord); +PVOID VaOrdAdd(void); +BOOL FInExcList (LSZ lszName); +void InstallSBR(void); +void AddCalProp(VA vaCurProp); +void AddCbyProp(VA vaCurProp); +void AddRefProp(VA vaCurProp); +void AddDefProp(VA vaCurProp); +VA VaPropBestOfSym(VA vaSym); +VA VaPropAddToSym(VA vaCurSym); +void BldModSymList(void); +void CleanUp(void); +BOOL FWildMatch(char *pchPat, char *pchText); +void Error(int imsg,char *parg); +void Error2(int imsg,char achar,char *parg); +void Warning(int imsg,char *parg); +void Fatal(void); +void sigint(void); +char far *LszDup(char far *lsz); +char far *LszDupNewExt(char far *pname,char far *pext); +void AddExcludeFileList(char far *pname); +BOOL FValidHeader(void); +void _CRTAPI1 main(int argc,char * *argv); +void Usage(void); +long GetArgPosn(void); +void SetArgPosn(long lArgPosn); +char *NextArg(void); +char *ParseArgs(int argc,char * *argv); +void WriteBSC(char *OutputFileName); +void DebugDump(void); +void DebugDumpProp(VA vaProp); +void SeekError(char *pfilenm); +void ReadError(char *pfilenm); +void WriteError(char *pfilenm); +void FindTmp(char *pbuf); +char *MakTmpFileName(char *pext); +char far *LszBaseName(char far *lsz); +VA VaSearchModule(char *p); +VA VaSearchModuleExact(char *p); +VA VaSearchSymbol(char *pStr); +char far *GetAtomStr(VA vaSym); +PVOID MbrAddAtom(char *pStr,char fFILENM); +void SortAtoms(void); +int _CRTAPI1 CmpSym(VA *sym1, VA *sym2); +void CloseBSC(void); +BOOL FOpenBSC (LSZ lszName); +void InstallBSC(void); +void NumberSBR(void); +VA VaSbrAdd(unsigned short fUpdate,char far *lszName); +VA VaSbrFrName(char far *lszName); +char far *ToCanonPath(char far *lszPath,char far *lszCwd,char far *lszCanon); +void ToRelativePath(char far *lszPath,char far *lszCwd); +char far *ToAbsPath(char far *lszPath,char far *lszCwd); +void ToBackSlashes(char far *lsz); +void GetStr(char *buf); +unsigned char GetSBRRec(void); +void DecodeSBR(void); +// rjsa forfile (char far * pat, void (*rtn)(char far *)); + diff --git a/private/utils/mep/browser/mbrmake/sbrx.c b/private/utils/mep/browser/mbrmake/sbrx.c new file mode 100644 index 000000000..a2b670389 --- /dev/null +++ b/private/utils/mep/browser/mbrmake/sbrx.c @@ -0,0 +1,357 @@ +#define LINT_ARGS + +#include +#include +#include +#include +#include + +#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 _CRTAPI1 +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); +} + diff --git a/private/utils/mep/browser/mbrmake/sources b/private/utils/mep/browser/mbrmake/sources new file mode 100644 index 000000000..0d8a80c53 --- /dev/null +++ b/private/utils/mep/browser/mbrmake/sources @@ -0,0 +1,31 @@ +MAJORCOMP=sdktools +MINORCOMP=mbrmake + +TARGETNAME=mbrmake +TARGETPATH=obj +TARGETTYPE=LIBRARY + +INCLUDES=.;..\inc;\nt\private\sdktools\ztools\inc + +SOURCES= addtolst.c \ + convert.c \ + dcodesbr.c \ + getsbrec.c \ + list.c \ + mbrhash.c \ + ord.c \ + owner.c \ + mbrwbsc.c \ + readbsc.c \ + sbrx.c \ + vm.c + +UMAPPL=mbrmake + + +C_DEFINES=-D_OS2_20_=0 -DNO_EXT_KEYS -Dpascal= -Dfar= -DNOLANMAN -DNT +UMTYPE=console +UMLIBS= obj\*\mbrmake.lib \ + ..\bsc\obj\*\bsc.lib \ + \nt\private\sdktools\ztools\src\obj\*\ztools.lib \ + \nt\public\sdk\lib\*\user32.lib diff --git a/private/utils/mep/browser/mbrmake/vm.c b/private/utils/mep/browser/mbrmake/vm.c new file mode 100644 index 000000000..9c8e0bef5 --- /dev/null +++ b/private/utils/mep/browser/mbrmake/vm.c @@ -0,0 +1,197 @@ +// vm.c +// +// simple minded virtual memory implemenation + +// there is no code to do the OS2 version... + +#include +#include +#include +#include +#include +#include +#include +#if defined(OS2) +#define INCL_NOCOMMON +#define INCL_DOSPROCESS +#define INCL_DOSSEMAPHORES +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#define INCL_DOSMISC +#include +#else +#include +#endif + + +#include "hungary.h" +#include "vm.h" +#include "sbrproto.h" +#include "errors.h" + +#define CB_PAGE_SIZE 2048 // 4k pages +#define C_LOCKS_MAX 16 // up to 16 pages may be locked in ram +#define C_PAGES_MAX 8192 // up to 4k pages resident +#define C_FREE_LIST_MAX 256 // keep free lists for items up to 256 bytes +#define GRP_MAX 16 // max number of memory groups + +typedef WORD VPG; // virtual page number +typedef VA far *LPVA; // far pointer to VA + +// virtual address arithmetic +// +// #define VpgOfVa(va) ((WORD)((va>>12))) + +// this is really the same as the above but it assumes that the high byte +// of the long is all zero's and it is optimized for our C compiler + +#define VpgOfVa(va) ((((WORD)((BYTE)(va>>16)))<<4)|\ + (((BYTE)(((WORD)va)>>8))>>4)) + +#define OfsOfVa(va) ((WORD)((va) & 0x07ff)) +#define VaBaseOfVpg(vpg) (((DWORD)(vpg)) << 12) + +// phsyical page header +typedef struct _pg { + BYTE fDirty; // needs to be written out + BYTE cLocks; // this page is locked + VPG vpg; // what is the virtual page number of this page + struct _pg FAR *lppgNext; // LRU ordering next + struct _pg FAR *lppgPrev; // and prev +} PG; + +typedef PG FAR * LPPG; + +typedef struct _mem { + VA vaFree; + WORD cbFree; + VA mpCbVa[C_FREE_LIST_MAX]; +#ifdef SWAP_INFO + WORD cPages; +#endif +} MGI; // Memory Group Info + +static MGI mpGrpMgi[GRP_MAX]; + +// translation table -- map virtual page number to physical page address +static LPPG mpVpgLppg[C_PAGES_MAX]; + +// head and tail pointers for LRU +// +static LPPG near lppgHead; +static LPPG near lppgTail; + +// nil page pointer +// +#define lppgNil 0 + +// points to the start of linked lists of free blocks +// +static VA mpCbVa[C_FREE_LIST_MAX]; + +// these pages are locked in memory +// +static LPPG near rgLppgLocked[C_LOCKS_MAX]; + +// number of pages we have given out +static VPG near vpgMac; + +// number of physical pages we have resident +static WORD near cPages; + +// should we keep trying to allocate memory +static BOOL near fTryMemory = TRUE; + +// the file handle for the backing store +static int near fhVM; + +// the name of the file for the backing store +static LSZ near lszVM; + +#ifdef ASSERT + +#define Assert(x, sz) { if (!(x)) AssertionFailed(sz); } + +VOID +AssertionFailed(LSZ lsz) +// something went wrong... +// +{ + printf("assertion failure:%s\n", lsz); + Fatal(); +} + +#else + +#define Assert(x, y) + +#endif + + +LPV VM_API +LpvAllocCb(ULONG cb) +// allocate a block of far memory, if _fmalloc fails, the free some of +// the memory we were using for the VM cache +// +{ + LPV lpv; + + if (!(lpv = calloc(cb,1))) { + Error(ERR_OUT_OF_MEMORY, ""); + } + return lpv; +} + + +VA VM_API +VaAllocGrpCb(WORD grp, ULONG cb) +// allocate cb bytes from the requested memory group +// +{ + VA vaNew; + MGI FAR *lpMgi; + LPV lpv; + + lpMgi = &mpGrpMgi[grp]; + + Assert(grp < GRP_MAX, "Memory Group out of range"); + + if (cb < C_FREE_LIST_MAX && (vaNew = lpMgi->mpCbVa[cb])) { + lpv = LpvFromVa(vaNew, 0); + lpMgi->mpCbVa[cb] = *(LPVA)lpv; + memset(lpv, 0, cb); + DirtyVa(vaNew); + return vaNew; + } + + if (cb < mpGrpMgi[grp].cbFree) { + vaNew = mpGrpMgi[grp].vaFree; + (PBYTE)mpGrpMgi[grp].vaFree += cb; + mpGrpMgi[grp].cbFree -= cb; + } + else { + vaNew = VaAllocCb(CB_PAGE_SIZE - sizeof(PG)); + mpGrpMgi[grp].vaFree = (PBYTE)vaNew + cb; + mpGrpMgi[grp].cbFree = CB_PAGE_SIZE - cb - sizeof(PG); + } + + return vaNew; +} + +VOID VM_API +FreeGrpVa(WORD grp, VA va, ULONG cb) +// put this block on the free list for blocks of that size +// we don't remember how big the blocks were so the caller has +// provide that info +// +{ + MGI FAR *lpMgi; + + lpMgi = &mpGrpMgi[grp]; + + if (cb < C_FREE_LIST_MAX && cb >= 4 ) { + *(LPVA)LpvFromVa(va, 0) = lpMgi->mpCbVa[cb]; + DirtyVa(va); + lpMgi->mpCbVa[cb] = va; + } +} diff --git a/private/utils/mep/browser/mbrmake/vm.h b/private/utils/mep/browser/mbrmake/vm.h new file mode 100644 index 000000000..730ff627c --- /dev/null +++ b/private/utils/mep/browser/mbrmake/vm.h @@ -0,0 +1,67 @@ +// +// simple minded virtual memory system headers +// + +typedef PVOID VA; + +#define vaNil 0 + +#define VM_API pascal + + +#define InitVM() +#define CloseVM() +#define FreeVa(va,cb) (free((LPV)va)) +#define VaAllocCb(cb) ((VA)LpvAllocCb(cb)) +#define LpvFromVa(va, wLock) (LPV)(va) +#define DirtyVa(va) +#define UnlockW(w) +#define FreeLpv(lpv) (free(lpv)) + +typedef VA VP; + +#define MkVpVa(vp, va) ((vp) = (VP)va) +#define VaFrVp(vp) ((VA)(vp)) + + +LPV VM_API LpvAllocCb(ULONG cb); +VA VM_API VaAllocGrpCb(WORD grp, ULONG cb); +VOID VM_API FreeGrpVa(WORD grp, VA va, ULONG cb); + +#ifdef SWAP_INFO + +#define VM_MISC 0 +#define VM_SEARCH_DEF 1 +#define VM_ADD_DEF 2 +#define VM_SEARCH_REF 3 +#define VM_ADD_REF 4 +#define VM_SEARCH_CAL 5 +#define VM_ADD_CAL 6 +#define VM_SEARCH_CBY 7 +#define VM_ADD_CBY 8 +#define VM_SEARCH_ORD 9 +#define VM_ADD_ORD 10 +#define VM_SEARCH_PROP 11 +#define VM_ADD_PROP 12 +#define VM_SEARCH_SYM 13 +#define VM_ADD_SYM 14 +#define VM_SEARCH_MOD 15 +#define VM_ADD_MOD 16 +#define VM_SORT_ATOMS 17 +#define VM_FIX_UNDEFS 18 +#define VM_CLEAN_REFS 19 +#define VM_INDEX_TREE 20 +#define VM_BUILD_MODSYM 21 +#define VM_EMIT_ATOMS 22 +#define VM_EMIT_TREE 23 + +extern WORD near iVMClient; +extern WORD near iVMGrp; + +#define SetVMClient(x) (iVMClient = (x)) + +#else + +#define SetVMClient(x) + +#endif -- cgit v1.2.3