/*--------------------------------------------------------------------------- FILE : PLEX.C AUTHOR: STOLEN FROM EXCEL modified by NavPal This file contains routines used to manipulate the PL (pronounced: "plex") structures. ----------------------------------------------------------------------------*/ #include "priv.h" #pragma hdrstop #ifndef WINNT #include "plex.h" #include "debug.h" #endif /*----------------------------------------------------------------------- | FInRange | Simple little routine that tells you if a number lies within a | range. | | | Arguments: | w: Number to check | wFirst: First number in the range | wLast: Last number in the range | | Returns: | fTrue if the number is in range | | Keywords: in range check -----------------------------------------------------------------------*/ BOOL FInRange(w, wFirst, wLast) int w; int wFirst, wLast; { Assert(wLast >= wFirst); return(w >= wFirst && w <= wLast); } #ifdef DEBUG /*---------------------------------------------------------------------------- | FValidPl | | Checks for a valid PL structure. | | Arguments: | ppl PL to check | | Returns: | fTrue if the PL looks reasonable. ----------------------------------------------------------------------------*/ BOOL FValidPl(pvPl) VOID *pvPl; { #define ppl ((PL *)pvPl) if (ppl== NULL || ppl->cbItem == 0 || ppl->iMac < 0 || ppl->iMax < 0 || ppl->iMax < ppl->iMac) return(fFalse); return(fTrue); #undef ppl } #endif //DEBUG /*---------------------------------------------------------------------------- | CbPlAlloc | | Returns amount of memory allocated to the given PL | | Arguments: | ppl PL to return info for. | | Returns: | memory allocated to the PL ----------------------------------------------------------------------------*/ int CbPlAlloc(pvPl) VOID *pvPl; { #define ppl ((PL *)pvPl) if (ppl == NULL) return(0); #ifdef DEBUG Assert(FValidPl(ppl)); #endif // DEBUG return(WAlign(cbPL + (ppl->iMax * ppl->cbItem))); #undef ppl } /*---------------------------------------------------------------------------- | FreePpl | | Frees a PL. | | Arguments: | ppl PL to free | | Returns: | Nothing. ----------------------------------------------------------------------------*/ void FreePpl(pvPl) VOID *pvPl; { #ifdef DEBUG Assert(FValidPl(pvPl)); #endif // DEBUG VFreeMemP(pvPl, (unsigned) CbPlAlloc(pvPl)); } /*---------------------------------------------------------------------------- | PplAlloc | | Allocates and initializes a PL. | | Arguments: | cbItem sizeof structure in the PL | dAlloc number of items to allocate at a time | iMax number of items in initial allocation | | Returns: | Pointer to PL. | | Notes: | returns NULL if OOM ----------------------------------------------------------------------------*/ VOID *PplAlloc(cbItem, dAlloc, iMax) unsigned cbItem; int dAlloc; unsigned iMax; { PL *ppl; long cb; if (iMax > 32767) /* not too likely, but what the heck. */ return(NULL); Assert((cbItem>=1 && cbItem<=65535u) && FInRange(dAlloc, 1, 31)); cb = WAlign((long) cbPL + (long) cbItem * (long) iMax); ppl = (PL *)PvMemAlloc((unsigned) cb); if(ppl==NULL) return(NULL); FillBuf(ppl,0, (unsigned) cb); ppl->cbItem = cbItem; ppl->dAlloc = dAlloc; ppl->iMax = iMax; ppl->fUseCount = fFalse; #ifdef DEBUG Assert(FValidPl(ppl)); #endif // DEBUG return(ppl); } /*---------------------------------------------------------------------------- | IAddPl | | Adds an item to a PL. | | Arguments: | pppl Pointer to PL. May change if reallocated. | pv New item to add. | | Returns: | Index of new item. | | Notes: | returns -1 if OOM ----------------------------------------------------------------------------*/ int IAddPl(ppvPl, pv) VOID **ppvPl; VOID *pv; { int cbItem; int iMac; PL *ppl, *pplNew; ppl = *ppvPl; #ifdef DEBUG Assert(FValidPl(ppl)); #endif // DEBUG cbItem = ppl->cbItem; iMac = ppl->iMac; #ifdef UNUSED if (ppl->fUseCount) { int i; BYTE *pb; (*(int *)pv) = 1; // Search for an unused entry for (i = 0, pb = ppl->rg; i < iMac; i++, pb += cbItem) { if ((*(int *) pb) == 0) { bltbh(hpv, hpb, cbItem); return i; } } } #endif if (iMac == ppl->iMax) { pplNew = PplAlloc(cbItem, ppl->dAlloc, iMac + ppl->dAlloc); if(pplNew==NULL)//OOM return(-1); pplNew->fUseCount = ppl->fUseCount; PbMemCopy(pplNew->rg,ppl->rg, iMac * cbItem); /* pplNew->iMac = iMac; /* This is not needed because hppl->iMac will be over-written later */ FreePpl(ppl); *ppvPl = ppl = pplNew; } PbMemCopy(&ppl->rg[iMac * cbItem],pv,cbItem); ppl->iMac = iMac + 1; #ifdef DEBUG Assert(FValidPl(*ppvPl)); #endif // DEBUG return(iMac); } /*---------------------------------------------------------------------------- | RemovePl | | Removes an item from a PL. | | Arguments: | ppl PL to remove item from | i index of item to remove | | Returns: | fTrue if an item was removed (only fFalse for use count plexes). ----------------------------------------------------------------------------*/ BOOL RemovePl(pvPl, i) VOID *pvPl; int i; { int iMac; int cbItem; BYTE *p; #define ppl ((PL *)pvPl) #ifdef DEBUG Assert(FValidPl(ppl) && i < ppl->iMac); #endif // DEBUG iMac = ppl->iMac; cbItem = ppl->cbItem; p = &ppl->rg[i * cbItem]; #ifdef UNUSED if (ppl->fUseCount) { Assert((*(int HUGE *) hp) > 0); if (--(*(int HUGE *) hp) > 0) return fFalse; } #endif if (i != iMac - 1) { PbMemCopy(p,p+cbItem,(iMac - i - 1) * cbItem); } ppl->iMac = iMac - 1; #ifdef DEBUG Assert(FValidPl(ppl)); #endif // DEBUG return fTrue; #undef ppl } /*---------------------------------------------------------------------------- | ILookupPl | | Searches a PL for an item. | | Arguments: | ppl PL to lookup into | p item to lookup | pfnSgn Comparison function | | Returns: | index of item, if found. | -1 if not found. ----------------------------------------------------------------------------*/ int ILookupPl(pvPl, pvItem, pfnSgn) VOID *pvPl; VOID *pvItem; int (*pfnSgn)(); { int i; BYTE *p; #define ppl ((PL *)pvPl) if (ppl == NULL) return(-1); #ifdef DEBUG Assert(FValidPl(ppl)); #endif // DEBUG #ifdef UNUSED if (ppl->fUseCount) { for (i = 0, p = ppl->rg; i < ppl->iMac; i++, p += ppl->cbItem) { if (*(int *)p != 0 && (*(int (*)(void *,void *))pfnSgn)(p, pvItem) == sgnEQ) return(i); } } else #endif { for (i = 0, p = ppl->rg; i < ppl->iMac; i++, p += ppl->cbItem) { if ((*(int (*)(void *, void *))pfnSgn)(p, pvItem) == sgnEQ) return(i); } } return(-1); #undef ppl } /*---------------------------------------------------------------------------- | PLookupPl | | Searches a PL for an item | | Arguments: | ppl PL to search | pItem item to search for | pfnSgn comparison function | | Returns: | Pointer to item, if found | Null, if not found ----------------------------------------------------------------------------*/ VOID *PLookupPl(pvPl, pvItem, pfnSgn) VOID *pvPl; VOID *pvItem; int (*pfnSgn)(); { int i; if ((i = ILookupPl(pvPl, pvItem, pfnSgn)) == -1) return(NULL); return(&((PL *)pvPl)->rg[i * ((PL *)pvPl)->cbItem]); } /*---------------------------------------------------------------------------- | FLookupSortedPl | | Searches a sorted PL for an item. | | Arguments: | hppl PL to lookup into | hpItem Item to lookup | pi Index of found item (or insertion location if not) | pfnSgn Comparison function | | Returns: | index of item, if found. | index of location to insert if not found. ----------------------------------------------------------------------------*/ int FLookupSortedPl(hpvPl, hpvItem, pi, pfnSgn) VOID *hpvPl; VOID *hpvItem; int *pi; int (*pfnSgn)(); { int sgn; unsigned iMin, iMid, iMac; int cbItem; BYTE *hprg; BYTE *hpMid; #define hppl ((PL *)hpvPl) if ((hppl)==NULL) { *pi = 0; return(fFalse); } #ifdef DEBUG Assert(FValidPl(hppl)); #endif // DEBUG Assert(!hppl->fUseCount); sgn = 1; cbItem = hppl->cbItem; iMin = iMid = 0; iMac = hppl->iMac; hprg = hppl->rg; while (iMin != iMac) { iMid = iMin + (iMac-iMin)/2; Assert(iMid != iMac); hpMid = hprg + iMid*cbItem; if ((sgn = (*(int (*)(void *, void *))pfnSgn)(hpMid, hpvItem)) == 0) break; /* Too low, look in upper interval */ if (sgn < 0) iMin = ++iMid; /* Too high, look in lower interval */ else iMac = iMid; } /* Not found, return index of location to insert it */ *pi = iMid; return(sgn == 0); #undef hppl } /*---------------------------------------------------------------------------- | IAddNewPl | | Adds an item to a PL, creating the PL if it's initially NULL. | | Arguments: | phppl pointer to PL | hp pointer to item to add | cbItem size of item | | Returns: | the index of item added, if successful | -1, if out-of-memory ----------------------------------------------------------------------------*/ int IAddNewPl(phpvPl, hpv, cbItem) VOID **phpvPl; VOID *hpv; int cbItem; { int i; #define phppl ((PL **)phpvPl) Assert(((*phppl)==NULL) || !(*phppl)->fUseCount); i = -1; if ((*phppl)==NULL) { *phppl = PplAlloc(cbItem, 5, 5); } if((*phppl)!=NULL) { Assert((*phppl)->cbItem == cbItem); i = IAddPl((VOID **)phppl, hpv); } return(i); #undef phppl } /*---------------------------------------------------------------------------- | IAddNewPlPos | | Inserts an item into a plex at a specific position. | | Arguments: | the index of the item added, if successful | -1 if out-of-memory ----------------------------------------------------------------------------*/ int IAddNewPlPos(phpvPl, hpv, cbItem, i) VOID **phpvPl; VOID *hpv; int cbItem; int i; { BYTE *hpT; #define phppl ((PL **)phpvPl) Assert(((*phppl)==NULL) || !(*phppl)->fUseCount); if (IAddNewPl((VOID **)phppl, hpv, cbItem) == -1) return(-1); Assert(i < (*phppl)->iMac); hpT = &(*phppl)->rg[i * cbItem]; // bltbh(hpT, hpT + cbItem, ((*phppl)->iMac - i - 1) * cbItem); // bltbh(hpv, hpT, cbItem); PbMemCopy(hpT + cbItem, hpT, ((*phppl)->iMac - i - 1) * cbItem); PbMemCopy(hpT, hpv, cbItem); #ifdef DEBUG Assert(FValidPl(*phppl)); #endif // DEBUG return(i); #undef phppl } int IAddPlSort(phpvPl, hpv, pfnSgn) VOID **phpvPl; VOID *hpv; int (*pfnSgn)(); { int i; #ifdef DEBUG int iOld; #endif Assert((*phpvPl)!=NULL); if (FLookupSortedPl(*phpvPl, hpv, &i, pfnSgn)) return(-1); #ifdef DEBUG iOld = i; #endif i = IAddNewPlPos(phpvPl, hpv, (*(PL **)phpvPl)->cbItem, i); #ifdef DEBUG Assert(i == -1 || i == iOld); #endif return(i); } //--------------------------------------------------------------------------- //NO CHANGES BELOW THIS LINE PLEASE //--------------------------------------------------------------------------- #ifdef FROMEXCEL /*--------------------------------------------------------------------------- THIS CODE IS FROM EXCEL SOURCES. ITS KEPT HERE FOR REFERENCE ---------------------------------------------------------------------------*/ #pragma hdrstop("Excel.pre") VSZASSERT #include "new.h" /* This file contains routines used to manipulate the PL (pronounced: "plex") structures. They should probably be moved somewhere a little more appropriate, like maybe alloc.c */ /*---------------------------------------------------------------------------- | HpLookupPl | | Searches a PL for an item | | Arguments: | hppl PL to search | hpItem item to search for | pfnSgn comparison function | | Returns: | Pointer to item, if found | hpNull, if not found ----------------------------------------------------------------------------*/ VOID HUGE *HpLookupPl(hpvPl, hpvItem, pfnSgn) VOID HUGE *hpvPl; VOID HUGE *hpvItem; int (*pfnSgn)(); { int i; if ((i = ILookupPl(hpvPl, hpvItem, pfnSgn)) == -1) return(hpNull); return(&((PL HUGE *)hpvPl)->rg[i * ((PL HUGE *)hpvPl)->cbItem]); } #ifndef GRAF #ifdef MAC #pragma alloc_text(window, HpplAlloc) #else #pragma alloc_text(window2, HpplAlloc) #endif #else #pragma alloc_text(plgboot, HpplAlloc) #endif /*---------------------------------------------------------------------------- | HpplAlloc | | Allocates and initializes a PL. | | Arguments: | cbItem sizeof structure in the PL | dAlloc number of items to allocate at a time | iMax number of items in initial allocation | dg memory group to allocate from | | Returns: | Pointer to PL. | | Notes: | May DoJmp(penvMem). ----------------------------------------------------------------------------*/ /*< 32767) /* not too likely, but what the heck. */ DoJmp(penvMem, alctNoMem); Assert((cbItem>=1 && cbItem<=65535u) && FInRange(dAlloc, 1, 31) && FInRange(BLow(dg), 1, 255)); cb = WAlign((long) cbPL + (long) cbItem * (long) iMax); #ifndef LARGEALLOC if(cb >= cbHeapMax) { ErrorNoMem(); DoJmp(penvMem, alctNoMem); } #endif hppl = (PL HUGE *)HpAlloc((unsigned) cb, dg); bltcbh(0, hppl, (unsigned) cb); Assert(dg!=0); for (dgShift = 0; !(dg & 1); dg >>= 1, dgShift++) ; Assert(dgShift<8); hppl->cbItem = cbItem; hppl->dAlloc = dAlloc; hppl->iMax = iMax; hppl->fUseCount = fFalse; hppl->dgShift = dgShift; #ifdef DEBUG Assert(FValidPl(hppl)); #endif // DEBUG return(hppl); } #pragma NATIVE_END /*<fUseCount = fTrue; return hppl; } /*---------------------------------------------------------------------------- | FreeHppl | | Frees a PL. | | Arguments: | hppl PL to free | | Returns: | Nothing. ----------------------------------------------------------------------------*/ /*<fUseCount) { for (i = 0, hp = hppl->rg; i < hppl->iMac; i++, hp += hppl->cbItem) { if (*(int HUGE *)hp != 0 && (*(int (*)(HP, HP))pfnSgn)(hp, hpvItem) == sgnEQ) return(i); } } else { for (i = 0, hp = hppl->rg; i < hppl->iMac; i++, hp += hppl->cbItem) { if ((*(int (*)(HP, HP))pfnSgn)(hp, hpvItem) == sgnEQ) return(i); } } return(-1); #undef hppl } #pragma NATIVE_END /*---------------------------------------------------------------------------- | FLookupSortedPl | | Searches a sorted PL for an item. | | Arguments: | hppl PL to lookup into | hpItem Item to lookup | pi Index of found item (or insertion location if not) | pfnSgn Comparison function | | Returns: | index of item, if found. | index of location to insert if not found. ----------------------------------------------------------------------------*/ #ifdef MAC #pragma alloc_text(window, FLookupSortedPl) #else #pragma alloc_text(window2, FLookupSortedPl) #endif #pragma NATIVE_START int FLookupSortedPl(hpvPl, hpvItem, pi, pfnSgn) VOID HUGE *hpvPl; VOID HUGE *hpvItem; int *pi; int (*pfnSgn)(); { int sgn; unsigned iMin, iMid, iMac; int cbItem; BYTE HUGE *hprg; BYTE HUGE *hpMid; #define hppl ((PL HUGE *)hpvPl) if (SbFromHp(hppl) == sbNull) { *pi = 0; return(fFalse); } #ifdef DEBUG Assert(FValidPl(hppl)); #endif // DEBUG Assert(!hppl->fUseCount); sgn = 1; cbItem = hppl->cbItem; iMin = iMid = 0; iMac = hppl->iMac; hprg = hppl->rg; while (iMin != iMac) { iMid = iMin + (iMac-iMin)/2; Assert(iMid != iMac); hpMid = hprg + iMid*cbItem; if ((sgn = (*(int (*)(HP, HP))pfnSgn)(hpMid, hpvItem)) == 0) break; /* Too low, look in upper interval */ if (sgn < 0) iMin = ++iMid; /* Too high, look in lower interval */ else iMac = iMid; } /* Not found, return index of location to insert it */ *pi = iMid; return(sgn == 0); #undef hppl } #pragma NATIVE_END /*---------------------------------------------------------------------------- | DeletePl | | Removes an item from a PL. The resulting PL is compacted. | | Arguments: | phppl pointer to PL to remove item from | i index of item to remove | | Returns: | Nothing. ----------------------------------------------------------------------------*/ DeletePl(phpvPl, i) VOID HUGE **phpvPl; int i; { #ifdef DEBUG Assert(FValidPl(*phpvPl)); #endif // DEBUG RemovePl(*phpvPl, i); FCompactPl(phpvPl, (*(PL HUGE **)phpvPl)->iMac == 0); #ifdef DEBUG Assert(SbOfHp(*phpvPl) == sbNull || FValidPl(*phpvPl)); #endif // DEBUG } /*---------------------------------------------------------------------------- | RemovePl | | Removes an item from a PL. | | Arguments: | hppl PL to remove item from | i index of item to remove | | Returns: | fTrue if an item was removed (only fFalse for use count plexes). ----------------------------------------------------------------------------*/ BOOL RemovePl(hpvPl, i) VOID HUGE *hpvPl; int i; { int iMac; int cbItem; BYTE HUGE *hp; #define hppl ((PL HUGE *)hpvPl) #ifdef DEBUG Assert(FValidPl(hppl) && i < hppl->iMac); #endif // DEBUG iMac = hppl->iMac; cbItem = hppl->cbItem; hp = &hppl->rg[i * cbItem]; if (hppl->fUseCount) { Assert((*(int HUGE *) hp) > 0); if (--(*(int HUGE *) hp) > 0) return fFalse; } if (i != iMac - 1) { bltbh(hp + cbItem, hp, (iMac - i - 1) * cbItem); } hppl->iMac = iMac - 1; #ifdef DEBUG Assert(FValidPl(hppl)); #endif // DEBUG return fTrue; #undef hppl } #ifndef GRAF #ifdef MAC #pragma alloc_text(window, IAddPl) #else #pragma alloc_text(window2, IAddPl) #endif #else #pragma alloc_text(swpmisc, IAddPl) #endif /*---------------------------------------------------------------------------- | IAddPl | | Adds an item to a PL. | | Arguments: | phppl Pointer to PL. May change if reallocated. | hp New item to add. | | Returns: | Index of new item. | | Notes: | May DoJmp(penvMem) when reallocating. ----------------------------------------------------------------------------*/ /*<cbItem; iMac = hppl->iMac; if (hppl->fUseCount) { int i; BYTE HUGE *hpb; (*(int HUGE *)hpv) = 1; // Search for an unused entry for (i = 0, hpb = hppl->rg; i < iMac; i++, hpb += cbItem) { if ((*(int HUGE *) hpb) == 0) { bltbh(hpv, hpb, cbItem); return i; } } } #ifdef DEBUG if (iMac == hppl->iMax || fShakeMem) #else if (iMac == hppl->iMax) #endif { hpplNew = HpplAlloc(cbItem, hppl->dAlloc, iMac + hppl->dAlloc, 0x01<dgShift); hpplNew->fUseCount = hppl->fUseCount; bltbh(hppl->rg, hpplNew->rg, iMac * cbItem); /* hpplNew->iMac = iMac; /* This is not needed because hppl->iMac will be over-written later */ FreeHppl(hppl); *phpvPl = hppl = hpplNew; } bltbh(hpv, &hppl->rg[iMac * cbItem], cbItem); hppl->iMac = iMac + 1; #ifdef DEBUG Assert(FValidPl(*phpvPl)); #endif // DEBUG return(iMac); } #pragma NATIVE_END /*<fUseCount); if ((i = ILookupPl(*phpvPl, hpv, pfnSgn)) == -1) i = IAddPl(phpvPl, hpv); return(i); #undef phppl } #endif #endif #ifndef GRAF #ifdef MAC #pragma alloc_text(window, IAddNewPl) #else #pragma alloc_text(window2, IAddNewPl) #endif #endif /*---------------------------------------------------------------------------- | IAddNewPl | | Adds an item to a PL, creating the PL if it's initially NULL. | | Arguments: | phppl pointer to PL | hp pointer to item to add | cbItem size of item | dg data group to alloc plex in | | Returns: | the index of item added, if successful | -1, if out-of-memory ----------------------------------------------------------------------------*/ /*<fUseCount); i = -1; penvSav = penvMem; if (SetJmp(penvMem = &env) == 0) { if (SbOfHp(*phppl) == sbNull) { *phppl = HpplAlloc(cbItem, 5, 5, dg); #ifdef DEBUG /* Turn off shake mem in this case, since we don't accomplish any additional memory checking when we've just allocated the plex from scratch anyway. */ Assert(fShakeMem != 2); fShakeMemSav = fShakeMem; fShakeMem = FALSE; #endif /* DEBUG */ } Assert((*phppl)->cbItem == cbItem); i = IAddPl((VOID HUGE **)phppl, hpv); } penvMem = penvSav; #ifdef DEBUG if (fShakeMemSav != 2) fShakeMem = fShakeMemSav; #endif /* DEBUG */ return(i); #undef phppl } #pragma NATIVE_END /*<fUseCount); if (IAddNewPl((VOID HUGE **)phppl, hpv, cbItem, dg) == -1) return(-1); Assert(i < (*phppl)->iMac); hpT = &(*phppl)->rg[i * cbItem]; bltbh(hpT, hpT + cbItem, ((*phppl)->iMac - i - 1) * cbItem); bltbh(hpv, hpT, cbItem); #ifdef DEBUG Assert(FValidPl(*phppl)); #endif // DEBUG return(i); #undef phppl } #pragma NATIVE_END /*<cbItem, i, 1<<(*(PL HUGE **)phpvPl)->dgShift); Assert(i == -1 || i == iOld); return(i); } /*---------------------------------------------------------------------------- | FCompactPl | | Squeezes unused memory out of a PL | | Arguments: | phppl Plex to compact | fFull fTrue if maximal compaction should be made | | Returns: | fTrue if some memory was freed. ----------------------------------------------------------------------------*/ BOOL FCompactPl(phpvPl, fFull) VOID HUGE **phpvPl; BOOL fFull; { int iMac, cbItem, cbFree, dAlloc; BYTE HUGE *hp; PL HUGE *hppl = *phpvPl; BOOL fFreed = fFalse; if (SbOfHp(hppl) != sbNull) { #ifdef DEBUG Assert(FValidPl(hppl)); #endif // DEBUG if ((iMac = hppl->iMac) == 0 && fFull) { FreeHppl(hppl); fFreed = fTrue; *phpvPl = hpNull; } else { if (!fFull) { dAlloc = hppl->dAlloc; iMac = (iMac + dAlloc) / dAlloc * dAlloc; } hp = &hppl->rg[iMac * (cbItem = hppl->cbItem)]; if (IbOfHp(hp) & 1) { /* can't free on an odd boundary */ Assert((cbItem & 1) && (iMac & 1)); iMac++; hp += cbItem; } Assert((IbOfHp(hp) & 1) == 0); /* must free at least 4 bytes, and it had better be an even number */ if ((cbFree = WAlign((hppl->iMax - iMac) * cbItem)) >= 4) { CbChopHp(hp, cbFree); fFreed = fTrue; hppl->iMax = iMac; } } } #ifdef DEBUG Assert(SbOfHp(*phpvPl) == sbNull || FValidPl(*phpvPl)); #endif // DEBUG return(fFreed); } /*---------------------------------------------------------------------------- | CbPlAlloc | | Returns amount of memory allocated to the given PL | | Arguments: | hppl PL to return info for. | | Returns: | memory allocated to the PL ----------------------------------------------------------------------------*/ /*<iMax * hppl->cbItem))); #undef hppl } #pragma NATIVE_END /*<fUseCount); // NYI #ifdef DEBUG Assert(FValidPl(hppl)); #endif // DEBUG cbItem = hppl->cbItem; if (hppl->iMax < iMac) { iMax = (iMac / (int) hppl->dAlloc + 1) * hppl->dAlloc; *phppl = HpplAlloc(cbItem, hppl->dAlloc, iMax, 0x01<dgShift); #ifdef USECOUNTRESIZE (*phppl)->fUseCount = hppl->fUseCount; #endif if (iIns >= 0) { bltbh(hppl->rg, (*phppl)->rg, iIns * cbItem); bltbh(hppl->rg + iIns * cbItem, (*phppl)->rg + (iIns+(iMac-hppl->iMac)) * cbItem, (hppl->iMac-iIns) * cbItem); } else bltbh(hppl->rg, (*phppl)->rg, hppl->iMax * cbItem); FreeHppl(hppl); } else if (iIns >= 0) { bltbh(hppl->rg + iIns * hppl->cbItem, hppl->rg + (iIns+(iMac-hppl->iMac)) * cbItem, (hppl->iMac-iIns) * cbItem); } (*phppl)->iMac = iMac; #ifdef DEBUG Assert(FValidPl(*phppl)); #endif // DEBUG #undef phppl } #pragma NATIVE_END /*<iMac); return ++(*(int HUGE *)&hppl->rg[i*hppl->cbItem]); #undef hppl } #pragma NATIVE_START int IDecUseCountPl(hpvPl, i) VOID HUGE *hpvPl; int i; { #define hppl ((PL HUGE *)hpvPl) #ifdef DEBUG Assert(FValidPl(hppl)); #endif // DEBUG Assert(i < hppl->iMac); Assert((*(int HUGE *)&hppl->rg[i*hppl->cbItem]) != 0); return --(*(int HUGE *)&hppl->rg[i*hppl->cbItem]); #undef hppl } #pragma NATIVE_END int IAddUseCountPl(phpvPl, hpv) VOID HUGE **phpvPl; VOID HUGE *hpv; { BYTE HUGE *hpb; int cbItem; int i; int iMac; PL HUGE *hppl; hppl = *phpvPl; #ifdef DEBUG Assert(FValidPl(hppl)); #endif // DEBUG Assert(hppl->fUseCount); cbItem = hppl->cbItem; iMac = hppl->iMac; // Search for an unused entry for (i = 0, hpb = hppl->rg; i < iMac; i++, hpb += cbItem) { if ((*(int HUGE *) hpb) == 0) { bltbh(hpv, hpb, cbItem); (*(int HUGE *) hpb) = 1; return i; } } return IAddPl(phpvPl, hpv); } #ifdef DEBUG /*---------------------------------------------------------------------------- | FValidPl | | Checks for a valid PL structure. | | Arguments: | hppl PL to check | | Returns: | fTrue if the PL looks reasonable. ----------------------------------------------------------------------------*/ BOOL FValidPl(hpvPl) VOID HUGE *hpvPl; { #define hppl ((PL HUGE *)hpvPl) if (SbOfHp(hppl) == sbNull || hppl->cbItem == 0 || hppl->iMac < 0 || hppl->iMax < 0 || hppl->iMax < hppl->iMac) return(fFalse); return(fTrue); #undef hppl } #endif /*---------------------------------------------------------------------------- END OF THE CODE FROM EXCEL ----------------------------------------------------------------------------*/ #endif