summaryrefslogtreecommitdiffstats
path: root/private/utils/mep/browser
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/utils/mep/browser
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/utils/mep/browser')
-rw-r--r--private/utils/mep/browser/bsc/bsc.c734
-rw-r--r--private/utils/mep/browser/bsc/bscdump.c114
-rw-r--r--private/utils/mep/browser/bsc/calltree.c213
-rw-r--r--private/utils/mep/browser/bsc/dump.c99
-rw-r--r--private/utils/mep/browser/bsc/filter.c44
-rw-r--r--private/utils/mep/browser/bsc/format.c112
-rw-r--r--private/utils/mep/browser/bsc/listref.c185
-rw-r--r--private/utils/mep/browser/bsc/makefile6
-rw-r--r--private/utils/mep/browser/bsc/outline.c101
-rw-r--r--private/utils/mep/browser/bsc/printf.c114
-rw-r--r--private/utils/mep/browser/bsc/query.c575
-rw-r--r--private/utils/mep/browser/bsc/revtree.c198
-rw-r--r--private/utils/mep/browser/bsc/sources26
-rw-r--r--private/utils/mep/browser/bsc/stats.c96
-rw-r--r--private/utils/mep/browser/bsc/wild.c73
-rw-r--r--private/utils/mep/browser/bscdump/bscdump.c324
-rw-r--r--private/utils/mep/browser/bscdump/bscdump.h15
-rw-r--r--private/utils/mep/browser/bscdump/makefile6
-rw-r--r--private/utils/mep/browser/bscdump/sources21
-rw-r--r--private/utils/mep/browser/bscdump/thunk.c174
-rw-r--r--private/utils/mep/browser/dirs25
-rw-r--r--private/utils/mep/browser/inc/bsc.h228
-rw-r--r--private/utils/mep/browser/inc/bscsup.h106
-rw-r--r--private/utils/mep/browser/inc/hungary.h31
-rw-r--r--private/utils/mep/browser/inc/mbrcache.h7
-rw-r--r--private/utils/mep/browser/inc/sbrbsc.h43
-rw-r--r--private/utils/mep/browser/inc/sbrfdef.h65
-rw-r--r--private/utils/mep/browser/inc/sbrvers.h7
-rw-r--r--private/utils/mep/browser/mbrmake/addtolst.c1004
-rw-r--r--private/utils/mep/browser/mbrmake/casts.h22
-rw-r--r--private/utils/mep/browser/mbrmake/convert.c266
-rw-r--r--private/utils/mep/browser/mbrmake/dcodesbr.c148
-rw-r--r--private/utils/mep/browser/mbrmake/errors.h20
-rw-r--r--private/utils/mep/browser/mbrmake/extern.h83
-rw-r--r--private/utils/mep/browser/mbrmake/getsbrec.c165
-rw-r--r--private/utils/mep/browser/mbrmake/list.c284
-rw-r--r--private/utils/mep/browser/mbrmake/list.h41
-rw-r--r--private/utils/mep/browser/mbrmake/makefile6
-rw-r--r--private/utils/mep/browser/mbrmake/mbrhash.c41
-rw-r--r--private/utils/mep/browser/mbrmake/mbrmake.c756
-rw-r--r--private/utils/mep/browser/mbrmake/mbrmake.h246
-rw-r--r--private/utils/mep/browser/mbrmake/mbrwbsc.c782
-rw-r--r--private/utils/mep/browser/mbrmake/ord.c116
-rw-r--r--private/utils/mep/browser/mbrmake/owner.c76
-rw-r--r--private/utils/mep/browser/mbrmake/profile.h58
-rw-r--r--private/utils/mep/browser/mbrmake/readbsc.c790
-rw-r--r--private/utils/mep/browser/mbrmake/sbrproto.h61
-rw-r--r--private/utils/mep/browser/mbrmake/sbrx.c357
-rw-r--r--private/utils/mep/browser/mbrmake/sources31
-rw-r--r--private/utils/mep/browser/mbrmake/vm.c197
-rw-r--r--private/utils/mep/browser/mbrmake/vm.h67
51 files changed, 9359 insertions, 0 deletions
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 <C> 1988, Microsoft Corporation
+//
+// Revision History:
+//
+//
+
+#include <stdio.h>
+#include <io.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stddef.h>
+#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 <os2.h>
+#include <dos.h>
+#else
+#include <windows.h>
+#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 <string.h>
+#include <stdio.h>
+#if defined(OS2)
+#define INCL_NOCOMMON
+#define INCL_DOSPROCESS
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSFILEMGR
+#define INCL_DOSERRORS
+#define INCL_DOSMISC
+#include <os2.h>
+#else
+#include <windows.h>
+#endif
+
+#include <dos.h>
+
+#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 <stdio.h>
+#include <string.h>
+#if defined(OS2)
+#define INCL_NOCOMMON
+#define INCL_DOSPROCESS
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSFILEMGR
+#define INCL_DOSERRORS
+#define INCL_DOSMISC
+#include <os2.h>
+#else
+#include <windows.h>
+#endif
+
+#include <dos.h>
+
+
+#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("<Unknown>", 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 <string.h>
+#include <stdio.h>
+#if defined(OS2)
+#define INCL_NOCOMMON
+#define INCL_DOSPROCESS
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSFILEMGR
+#define INCL_DOSERRORS
+#define INCL_DOSMISC
+#include <os2.h>
+#else
+#include <windows.h>
+#endif
+
+#include <dos.h>
+
+#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<<i)) BSCPrintf (":%s", patrtab[i]);
+
+ BSCPrintf(")");
+}
+
+LSZ BSC_API
+LszTypInst(IINST iinst)
+// return the type string of a single inst
+//
+{
+ ISYM isym;
+ TYP typ;
+ ATR atr;
+
+ InstInfo(iinst, &isym, &typ, &atr);
+ return ptyptab[typ];
+}
diff --git a/private/utils/mep/browser/bsc/filter.c b/private/utils/mep/browser/bsc/filter.c
new file mode 100644
index 000000000..5f01c7b1a
--- /dev/null
+++ b/private/utils/mep/browser/bsc/filter.c
@@ -0,0 +1,44 @@
+
+// filter.c
+//
+#include <string.h>
+#if defined(OS2)
+#define INCL_NOCOMMON
+#define INCL_DOSPROCESS
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSFILEMGR
+#define INCL_DOSERRORS
+#define INCL_DOSMISC
+#include <os2.h>
+#else
+#include <windows.h>
+#endif
+
+#include <dos.h>
+
+#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 <string.h>
+#if defined(OS2)
+#define INCL_NOCOMMON
+#define INCL_DOSPROCESS
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSFILEMGR
+#define INCL_DOSERRORS
+#define INCL_DOSMISC
+#include <os2.h>
+#else
+#include <windows.h>
+#endif
+
+#include <dos.h>
+
+#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 <string.h>
+#if defined(OS2)
+#define INCL_NOCOMMON
+#define INCL_DOSPROCESS
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSFILEMGR
+#define INCL_DOSERRORS
+#define INCL_DOSMISC
+#include <os2.h>
+#else
+#include <windows.h>
+#endif
+
+#include <dos.h>
+
+#include "hungary.h"
+#include "bsc.h"
+#include "bscsup.h"
+
+#include <stdlib.h>
+
+// 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<l; i++) bufg[i] = '-';
+ for (; i < MaxSymLen+5; i++) bufg[i] = ' ';
+ l = i + strlen(lszUsers);
+ for (; i<l; i++) bufg[i] = '-';
+ bufg[i] = 0;
+ PutLine();
+
+ for (isym = 0; isym < isymMac; isym++)
+ ListRefSym (isym, mbf);
+
+ strcpy (bufg, " ");
+ PutLine();
+}
+
+static VOID
+ListRefSym (ISYM isym, MBF mbf)
+// list all the references associated with this symbol
+{
+ IINST iinst, iinstMac, iinstUby;
+ IUBY iuby, iubyMac;
+ WORD csym;
+ WORD icol = MaxSymLen+5;
+ WORD maxcol = 80 / (MaxSymLen+5)-1;
+ WORD cnt;
+
+ InstRangeOfSym(isym, &iinst, &iinstMac);
+
+ for ( ;iinst < iinstMac ; iinst++) {
+
+ if (!FInstFilter (iinst, mbf))
+ continue;
+
+ csym = 0;
+ strcpy (bufg, " ");
+ strcat (bufg, LszNameFrSym(isym));
+ strcat (bufg, ": ");
+
+ UbyRangeOfInst(iinst, &iuby, &iubyMac);
+
+ for ( ;iuby < iubyMac; iuby++) {
+ if (++csym > 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<icol; i++) bufg[i] = ' ';
+
+ bufg[icol] = 0;
+
+ if (fVar) {
+ if (cuse > 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 <string.h>
+#if defined(OS2)
+#define INCL_NOCOMMON
+#define INCL_DOSPROCESS
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSFILEMGR
+#define INCL_DOSERRORS
+#define INCL_DOSMISC
+#include <os2.h>
+#else
+#include <windows.h>
+#endif
+
+#include <dos.h>
+
+#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 <string.h>
+#include <io.h>
+#include <stdlib.h>
+#if defined(OS2)
+#define INCL_NOCOMMON
+#define INCL_DOSPROCESS
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSFILEMGR
+#define INCL_DOSERRORS
+#define INCL_DOSMISC
+#include <os2.h>
+#else
+#include <windows.h>
+#endif
+
+#include <dos.h>
+
+#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 <stddef.h>
+#include <string.h>
+#if defined(OS2)
+#define INCL_NOCOMMON
+#define INCL_DOSPROCESS
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSFILEMGR
+#define INCL_DOSERRORS
+#define INCL_DOSMISC
+#include <os2.h>
+#else
+#include <windows.h>
+#endif
+
+#include <dos.h>
+
+#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 <stdio.h>
+#include <string.h>
+#if defined(OS2)
+#define INCL_NOCOMMON
+#define INCL_DOSPROCESS
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSFILEMGR
+#define INCL_DOSERRORS
+#define INCL_DOSMISC
+#include <os2.h>
+#else
+#include <windows.h>
+#endif
+
+#include <dos.h>
+
+
+#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 <string.h>
+#include <stdio.h>
+#if defined(OS2)
+#define INCL_NOCOMMON
+#define INCL_DOSPROCESS
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSFILEMGR
+#define INCL_DOSERRORS
+#define INCL_DOSMISC
+#include <os2.h>
+#else
+#include <windows.h>
+#endif
+
+#include <dos.h>
+
+#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 <string.h>
+#if defined(OS2)
+#define INCL_NOCOMMON
+#define INCL_DOSPROCESS
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSFILEMGR
+#define INCL_DOSERRORS
+#define INCL_DOSMISC
+#include <os2.h>
+#else
+#include <windows.h>
+#endif
+
+#include <dos.h>
+
+#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 <stdio.h>
+#include <string.h>
+#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 <os2.h>
+#else
+#include <windows.h>
+#endif
+
+#include <dos.h>
+
+
+#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] <file> outline\n");
+ BSCPrintf(" -l[FVMT] List References\n");
+ BSCPrintf(" -u[FVMT] List Redundant definitions\n");
+ BSCPrintf(" -t <sym> Calltree <sym>\n");
+ BSCPrintf(" -b <sym> Backwards Calltree <sym>\n");
+ BSCPrintf(" -s Emit BSC stats\n");
+ BSCPrintf(" -r <sym> List all references to symbol\n");
+ BSCPrintf(" -d <sym> 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 <C> 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 <string.h>
+#include <stdio.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <io.h>
+#if defined(OS2)
+#define INCL_NOCOMMON
+#define INCL_DOSPROCESS
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSFILEMGR
+#define INCL_DOSERRORS
+#define INCL_DOSMISC
+#include <os2.h>
+#else
+#include <windows.h>
+#endif
+
+#include <dos.h>
+
+#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 <stdarg.h>
+
+#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 <ctype.h>
+
+// 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 ("<Unknown>", 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 <Unknown>
+//
+{
+ 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 <Unknown> 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 <string.h>
+#include <ctype.h>
+
+LSZ ToCanonPath(LSZ lszPath, LSZ lszCwd, LSZ lszCanon);
+VOID ToRelativePath(LSZ lszPath, LSZ lszCwd);
+VOID ToBackSlashes(LSZ lsz);
+
+#ifdef STANDALONE
+
+#include <stdio.h>
+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 <signal.h>
+#include <process.h>
+#include <direct.h>
+#include <stdlib.h>
+
+// get version.h from mb
+
+#include "..\..\inc\version.h"
+
+#include "sbrvers.h"
+#include "sbrfdef.h"
+#include "mbrmake.h"
+
+#include <sys\types.h>
+#include <sys\stat.h>
+#include <tools.h>
+
+// 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>] [@<file>] <.sbr>...\n\n");
+#else
+ printf("usage: mbrmake [-Emu] [-Ei ...] [-v] [-help] [-o <.BSC>] [@<file>] <.sbr>...\n\n");
+#endif
+ printf(" @<file> Get arguments from specified file\n");
+ printf(" /E... Exclude:\n");
+ printf(" s system files\n");
+ printf(" i <file> named include file <file>\n");
+ printf(" i ( <files> ) named include file list <files>\n");
+ printf(" m macro expanded symbols\n");
+ printf(" /I... Include:\n");
+ printf(" u unreferenced symbols\n");
+ printf(" /o <file> 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 <io.h>
+#include <fcntl.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <string.h>
+
+#if defined (OS2)
+#define INCL_NOCOMMON
+#define INCL_DOSPROCESS
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSFILEMGR
+#define INCL_DOSERRORS
+#define INCL_DOSMISC
+#include <os2.h>
+#else
+#include <windows.h>
+#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 <stdlib.h>
+#include <search.h>
+#include <ctype.h>
+
+#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<PORD_MAX; i++)
+ rgvaOrd[i] = vaNil;
+
+ vaOrdBase = vaOrdRoot;
+ vaOrdNext = (PBYTE)vaOrdRoot + sizeof(ORD);
+ cOrdFree = ORD_BLOCK - 1;
+}
+
+
+VA
+VaOrdFind (WORD ord)
+// search for the specified ord, return the corresponding PROP entry
+// return vaNil if not found
+//
+{
+ VA vaOrd;
+
+ SetVMClient(VM_SEARCH_ORD);
+
+ vaOrd = rgvaOrd[HASH_ORD(ord)];
+
+ while (vaOrd) {
+ if (ord == gORD(vaOrd).aliasord) {
+ SetVMClient(VM_MISC);
+ return(cORD.vaOrdProp);
+ }
+ else
+ vaOrd = cORD.vaNextOrd;
+ }
+
+ SetVMClient(VM_MISC);
+ return(vaNil);
+}
+
+VA
+VaOrdAdd()
+// Add the symbol ordinal to the alias list.
+//
+{
+ VA vaOrdNew;
+
+ SetVMClient(VM_ADD_ORD);
+
+ if (cOrdFree--) {
+ vaOrdNew = vaOrdNext;
+ vaOrdNext = (PBYTE)vaOrdNext + sizeof(ORD);
+ }
+ else if (vaOrdBase && gORD(vaOrdBase).vaNextOrd) {
+ // if there is an old allocated block that we can re-use, then do so
+ vaOrdBase = cORD.vaNextOrd;
+ vaOrdNew = (PBYTE)vaOrdBase + sizeof(ORD);
+ vaOrdNext = (PBYTE)vaOrdNew + sizeof(ORD);
+ cOrdFree = ORD_BLOCK - 2;
+ }
+ else {
+
+ // allocate a new block -- keep a backwards pointer in this block
+
+ vaOrdNew = VaAllocGrpCb(grpOrd, sizeof(ORD) * ORD_BLOCK);
+
+ if (!vaOrdRoot)
+ vaOrdRoot = vaOrdNew;
+
+ if (vaOrdBase) {
+ gORD(vaOrdBase);
+ cORD.vaNextOrd = vaOrdNew;
+ pORD(vaOrdBase);
+ }
+
+ vaOrdBase = vaOrdNew;
+ (PBYTE)vaOrdNew += sizeof(ORD);
+ vaOrdNext = (PBYTE)vaOrdNew + sizeof(ORD);
+ cOrdFree = ORD_BLOCK - 2;
+ }
+
+ gORD(vaOrdNew).aliasord = r_ordinal;
+ cORD.vaNextOrd = rgvaOrd[HASH_ORD(r_ordinal)];
+ rgvaOrd[HASH_ORD(r_ordinal)] = vaOrdNew;
+ pORD(vaOrdNew);
+
+ SetVMClient(VM_MISC);
+
+ return(vaOrdNew);
+}
diff --git a/private/utils/mep/browser/mbrmake/owner.c b/private/utils/mep/browser/mbrmake/owner.c
new file mode 100644
index 000000000..e3107640f
--- /dev/null
+++ b/private/utils/mep/browser/mbrmake/owner.c
@@ -0,0 +1,76 @@
+//
+// owner.c : this code manipulates the SBR records for keeping track of
+// what SBR file owns a particular DEF/REF
+//
+
+#include "mbrmake.h"
+
+VA near vaRootSbr; // head of SBR list
+VA near vaTailSbr; // tail of SBR list
+WORD near SbrCnt; // count of sbr files
+
+VA
+VaSbrAdd(WORD fUpdate, LSZ lszName)
+// add a new sbr entry to the list -- we promise that cSBR will be the
+// setup for the newly added vaSbr
+//
+{
+ WORD cb;
+ VA vaSbr;
+
+ vaSbr = vaRootSbr;
+
+ while (vaSbr) {
+ gSBR(vaSbr);
+ if (strcmpi(cSBR.szName, lszName) == 0) {
+ cSBR.fUpdate |= fUpdate;
+ pSBR(vaSbr);
+ return vaSbr;
+ }
+ vaSbr = cSBR.vaNextSbr;
+ }
+
+ cb = strlen(lszName);
+
+ vaSbr = VaAllocGrpCb(grpSbr, sizeof(SBR) + cb);
+
+ gSBR(vaSbr);
+ cSBR.vaNextSbr = vaNil;
+ cSBR.fUpdate |= fUpdate;
+ cSBR.isbr = -1;
+ strcpy(cSBR.szName, lszName);
+ pSBR(vaSbr);
+
+
+ if (vaTailSbr) {
+ gSBR(vaTailSbr);
+ cSBR.vaNextSbr = vaSbr;
+ pSBR(vaTailSbr);
+ }
+ else
+ vaRootSbr = vaSbr;
+ vaTailSbr = vaSbr;
+
+ gSBR(vaSbr);
+
+ SbrCnt++;
+ return vaSbr;
+}
+
+VA
+VaSbrFrName(LSZ lszName)
+// find the .sbr entry matching the given name
+//
+{
+ VA vaSbr;
+
+ vaSbr = vaRootSbr;
+
+ while (vaSbr) {
+ gSBR(vaSbr);
+ if (strcmp(cSBR.szName, lszName) == 0)
+ return vaSbr;
+ vaSbr = cSBR.vaNextSbr;
+ }
+ return vaNil;
+}
diff --git a/private/utils/mep/browser/mbrmake/profile.h b/private/utils/mep/browser/mbrmake/profile.h
new file mode 100644
index 000000000..b58ed84a6
--- /dev/null
+++ b/private/utils/mep/browser/mbrmake/profile.h
@@ -0,0 +1,58 @@
+/* profile.h - definitions for profile.dll */
+
+extern word far pascal PROFCLEAR (int);
+extern word far pascal PROFDUMP (int,FPC);
+extern word far pascal PROFFREE (int);
+extern word far pascal PROFINIT (int,FPC);
+extern word far pascal PROFOFF (int);
+extern word far pascal PROFON (int);
+
+#define PROF_SHIFT 2 /* Power of 2 profile granularity */
+
+#define MOD_NAME_SIZE 10 /* size of module name */
+
+/* Profile flags */
+#define PT_SYSTEM 0 /* select system profiling */
+#define PT_USER 1 /* select user profiling */
+
+#define PT_USEDD 2 /* tell PROFON to call profile DD */
+#define PT_USEKP 4 /* Do kernel-support profiling */
+#define PT_VERBOSE 8 /* Also collect detail kernel tics */
+#define PT_NODD 0 /* tell PROFON not to call profile DD */
+
+
+/* Profiling SCOPE
+* ---------------
+* PT_SYSTEM
+* Profile the ENTIRE system;
+* Exists for the use of tools like PSET, which gather data on
+* system behavior. Avoids need to write/modify test programs.
+*
+* PT_USER (i.e., PT_SYSTEM not specified)
+* Profile ONLY in the context of the calling process;
+* Exists to gather data on an individual program and those parts of
+* the system exercised by that program.
+*
+* Profiling Configuration
+* -----------------------
+* PT_USEDD
+* Call PROFILE device driver, if installed, on every timer tick.
+* Used by Presentation Manager "attributed" profiling, in
+* particular. Allows for arbitrary actions at "profile" time.
+*
+* PT_USEKP
+* Cause kernel to record profiling information;
+* These are the 4-byte granularity tick counts kept for each
+* code segment of interest. Making this optional allows one to
+* do PT_USEDD profiling without taking the memory hit of Kernel
+* Profiling.
+*
+* PT_VERBOSE
+* Collect detailed tick counts on KERNEL code segments;
+* Works only if PT_USEKP also specified. Generally useful
+* only for kernel programmers tuning the kernel.
+*
+*
+* The above flags can be used in any combination, with the exception
+* that PT_VERBOSE is allowed only if PT_USEKP is also specified.
+*/
diff --git a/private/utils/mep/browser/mbrmake/readbsc.c b/private/utils/mep/browser/mbrmake/readbsc.c
new file mode 100644
index 000000000..6cdd08eec
--- /dev/null
+++ b/private/utils/mep/browser/mbrmake/readbsc.c
@@ -0,0 +1,790 @@
+//
+// readbsc.c -- read in a .BSC file and install in mbrmake's vm space
+//
+// Copyright <C> 1988, Microsoft Corporation
+//
+// Revision History:
+//
+// 13-Aug-1989 rm Extracted from mbrapi.c
+//
+
+#define LINT_ARGS
+
+#include "mbrmake.h"
+
+#include <stddef.h>
+
+#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 <stdlib.h>
+#include <ctype.h>
+#include <search.h>
+#include <sys\types.h>
+#include <sys\stat.h>
+
+#include "mbrmake.h"
+
+#define LONGESTPATH 128
+
+#define SLASH "\\"
+#define SLASHCHAR '\\'
+#define XSLASHCHAR '/'
+
+WORD near cAtomsMac; // total number of atoms
+WORD near cModulesMac; // total number of modules
+WORD near cSymbolsMac; // total number of symbols
+
+static char *tmpl = "XXXXXX";
+
+extern WORD HashAtomStr (char *);
+
+// rjsa LPCH GetAtomStr (VA vaSym);
+
+void
+SeekError (char *pfilenm)
+// couldn't seek to position ... emit error message
+//
+{
+ Error(ERR_SEEK_FAILED, pfilenm);
+}
+
+void
+ReadError (char *pfilenm)
+// couldn't read from file... emit error message
+//
+{
+ Error(ERR_READ_FAILED, pfilenm);
+}
+
+void
+WriteError (char *pfilenm)
+// couldn't write to file ... emit error message
+//
+{
+ Error(ERR_WRITE_FAILED, pfilenm);
+}
+
+void
+FindTmp (char *pbuf) /* copy TMP path to pbuf if exists */
+//
+//
+{
+ char ebuf[LONGESTPATH];
+ char *env = ebuf;
+
+ *pbuf = '\0';
+ *env = '\0';
+
+// if (!(env = getenv("TMP")))
+ if (!(env = getenvOem("TMP")))
+ return; /* no path, return */
+
+// env = strncpy(ebuf, env, LONGESTPATH-1);
+ strncpy(ebuf, env, LONGESTPATH-1);
+ free( env );
+ env = ebuf;
+ ebuf[LONGESTPATH-1] = '\0';
+
+ if (!( env = ebuf ) )
+ return;
+
+ env = ebuf + strcspn(ebuf, ";");
+ if (*env == ';')
+ *env = '\0';
+
+ if (env != ebuf) {
+ env--;
+ if (*env != SLASHCHAR
+ && *env != XSLASHCHAR)
+ strcat(ebuf, SLASH);
+ }
+ strcpy (pbuf, ebuf);
+}
+
+
+char *
+MakTmpFileName (char *pext)
+// Create a temporary file with the extension supplied.
+// returns a pointer to the file name on the heap.
+//
+{
+ char ptmpnam[96];
+ char btmpl[7];
+ char *p;
+
+ strcpy (btmpl, tmpl);
+ p = mktemp(btmpl);
+ FindTmp (ptmpnam);
+ strcat (ptmpnam, p);
+ free (p);
+ strcat (ptmpnam, pext); /* /tmp/xxxxxx.ext file */
+ return (LszDup(ptmpnam));
+}
+
+LSZ
+LszBaseName (LSZ lsz)
+// return the base name part of a path
+//
+{
+ LPCH lpch;
+
+ lpch = strrchr(lsz, '\\');
+ if (lpch) return lpch+1;
+ if (lsz[1] == ':')
+ return lsz+2;
+
+ return lsz;
+}
+
+VA
+VaSearchModule (char *p)
+// search for the named module in the module list
+//
+{
+ VA vaMod;
+ LSZ lsz, lszBase;
+ char buf[PATH_BUF];
+
+ strcpy(buf, ToAbsPath(p, r_cwd));
+ lszBase = LszBaseName(buf);
+
+ SetVMClient(VM_SEARCH_MOD);
+
+ vaMod = vaRootMod;
+
+ while (vaMod) {
+ gMOD(vaMod);
+
+ lsz = GetAtomStr(cMOD.vaNameSym);
+
+ if (strcmpi(LszBaseName(lsz), lszBase) == 0 &&
+ strcmpi(buf,ToAbsPath(lsz, c_cwd)) == 0) {
+ SetVMClient(VM_MISC);
+ return (vaMod);
+ }
+ vaMod = cMOD.vaNextMod;
+ }
+ SetVMClient(VM_MISC);
+ return vaNil;
+}
+
+VA
+VaSearchModuleExact (char *p)
+// search for the named module in the module list -- EXACT match only
+//
+{
+ VA vaMod;
+
+ SetVMClient(VM_SEARCH_MOD);
+
+ vaMod = vaRootMod;
+
+ while (vaMod) {
+ gMOD(vaMod);
+
+ if (strcmp(p,GetAtomStr(cMOD.vaNameSym)) == 0) {
+ SetVMClient(VM_MISC);
+ return (vaMod);
+ }
+ vaMod = cMOD.vaNextMod;
+ }
+ SetVMClient(VM_MISC);
+ return vaNil;
+}
+
+VA
+VaSearchSymbol (char *pStr)
+// search for the named symbol (not a module!)
+//
+{
+ WORD hashid;
+ VA vaRootSym, vaSym;
+ LSZ lszAtom;
+
+ SetVMClient(VM_SEARCH_SYM);
+
+ vaRootSym = rgVaSym[hashid = HashAtomStr (pStr)];
+
+ if (vaRootSym) {
+ vaSym = vaRootSym;
+ while (vaSym) {
+
+ gSYM(vaSym);
+ lszAtom = gTEXT(cSYM.vaNameText);
+
+ if (strcmp (pStr, lszAtom) == 0) {
+ SetVMClient(VM_MISC);
+ return (vaSym); // Duplicate entry
+ }
+
+ vaSym = cSYM.vaNextSym; // current = next
+ }
+ }
+
+ SetVMClient(VM_MISC);
+ return vaNil;
+}
+
+LPCH
+GetAtomStr (VA vaSym)
+// Swap in the Atom page for the symbol chain entry pSym
+// Return the atom's address in the page.
+//
+{
+ gSYM(vaSym);
+ return gTEXT(cSYM.vaNameText);
+}
+
+VA
+MbrAddAtom (char *pStr, char fFILENM)
+// create a new symbol with the given name
+//
+{
+ WORD hashid;
+ VA vaSym, vaSymRoot, vaText;
+
+ if (!fFILENM)
+ vaSymRoot = rgVaSym[hashid = HashAtomStr (pStr)];
+ else
+ vaSymRoot = rgVaSym[hashid = MAXSYMPTRTBLSIZ - 1];
+
+ SetVMClient(VM_SEARCH_SYM);
+
+ if (vaSymRoot) {
+ vaSym = vaSymRoot;
+ while (vaSym) {
+ gSYM(vaSym);
+
+ if (!strcmp (pStr, GetAtomStr(vaSym))) {
+ #if defined (DEBUG)
+ if (OptD & 2)
+ printf("MbrAddAtom: duplicate (%s)\n", pStr);
+ #endif
+ SetVMClient(VM_SEARCH_SYM);
+ return (vaSym); // Duplicate entry
+ }
+
+ vaSym = cSYM.vaNextSym; // current = next
+ }
+ }
+
+ // we are now going to have to add the symbol
+
+
+ if (fFILENM) {
+ SetVMClient(VM_ADD_MOD);
+ cModulesMac++;
+ }
+ else {
+ SetVMClient(VM_ADD_SYM);
+ cSymbolsMac++;
+ }
+
+ cAtomsMac++;
+
+ vaSym = VaAllocGrpCb(grpSym, sizeof(SYM));
+ vaText = VaAllocGrpCb(grpText, strlen(pStr) + 1);
+
+ gSYM(vaSym);
+ cSYM.vaNameText = vaText;
+ cSYM.vaNextSym = rgVaSym[hashid];
+ pSYM(vaSym);
+
+ rgVaSym[hashid] = vaSym;
+
+ strcpy(gTEXT(vaText), pStr);
+
+ pTEXT(vaText);
+
+ SetVMClient(VM_MISC);
+
+ return (vaSym);
+}
+
+VA FAR * near rgvaSymSorted;
+
+// rjsa int CmpSym(VA FAR *lhsym1, VA FAR *lhsym2);
+
+void
+SortAtoms ()
+// create the "subscript sort" array pointers rgvaSymSorted
+//
+{
+ VA vaSym;
+ char buf[PATH_BUF];
+ WORD i, iSym;
+
+ SetVMClient(VM_SORT_ATOMS);
+
+ rgvaSymSorted = (VA FAR *)LpvAllocCb(cAtomsMac * sizeof(VA));
+
+ iSym = 0;
+ for (i=0; i < MAXSYMPTRTBLSIZ; i++) {
+ vaSym = rgVaSym[i];
+ while (vaSym) {
+ gSYM(vaSym);
+ rgvaSymSorted[iSym] = cSYM.vaNameText;
+ vaSym = cSYM.vaNextSym;
+ iSym++;
+ }
+ }
+
+ // sort symbols
+ qsort(rgvaSymSorted, cSymbolsMac, sizeof(VA), CmpSym);
+
+ // the files are in the last hash bucket so they went to the
+ // end of this array we just made -- we sort them separately
+
+ // sort files
+ qsort(rgvaSymSorted + cSymbolsMac, cModulesMac, sizeof(VA), CmpSym);
+
+ // convert the Page/Atom values back to virtual symbol addresses
+ for (i=0; i < cSymbolsMac; i++) {
+ strcpy(buf, gTEXT(rgvaSymSorted[i]));
+ rgvaSymSorted[i] = VaSearchSymbol(buf);
+ }
+
+ for (; i < cAtomsMac; i++) {
+ strcpy(buf, gTEXT(rgvaSymSorted[i]));
+#ifdef DEBUG
+ if (OptD & 64) printf("Module: %s\n", buf);
+#endif
+ rgvaSymSorted[i] = (VaSearchModuleExact(buf), cMOD.vaNameSym);
+ }
+}
+
+int _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 <stdio.h>
+#include <fcntl.h>
+#include <io.h>
+#include <sys\types.h>
+#include <sys\stat.h>
+#include <malloc.h>
+#include <string.h>
+#if defined(OS2)
+#define INCL_NOCOMMON
+#define INCL_DOSPROCESS
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSFILEMGR
+#define INCL_DOSERRORS
+#define INCL_DOSMISC
+#include <os2.h>
+#else
+#include <windows.h>
+#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