#include #include #include #include #include "extract.h" /* * ERROR MESSAGES */ char errFarMemory[] = "Error: Out of far memory. Current used: %lud bytes\n"; char errNearMemory[] = "Error: Out of near memory. Current used: %u bytes\n"; char errRealloc[] = "\t(Attempting to realloc %u bytes to %u bytes)\n"; /* * Keeps count of how much memory has been used by system. */ WORD wNearMemoryUsed = 0; DWORD dwFarMemoryUsed = 0L; #if 0 LPSTR FarMalloc(int size, BOOL fZero) { LPSTR fp; fp = _fmalloc(size); if (fp == 0L) { fprintf(stderr, errFarMemory, dwFarMemoryUsed); exit(2); } dwFarMemoryUsed += (DWORD) size; if (fZero) lmemzero(fp, size); return fp; } void FarFree(LPSTR lpblock) { WORD size; size = _fmsize(lpblock); dwFarMemoryUsed -= (DWORD) size; _ffree(lpblock); } #endif #ifdef HEAPDEBUG void NearHeapCheck() { char foo[5]; switch (_nheapchk()) { case _HEAPOK: return; case _HEAPEMPTY: fprintf(stderr, "Non-Initted heap\n"); return; case _HEAPBADBEGIN: fprintf(stderr, "NearHeapCheck: BAD BEGIN!\n"); break; case _HEAPBADNODE: fprintf(stderr, "NearHeapCheck: BAD NODE!\n"); break; } fprintf(stderr, "BOGUS HEAP DETECTED!!!!, BREAK HERE!\n"); gets(foo); } #endif /* * @doc EXTRACT * @api PSTR | NearMalloc | Allocate a near memory buffer. * @parm WORD | size | Specifies the size in bytes of the block to be * allocated. * @parm BOOL | fZero | Specifies whether to zero initialize the * allocated buffer. * * @rdesc Returns a near pointer to the new buffer. * * @comm If the requested amount of memory can not be allocated, an * error message is displayed on stderr, and the program exited. If * memory allocation is successful, the count of near memory currently * allocated is updated to reflect the new block. * */ PSTR NearMalloc(WORD size, BOOL fZero) { PSTR pstr; #ifdef HEAPDEBUG NearHeapCheck(); #endif pstr = _nmalloc(size); if (!pstr) { fprintf(stderr, errNearMemory, wNearMemoryUsed); exit(2); } wNearMemoryUsed += size; if (fZero) memset(pstr, '\0', size); return pstr; } /* * @doc EXTRACT * @api PSTR | NearRealloc | Change the size of a dynamically * allocated near memory block. * * @parm PSTR | pblock | Specifies the old memory block that is to be * resized. * @parm WORD | newsize | Specifies the requested new size in bytes of * the reallocated block. * * @rdesc Returns a pointer to the new memory block, with size as * specified by

. The block contents will be indentical to * the contents of

up to the smaller of the old size and new * size. This pointer may be different from

. * * @comm If the requested amount of memory cannot be allocated, an * error message is displayed on stderr and the program exited. If * memory allocation is successful, the count of near memory currently * allocated is updated to reflect the new size of

. * */ PSTR NearRealloc(PSTR pblock, WORD newsize) { WORD oldsize; PSTR pnew; #ifdef HEAPDEBUG NearHeapCheck(); #endif oldsize = _nmsize(pblock); // dprintf("(Attempting to realloc %u bytes to %u bytes)\n", oldsize, newsize); pnew = realloc(pblock, newsize); if (!pnew) { fprintf(stderr, errNearMemory, wNearMemoryUsed); fprintf(stderr, errRealloc, oldsize, newsize); exit(2); } wNearMemoryUsed += (newsize - oldsize); #ifdef HEAPDEBUG NearHeapCheck(); #endif return pnew; } /* * @doc EXTRACT * @api void | NearFree | Frees a block of dynamically allocated near * memory. * @parm PSTR | pblock | Specifies the block to be freed. * * @comm The pointer

should not be referenced again after * calling this function, as the memory may be re-used by subsequent * calls to , , or . * * The count of near memory currently allocated is updated to reflect * the freed block. * */ void NearFree(PSTR pblock) { WORD size; #ifdef HEAPDEBUG NearHeapCheck(); #endif size = (WORD) _nmsize(pblock); wNearMemoryUsed -= size; _nfree(pblock); #ifdef HEAPDEBUG NearHeapCheck(); #endif } /* * @doc EXTRACT * @api WORD | NearSize | Returns the size in bytes of a near block * allocated using or . * * @parm PSTR | pblock | Specifies the block to return the size of. * * @rdesc Returns the size in bytes of

. * * @xref NearMalloc, StringAlloc, NearFree * */ WORD NearSize(PSTR pblock) { #ifdef HEAPDEBUG NearHeapCheck(); #endif return (WORD) _nmsize(pblock); } /* * @doc EXTRACT * @api PSTR | StringAlloc | Allocates near memory and copies a * string into it. * * @parm PSTR | string | Specifies the null-terminated string to * preserve. * * @rdesc Returns a near pointer to an allocated memory block * containing a copy of string

. * * @comm This function uses to allocate the memory * buffer that is returned. This buffer must be freed with * when it is no longer needed. * */ PSTR StringAlloc(PSTR string) { PSTR pstr; WORD size; #ifdef HEAPDEBUG NearHeapCheck(); #endif size = (WORD) strlen(string) + 1; pstr = _nmalloc(size); if (!pstr) { fprintf(stderr, errNearMemory, wNearMemoryUsed); exit(2); } wNearMemoryUsed += size; strcpy(pstr, string); #ifdef HEAPDEBUG NearHeapCheck(); #endif return pstr; } #ifdef DEBUG static FILE *fpCOM1 = stdaux; static BOOL fFixed = False; #include #include #include void cdecl COMprintf(PSTR format, ...) { va_list arglist; if (!fFixed) { setmode(fileno(fpCOM1), O_TEXT); } va_start (arglist, format); vfprintf(fpCOM1, format, arglist); va_end (arglist); } #endif