Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

790 lines
21 KiB

  1. //
  2. // readbsc.c -- read in a .BSC file and install in mbrmake's vm space
  3. //
  4. // Copyright <C> 1988, Microsoft Corporation
  5. //
  6. // Revision History:
  7. //
  8. // 13-Aug-1989 rm Extracted from mbrapi.c
  9. //
  10. #define LINT_ARGS
  11. #include "mbrmake.h"
  12. #include <stddef.h>
  13. #include "mbrcache.h"
  14. #include "sbrfdef.h" // sbr attributes
  15. #include "sbrbsc.h"
  16. typedef struct _sbrinfo {
  17. WORD fUpdate;
  18. WORD isbr;
  19. } SI, far *LPSI; // sbr info
  20. #define LISTALLOC 50 // Browser max list size
  21. typedef WORD IDX;
  22. // these will be initialized by the reading of the .bsc file
  23. //
  24. // fCase; TRUE for case compare
  25. // MaxSymLen; longest symbol length
  26. // ModCnt; count of modules
  27. // SbrCnt; count of sbr files
  28. // vaUnknownSym; unknown symbol
  29. // vaUnknownMod; unknown module
  30. //
  31. // static data
  32. static BOOL fIncremental; // update will be incremental
  33. static BOOL fFoundSBR; // at least .sbr file matched
  34. static int fhBSC = 0; // .BSC file handle
  35. static IDX Unknown; // UNKNOWN symbol index
  36. static WORD ModSymCnt; // count of modsyms
  37. static WORD SymCnt; // count of symbols
  38. static WORD PropCnt; // count of properties
  39. static DWORD RefCnt; // count of references
  40. static WORD DefCnt; // count of definitions
  41. static WORD CalCnt; // count of calls
  42. static WORD CbyCnt; // count of called bys
  43. static WORD lastAtomPage; // last atom page #
  44. static WORD lastAtomCnt; // last atom page size
  45. static WORD cbModSymCnt; // size of list of modsyms
  46. static WORD cbSymCnt; // size of list of symbols
  47. static WORD cbPropCnt; // size of list of properties
  48. static WORD cbRefCnt; // size of list of references
  49. static WORD cbDefCnt; // size of list of definitions
  50. static WORD cbCalCnt; // size of list of calls
  51. static WORD cbCbyCnt; // size of list of called bys
  52. static WORD MaxModSymCnt; // max list of modsyms
  53. static WORD MaxSymCnt; // max list of symbols
  54. static WORD MaxPropCnt; // max list of properties
  55. static WORD MaxRefCnt; // max list of references
  56. static WORD MaxDefCnt; // max list of definitions
  57. static WORD MaxCalCnt; // max list of calls
  58. static WORD MaxCbyCnt; // max list of called bys
  59. static DWORD lbModSymList; // modsym list file start
  60. static DWORD lbSymList; // symbol list file start
  61. static DWORD lbPropList; // property list file start
  62. static DWORD lbRefList; // reference list file start
  63. static DWORD lbDefList; // defintion list file start
  64. static DWORD lbCalList; // call list file start
  65. static DWORD lbCbyList; // called by list file start
  66. static DWORD lbSbrList; // sbr list file start
  67. static DWORD lbAtomCache; // atom cache file start
  68. static WORD CurModSymPage = 0; // Current page of modsyms
  69. static WORD CurSymPage = 0; // Current page of symbols
  70. static WORD CurPropPage = 0; // Current page of properties
  71. static WORD CurRefPage = 0; // Current page of references
  72. static WORD CurDefPage = 0; // Current page of defintions
  73. static WORD CurCalPage = 0; // Current page of calls
  74. static WORD CurCbyPage = 0; // Current page of called bys
  75. static LSZ lszBSCName = NULL; // name of .bsc file
  76. static MODLIST far *pfModList; // module list cache start
  77. static MODSYMLIST far *pfModSymList; // modsym list cache start
  78. static SYMLIST far *pfSymList; // symbol list cache start
  79. static PROPLIST far *pfPropList; // property list cache start
  80. static REFLIST far *pfRefList; // reference list cache start
  81. static REFLIST far *pfDefList; // def'n list cache start
  82. static USELIST far *pfCalList; // calls list cache start
  83. static USELIST far *pfCbyList; // call bys list cache start
  84. static WORD AtomPageTblMac; // last cache page used
  85. static CACHEPAGE AtomPageTbl[MAXATOMPAGETBL]; // Atom Cache table
  86. #define bMOD(imod) (pfModList[imod])
  87. #define bMODSYM(isym) (pfModSymList[ModSymPAGE(isym)])
  88. #define bSYM(isym) (pfSymList[SymPAGE(isym)])
  89. #define bPROP(iprop) (pfPropList[PropPAGE(iprop)])
  90. #define bREF(iref) (pfRefList[RefPAGE(iref)])
  91. #define bDEF(idef) (pfDefList[DefPAGE(idef)])
  92. #define bCAL(iuse) (pfCalList[CalPAGE(iuse)])
  93. #define bCBY(iuse) (pfCbyList[CbyPAGE(iuse)])
  94. #define bUSE(iuse) (pfCalList[CalPAGE(iuse)])
  95. #define bUBY(iuse) (pfCbyList[CbyPAGE(iuse)])
  96. #define BSCIn(v) ReadBSC(&v, sizeof(v))
  97. // prototypes
  98. //
  99. static VOID GetBSCLsz(LSZ lsz);
  100. static VOID GetBSC (DWORD lpos, LPV lpv, WORD cb);
  101. static VOID ReadBSC(LPV lpv, WORD cb);
  102. static IDX SwapPAGE (DWORD, LPV, WORD, WORD, WORD *, DWORD);
  103. static LPCH GetAtomCache (WORD);
  104. static WORD ModSymPAGE(WORD idx);
  105. static WORD SymPAGE(WORD idx);
  106. static WORD PropPAGE(WORD idx);
  107. static WORD RefPAGE(DWORD idx);
  108. static WORD DefPAGE(WORD idx);
  109. static WORD CalPAGE(WORD idx);
  110. static WORD CbyPAGE(WORD idx);
  111. static LSZ LszNameFrIsym(WORD isym);
  112. static LPSI LpsiCreate(VOID);
  113. static VOID
  114. GetBSCLsz(LSZ lsz)
  115. // read a null terminated string from the current position in the BSC file
  116. //
  117. {
  118. for (;;) {
  119. if (read(fhBSC, lsz, 1) != 1)
  120. ReadError(lszBSCName);
  121. if (*lsz++ == 0) return;
  122. }
  123. }
  124. static VOID
  125. ReadBSC(LPV lpv, WORD cb)
  126. // read a block of data from the BSC file
  127. //
  128. // the requested number of bytes MUST be present
  129. //
  130. {
  131. if (read(fhBSC, lpv, cb) != (int)cb)
  132. ReadError(lszBSCName);
  133. }
  134. static VOID
  135. GetBSC(DWORD lpos, LPV lpv, WORD cb)
  136. // Read a block of the specified size from the specified position
  137. //
  138. // we have to be tolerant of EOF here because the swapper might ask
  139. // for a whole block when only block when only part of a block is actually
  140. // is actually present
  141. //
  142. {
  143. if (lseek(fhBSC, lpos, SEEK_SET) == -1)
  144. SeekError(lszBSCName);
  145. if (read(fhBSC, lpv, cb) == -1)
  146. ReadError(lszBSCName);
  147. }
  148. static IDX
  149. SwapPAGE (DWORD lbuflist, LPV pfTABLE, WORD tblsiz,
  150. /* */ WORD lstsiz, WORD * pcurpage, DWORD idx)
  151. // SwapPAGE - Swap in the table page for the table pfTABLE[idx]
  152. // and return the table's new index in the page.
  153. {
  154. WORD page;
  155. IDX newidx;
  156. page = (WORD)(idx / lstsiz);
  157. newidx = (WORD)(idx % lstsiz);
  158. if (page == *pcurpage)
  159. return newidx;
  160. GetBSC(lbuflist+((long)tblsiz*(long)page), pfTABLE, tblsiz);
  161. *pcurpage = page;
  162. return newidx;
  163. }
  164. static IDX
  165. ModSymPAGE (IDX idx)
  166. // Swap in the ModSym page for ModSym[idx]
  167. // return the ModSym's index in the page.
  168. //
  169. {
  170. return SwapPAGE (lbModSymList, pfModSymList,
  171. cbModSymCnt, MaxModSymCnt, &CurModSymPage, (DWORD)idx);
  172. }
  173. static IDX
  174. SymPAGE (IDX idx)
  175. // Swap in the Symbol page for symbol[idx]
  176. // return the Symbol's index in the page.
  177. //
  178. {
  179. return SwapPAGE (lbSymList, pfSymList,
  180. cbSymCnt, MaxSymCnt, &CurSymPage, (DWORD)idx);
  181. }
  182. static IDX
  183. PropPAGE (IDX idx)
  184. // Swap in the Property page for Property[idx]
  185. // return the Property's index in the page.
  186. //
  187. {
  188. return SwapPAGE (lbPropList, pfPropList,
  189. cbPropCnt, MaxPropCnt, &CurPropPage, (DWORD)idx);
  190. }
  191. static IDX
  192. RefPAGE (DWORD idx)
  193. // Swap in the Reference page for Reference[idx] (ref/def)
  194. // return the Reference's index in the page.
  195. //
  196. {
  197. return SwapPAGE (lbRefList, pfRefList,
  198. cbRefCnt, MaxRefCnt, &CurRefPage, idx);
  199. }
  200. static IDX
  201. DefPAGE (IDX idx)
  202. // Swap in the Reference page for Defintions[idx] (ref/def)
  203. // return the Reference's index in the page.
  204. //
  205. {
  206. return SwapPAGE (lbDefList, pfDefList,
  207. cbDefCnt, MaxDefCnt, &CurDefPage, (DWORD)idx);
  208. }
  209. static IDX
  210. CalPAGE (IDX idx)
  211. // Swap in the Usage page for Usage[idx] (cal/cby)
  212. // and return the Usage's index in the page.
  213. //
  214. {
  215. return SwapPAGE (lbCalList, pfCalList,
  216. cbCalCnt, MaxCalCnt, &CurCalPage, (DWORD)idx);
  217. }
  218. static IDX
  219. CbyPAGE (IDX idx)
  220. // Swap in the Usage page for Usage[idx] (cal/cby)
  221. // and return the Usage's index in the page.
  222. //
  223. {
  224. return SwapPAGE (lbCbyList, pfCbyList,
  225. cbCbyCnt, MaxCbyCnt, &CurCbyPage, (DWORD)idx);
  226. }
  227. static LPCH
  228. GetAtomCache (WORD Page)
  229. // load the requested page into the cache
  230. //
  231. {
  232. WORD ipg;
  233. WORD pagesize;
  234. LPCH pfAtomCsave;
  235. for (ipg = 0; ipg < AtomPageTblMac; ipg++) {
  236. if (AtomPageTbl[ipg].uPage == Page)
  237. return AtomPageTbl[ipg].pfAtomCache;
  238. }
  239. if (ipg == AtomPageTblMac && ipg != MAXATOMPAGETBL)
  240. AtomPageTblMac++;
  241. pfAtomCsave = AtomPageTbl[MAXATOMPAGETBL-1].pfAtomCache;
  242. for (ipg = MAXATOMPAGETBL-1; ipg; ipg--)
  243. AtomPageTbl[ipg] = AtomPageTbl[ipg-1]; // move up
  244. AtomPageTbl[0].pfAtomCache = pfAtomCsave;
  245. AtomPageTbl[0].uPage = Page;
  246. if (Page == lastAtomPage)
  247. pagesize = lastAtomCnt;
  248. else
  249. pagesize = ATOMALLOC;
  250. GetBSC(lbAtomCache+ATOMALLOC*(long)Page,
  251. AtomPageTbl[0].pfAtomCache, pagesize);
  252. return AtomPageTbl[0].pfAtomCache;
  253. }
  254. static LSZ
  255. LszNameFrIsym (IDX isym)
  256. // Swap in the Atom page for the symbol isym
  257. // return the atom's address in the page.
  258. //
  259. {
  260. SYMLIST sym;
  261. sym = bSYM(isym);
  262. return GetAtomCache (sym.Page) + sym.Atom;
  263. }
  264. VOID
  265. CloseBSC()
  266. // close database and free as much memory as possible
  267. // return TRUE iff successful.
  268. //
  269. {
  270. int i;
  271. if (fhBSC) { // if open then close, & free memory
  272. FreeLpv (pfModList); // module table
  273. FreeLpv (pfModSymList); // modsym table
  274. FreeLpv (pfSymList); // symbol table
  275. FreeLpv (pfPropList); // property table
  276. FreeLpv (pfRefList); // reference table
  277. FreeLpv (pfDefList); // definition table
  278. FreeLpv (pfCalList); // call table
  279. FreeLpv (pfCbyList); // called by table
  280. for (i=0; i < MAXATOMPAGETBL; i++)
  281. FreeLpv (AtomPageTbl[i].pfAtomCache); // dispose Atom Cache
  282. close (fhBSC);
  283. }
  284. }
  285. BOOL
  286. FOpenBSC (LSZ lszName)
  287. // Open the specified data base.
  288. // Allocate buffers for cache areas
  289. // Initialize the data cache from the data base.
  290. //
  291. // Return TRUE iff successful, FALSE if database can't be read
  292. //
  293. {
  294. int i;
  295. WORD pagesize;
  296. BYTE MajorVer; // .bsc version (major)
  297. BYTE MinorVer; // .bsc version (minor)
  298. BYTE UpdatVer; // .bsc version (updat)
  299. WORD MaxModCnt; // max list of modules
  300. WORD cbModCnt; // size of list of modules
  301. DWORD lbModList; // module list file start
  302. lszBSCName = lszName;
  303. fhBSC = open(lszBSCName, O_BINARY|O_RDONLY);
  304. // if the .bsc file doesn't exist then we don't do any work
  305. // this is the cold compile case
  306. //
  307. if (fhBSC == -1)
  308. return FALSE;
  309. // read and check BSC version (major, minor and update)
  310. BSCIn(MajorVer);
  311. BSCIn(MinorVer);
  312. BSCIn(UpdatVer);
  313. #ifdef DEBUG
  314. printf("Browser Data Base: %s ver %d.%d.%d\n\n",
  315. lszBSCName, MajorVer, MinorVer, UpdatVer);
  316. #endif
  317. if ((MajorVer != BSC_MAJ) ||
  318. (MinorVer != BSC_MIN) ||
  319. (UpdatVer != BSC_UPD))
  320. return FALSE;
  321. // we will be attempting an incremental update
  322. fIncremental = TRUE;
  323. // read Case sense switch, max symbol length and Unknown module id
  324. BSCIn(fCase);
  325. BSCIn(MaxSymLen);
  326. BSCIn(Unknown);
  327. // read counts (sizes) of each data area
  328. BSCIn(ModCnt);
  329. BSCIn(ModSymCnt);
  330. BSCIn(SymCnt);
  331. BSCIn(PropCnt);
  332. BSCIn(RefCnt);
  333. BSCIn(DefCnt);
  334. BSCIn(CalCnt);
  335. BSCIn(CbyCnt);
  336. BSCIn(lastAtomPage);
  337. BSCIn(lastAtomCnt);
  338. // read BSC data area offsets
  339. BSCIn(lbModList);
  340. BSCIn(lbModSymList);
  341. BSCIn(lbSymList);
  342. BSCIn(lbPropList);
  343. BSCIn(lbRefList);
  344. BSCIn(lbDefList);
  345. BSCIn(lbCalList);
  346. BSCIn(lbCbyList);
  347. BSCIn(lbAtomCache);
  348. BSCIn(lbSbrList);
  349. // determine data cache area sizes
  350. #define MIN(a,b) ((a)>(b) ? (b) : (a))
  351. MaxModCnt = ModCnt; // max list of modules
  352. MaxModSymCnt = MIN(ModSymCnt , LISTALLOC); // max list of modsyms
  353. MaxSymCnt = MIN(SymCnt+ModCnt, LISTALLOC); // max list of symbols
  354. MaxPropCnt = MIN(PropCnt , LISTALLOC); // max list of props
  355. MaxRefCnt = (WORD)MIN(RefCnt, (long)LISTALLOC); // max list of refs
  356. MaxDefCnt = MIN(DefCnt , LISTALLOC); // max list of defs
  357. MaxCalCnt = MIN(CalCnt , LISTALLOC); // max list of cals
  358. MaxCbyCnt = MIN(CbyCnt , LISTALLOC); // max list of cbys
  359. cbModCnt = sizeof (MODLIST) * MaxModCnt; // size of mods list
  360. cbModSymCnt = sizeof (MODSYMLIST) * MaxModSymCnt; // size of modsyms list
  361. cbSymCnt = sizeof (SYMLIST) * MaxSymCnt; // size of syms list
  362. cbPropCnt = sizeof (PROPLIST) * MaxPropCnt; // size of props list
  363. cbRefCnt = sizeof (REFLIST) * MaxRefCnt; // size of refs list
  364. cbDefCnt = sizeof (REFLIST) * MaxDefCnt; // size of defs list
  365. cbCalCnt = sizeof (USELIST) * MaxCalCnt; // size of cals list
  366. cbCbyCnt = sizeof (USELIST) * MaxCbyCnt; // size of cbys list
  367. // Allocate data cache
  368. pfModList = LpvAllocCb(cbModCnt);
  369. pfModSymList = LpvAllocCb(cbModSymCnt);
  370. pfSymList = LpvAllocCb(cbSymCnt);
  371. pfPropList = LpvAllocCb(cbPropCnt);
  372. pfRefList = LpvAllocCb(cbRefCnt);
  373. pfDefList = LpvAllocCb(cbDefCnt);
  374. pfCalList = LpvAllocCb(cbCalCnt);
  375. pfCbyList = LpvAllocCb(cbCbyCnt);
  376. for (i=0; i < MAXATOMPAGETBL; i++) {
  377. AtomPageTbl[i].uPage = 0;
  378. AtomPageTbl[i].pfAtomCache = LpvAllocCb(ATOMALLOC);
  379. }
  380. AtomPageTblMac = 0; // last cache page used
  381. AtomPageTbl[0].uPage = 65535;
  382. // read data areas
  383. if (lastAtomPage == 0)
  384. pagesize = lastAtomCnt;
  385. else
  386. pagesize = ATOMALLOC;
  387. GetBSC(lbModList, pfModList, cbModCnt); // Init Mod cache
  388. GetBSC(lbModSymList, pfModSymList, cbModSymCnt); // Init ModSym cache
  389. GetBSC(lbSymList, pfSymList, cbSymCnt); // Init Sym cache
  390. GetBSC(lbPropList, pfPropList, cbPropCnt); // Init Prop cache
  391. GetBSC(lbRefList, pfRefList, cbRefCnt); // Init Ref cache
  392. GetBSC(lbDefList, pfDefList, cbDefCnt); // Init Def cache
  393. GetBSC(lbCalList, pfCalList, cbCalCnt); // Init Cal cache
  394. GetBSC(lbCbyList, pfCbyList, cbCbyCnt); // Init Cby cache
  395. GetAtomCache (0); // Init Atom cache
  396. return TRUE;
  397. }
  398. VOID
  399. InstallBSC()
  400. // Install the currently open BSC into the mbrmake lists
  401. //
  402. {
  403. IDX iprop, imod, isym, idef, ical, icby, isbr, iFirstFileSym;
  404. VA vaSym, vaProp, vaRef, vaFileSym, vaMod;
  405. DWORD iref;
  406. PROPLIST prop, prop0;
  407. MODLIST mod;
  408. DEF def;
  409. CAL cal;
  410. CBY cby;
  411. VA *rgVaProp; // preallocated array of PROPs
  412. VA *rgVaFileSym; // cached SYMs for the filenames
  413. BYTE *rgFModUsed; // is this module used?
  414. SI *mpIsbrSi;
  415. rgVaProp = (VA *)LpvAllocCb(PropCnt * sizeof(VA));
  416. rgVaFileSym = (VA *)LpvAllocCb(ModCnt * sizeof(VA));
  417. rgFModUsed = (BYTE *)LpvAllocCb(ModCnt * sizeof(BYTE));
  418. // make the SBR info for this BSC file
  419. mpIsbrSi = LpsiCreate();
  420. // this relies on the fact that all the SYMs for the files are together
  421. // (they're after all the SYMs for the variables)
  422. iFirstFileSym = bMOD(0).ModName;
  423. for (iprop = 0; iprop < PropCnt; iprop++)
  424. rgVaProp[iprop] = VaAllocGrpCb(grpProp, sizeof(PROP));
  425. for (imod = 0; imod < ModCnt; imod++) {
  426. mod = bMOD(imod);
  427. vaCurMod = VaAllocGrpCb(grpMod, sizeof(MOD));
  428. gMOD(vaCurMod);
  429. cMOD.vaFirstModSym = vaNil;
  430. cMOD.csyms = 0;
  431. cMOD.vaNameSym = MbrAddAtom (LszNameFrIsym (mod.ModName), TRUE);
  432. cMOD.vaNextMod = vaRootMod;
  433. pMOD(vaCurMod);
  434. rgVaFileSym[imod] = cMOD.vaNameSym;
  435. rgFModUsed[imod] = 0;
  436. vaRootMod = vaCurMod;
  437. if (Unknown == mod.ModName) {
  438. vaUnknownSym = cMOD.vaNameSym;
  439. vaUnknownMod = vaCurMod;
  440. }
  441. gSYM(cMOD.vaNameSym).vaFirstProp = vaCurMod; // store ptr to MOD
  442. pSYM(cMOD.vaNameSym);
  443. }
  444. for (isym = 0; isym < SymCnt; isym++) {
  445. vaSym = MbrAddAtom(LszNameFrIsym(isym), FALSE);
  446. iprop = isym ? bSYM((IDX)(isym-1)).PropEnd : 0;
  447. for (; iprop < bSYM(isym).PropEnd; iprop++) {
  448. prop = bPROP(iprop);
  449. if (iprop)
  450. prop0 = bPROP((IDX)(iprop-1));
  451. else {
  452. prop0.DefEnd = 0L;
  453. prop0.RefEnd = 0;
  454. prop0.CalEnd = 0;
  455. prop0.CbyEnd = 0;
  456. }
  457. // the properties were preallocated
  458. vaProp = rgVaProp[iprop];
  459. gSYM(vaSym);
  460. if (cSYM.vaFirstProp == vaNil)
  461. cSYM.vaFirstProp = vaProp;
  462. else
  463. cPROP.vaNextProp = vaProp;
  464. cSYM.cprop++;
  465. pSYM(vaSym);
  466. gPROP(vaProp);
  467. cPROP.vaNameSym = vaSym;
  468. cPROP.sattr = prop.PropAttr;
  469. #ifdef DEBUG
  470. if (isym != prop.PropName)
  471. printf("\t ERROR property points back to wrong symbol!\n"); // DEBUG
  472. #endif
  473. for (idef = prop0.DefEnd; idef < prop.DefEnd; idef++) {
  474. isbr = bDEF(idef).isbr;
  475. // this SBR file is being updated -- ignore incoming info
  476. if (isbr == 0xffff || mpIsbrSi[isbr].fUpdate) continue;
  477. imod = bDEF(idef).RefNam - iFirstFileSym;
  478. def.isbr = mpIsbrSi[isbr].isbr;
  479. def.deflin = bDEF(idef).RefLin;
  480. def.vaFileSym = rgVaFileSym[imod];
  481. rgFModUsed[imod] = 1;
  482. VaAddList(&cPROP.vaDefList, &def, sizeof(def), grpDef);
  483. }
  484. for (iref = prop0.RefEnd; iref < prop.RefEnd; iref++) {
  485. isbr = bREF(iref).isbr;
  486. // this SBR file is being updated -- ignore incoming info
  487. if (mpIsbrSi[isbr].fUpdate) continue;
  488. vaRef = VaAllocGrpCb(grpRef, sizeof(REF));
  489. gREF(vaRef);
  490. imod = bREF(iref).RefNam - iFirstFileSym;
  491. cREF.isbr = mpIsbrSi[isbr].isbr;
  492. cREF.reflin = bREF(iref).RefLin;
  493. vaFileSym = rgVaFileSym[imod];
  494. rgFModUsed[imod] = 1;
  495. MkVpVa(cREF.vpFileSym, vaFileSym);
  496. pREF(vaRef);
  497. AddTail (Ref, REF);
  498. cPROP.cref++; // count references
  499. }
  500. for (ical = prop0.CalEnd; ical < prop.CalEnd; ical++) {
  501. isbr = bCAL(ical).isbr;
  502. // this SBR file is being updated -- ignore incoming info
  503. if (mpIsbrSi[isbr].fUpdate) continue;
  504. cal.isbr = mpIsbrSi[isbr].isbr;
  505. cal.vaCalProp = rgVaProp[bCAL(ical).UseProp];
  506. cal.calcnt = bCAL(ical).UseCnt;
  507. VaAddList(&cPROP.vaCalList, &cal, sizeof(cal), grpCal);
  508. }
  509. for (icby = prop0.CbyEnd; icby < prop.CbyEnd; icby++) {
  510. isbr = bCBY(icby).isbr;
  511. // this SBR file is being updated -- ignore incoming info
  512. if (mpIsbrSi[isbr].fUpdate) continue;
  513. cby.isbr = mpIsbrSi[isbr].isbr;
  514. cby.vaCbyProp = rgVaProp[bCBY(icby).UseProp];
  515. cby.cbycnt = bCBY(icby).UseCnt;
  516. VaAddList(&cPROP.vaCbyList, &cby, sizeof(cby), grpCby);
  517. }
  518. pPROP(vaProp);
  519. }
  520. }
  521. for (imod = 0; imod < ModCnt; imod++) {
  522. vaMod = gSYM(rgVaFileSym[imod]).vaFirstProp;
  523. gMOD(vaMod);
  524. if (rgFModUsed[imod] == 0) {
  525. cMOD.csyms = 1; // mark this MOD as empty
  526. pMOD(vaMod);
  527. }
  528. }
  529. FreeLpv(mpIsbrSi);
  530. FreeLpv(rgFModUsed);
  531. FreeLpv(rgVaFileSym);
  532. FreeLpv(rgVaProp);
  533. }
  534. static LPSI
  535. LpsiCreate()
  536. // create the SBR info records for this .BSC file
  537. //
  538. {
  539. SI FAR *mpIsbrSi;
  540. LSZ lszSbrName;
  541. VA vaSbr;
  542. WORD isbr, isbr2;
  543. WORD fUpdate;
  544. // add the files that are current in the database to the list of .SBR files
  545. //
  546. lszSbrName = LpvAllocCb(PATH_BUF);
  547. lseek(fhBSC, lbSbrList, SEEK_SET);
  548. for (isbr = 0;;isbr++) {
  549. GetBSCLsz(lszSbrName);
  550. if (*lszSbrName == '\0')
  551. break;
  552. vaSbr = VaSbrAdd(SBR_OLD, lszSbrName);
  553. cSBR.isbr = isbr;
  554. pSBR(vaSbr);
  555. }
  556. FreeLpv(lszSbrName);
  557. mpIsbrSi = LpvAllocCb(SbrCnt * sizeof(SI));
  558. // allocate and fill in the new table with the base numbers
  559. // mark files that are staying and those that are going away
  560. // number any new sbr files that we find while doing this.
  561. vaSbr = vaRootSbr;
  562. while (vaSbr) {
  563. gSBR(vaSbr);
  564. if (cSBR.isbr == (WORD)-1) {
  565. cSBR.isbr = isbr++;
  566. pSBR(vaSbr);
  567. }
  568. if (cSBR.fUpdate == SBR_NEW)
  569. Warning(WARN_SBR_TRUNC, cSBR.szName);
  570. else if (cSBR.fUpdate & SBR_NEW)
  571. fFoundSBR = TRUE;
  572. mpIsbrSi[cSBR.isbr].fUpdate = cSBR.fUpdate;
  573. vaSbr = cSBR.vaNextSbr;
  574. }
  575. if (!fFoundSBR) {
  576. // all SBR files were not in the database and were truncated. ERROR!
  577. Error(ERR_ALL_SBR_TRUNC, "");
  578. }
  579. isbr2 = 0;
  580. for (isbr = 0; isbr < SbrCnt; isbr++) {
  581. fUpdate = mpIsbrSi[isbr].fUpdate;
  582. if (fUpdate & SBR_NEW)
  583. mpIsbrSi[isbr].isbr = isbr2++;
  584. else
  585. mpIsbrSi[isbr].isbr = (WORD)-1;
  586. if ((fUpdate & SBR_UPDATE) ||
  587. (fUpdate & SBR_OLD) && (~fUpdate & SBR_NEW))
  588. mpIsbrSi[isbr].fUpdate = TRUE;
  589. else
  590. mpIsbrSi[isbr].fUpdate = FALSE;
  591. }
  592. return mpIsbrSi;
  593. }
  594. VOID
  595. NumberSBR()
  596. // stub version of LpsiCreate --- call this if FOpenBSC fails to just
  597. // assign new numbers to all the .sbr files that are in the list
  598. //
  599. {
  600. VA vaSbr;
  601. WORD isbr;
  602. // number new sbr files
  603. vaSbr = vaRootSbr;
  604. isbr = 0;
  605. while (vaSbr) {
  606. gSBR(vaSbr);
  607. #ifdef DEBUG
  608. if (cSBR.isbr != (WORD)-1) {
  609. printf("Non initialized SBR file encountered\n"); //DEBUG
  610. }
  611. #endif
  612. // if this file is truncated then and there is no
  613. // old version of the file then emit a warning about the file
  614. // and then an error stating that we are not in incremental mode
  615. if (cSBR.fUpdate == SBR_NEW) {
  616. Warning(WARN_SBR_TRUNC, cSBR.szName);
  617. Error(ERR_NO_INCREMENTAL, "");
  618. }
  619. cSBR.isbr = isbr++;
  620. pSBR(vaSbr);
  621. vaSbr = cSBR.vaNextSbr;
  622. }
  623. }