1366 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1366 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/* m4memory.c   (c)Copyright Sequiter Software Inc., 1988-1996.  All rights reserved. */
 | 
						|
 | 
						|
#ifdef S4OS2
 | 
						|
   #ifdef __DLL__
 | 
						|
      #define  INCL_DOSMEMMGR
 | 
						|
   #endif
 | 
						|
#endif
 | 
						|
#include "d4all.h"
 | 
						|
 | 
						|
#ifdef S4VB_DOS
 | 
						|
   #include "malloc.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef __TURBOC__
 | 
						|
   #pragma hdrstop
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef S4OS2
 | 
						|
   #ifdef __DLL__
 | 
						|
      #include <bsememf.h>
 | 
						|
   #endif
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef S4SERVER
 | 
						|
   /* for 32 bit servers, allow more than 10000 memory allocations... */
 | 
						|
   #ifndef S4WIN32
 | 
						|
      #ifdef S4WINTEL
 | 
						|
         #ifndef S4OS2
 | 
						|
            #define MEM4MAX_POINTERS 10000
 | 
						|
         #endif
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
   #ifndef MEM4MAX_POINTERS
 | 
						|
      #define MEM4MAX_POINTERS 100000
 | 
						|
   #endif
 | 
						|
#else
 | 
						|
   #define MEM4MAX_POINTERS 10000
 | 
						|
#endif
 | 
						|
 | 
						|
#define mem4numTypes 10
 | 
						|
 | 
						|
#ifdef S4MEM_PRINT
 | 
						|
   #ifdef S4WINDOWS
 | 
						|
      #ifdef S4TESTING
 | 
						|
         #include "t4test.h"
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
   int v4print = 0 ; /* if v4print == 0 then stdout, else stdprn, no output if -1 */
 | 
						|
   /* use globals to hold the current file name and line number */
 | 
						|
   const char *m4fileName = 0 ;
 | 
						|
   int m4lineNo = 0 ;
 | 
						|
   #ifdef S4WINDOWS
 | 
						|
      int  S4FUNCTION code4memFileName( void )
 | 
						|
      {
 | 
						|
         return m4lineNo ;
 | 
						|
      }
 | 
						|
 | 
						|
      const char *S4FUNCTION code4memFileNo( void )
 | 
						|
      {
 | 
						|
         return m4fileName ;
 | 
						|
      }
 | 
						|
 | 
						|
      void S4FUNCTION code4memLineNoSet( int val )
 | 
						|
      {
 | 
						|
         m4lineNo = val ;
 | 
						|
      }
 | 
						|
 | 
						|
      void S4FUNCTION code4memFileNameSet( const char *ptr )
 | 
						|
      {
 | 
						|
         m4fileName = ptr ;
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
#endif
 | 
						|
 | 
						|
typedef struct
 | 
						|
{
 | 
						|
   LINK4  link ;
 | 
						|
   MEM4  types[mem4numTypes] ;
 | 
						|
} MEMORY4GROUP ;
 | 
						|
 | 
						|
#ifdef S4WIN32
 | 
						|
   #ifdef S4SEMAPHORE
 | 
						|
      /* multi-thread support */
 | 
						|
      CRITICAL_SECTION critical4memory, critical4expression ;
 | 
						|
   #endif
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef S4CBPP
 | 
						|
   static LIST4  avail = { 0, 0, 0 } ;   /* A list of available MEM4 entries */
 | 
						|
   static LIST4  used = { 0, 0, 0 } ;   /* A list of used MEM4 entries */
 | 
						|
   static LIST4  groups = { 0, 0, 0 } ; /* A list of Allocated MEM4 groups */
 | 
						|
#else
 | 
						|
   /* initialization with class and union structures */
 | 
						|
   static LIST4  avail  = { {0}, 0, {0} } ;   /* A list of available MEM4 entries */
 | 
						|
   static LIST4  used   = { {0}, {0}, {0} } ;   /* A list of used MEM4 entries */
 | 
						|
   static LIST4  groups = { {0}, 0, {0} } ;   /* A list of Allocated MEM4 groups */
 | 
						|
#endif
 | 
						|
#ifdef S4SEMAPHORE
 | 
						|
   #ifdef S4WIN32
 | 
						|
      static int memoryInitialized = 0 ;
 | 
						|
   #endif
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef S4SEMAPHORE
 | 
						|
#ifdef S4WIN32
 | 
						|
int mem4start( CODE4 *c4 )
 | 
						|
{
 | 
						|
   if ( memoryInitialized == 0 )
 | 
						|
      return -1 ;
 | 
						|
 | 
						|
   EnterCriticalSection( &critical4memory ) ;
 | 
						|
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
void mem4stop( CODE4 *c4 )
 | 
						|
{
 | 
						|
   if ( memoryInitialized == 0 )
 | 
						|
      return ;
 | 
						|
 | 
						|
   LeaveCriticalSection( &critical4memory ) ;
 | 
						|
}
 | 
						|
#else
 | 
						|
static int mem4start( CODE4 *c4 )
 | 
						|
{
 | 
						|
   APIRET rc ;
 | 
						|
 | 
						|
   #ifdef E4ANALYZE
 | 
						|
      if ( c4 == 0 )
 | 
						|
         return error4( c4, e4info, "OS/2 Semaphore Failure" ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   rc = DosRequestMutexSem( c4->hmtxMem, -1 ) ;
 | 
						|
   if ( rc != 0 )
 | 
						|
      return error4( c4, e4info, "OS/2 Semaphore Failure" ) ;
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
static void mem4stop( CODE4 *c4 )
 | 
						|
{
 | 
						|
   #ifdef E4ANALYZE
 | 
						|
      if ( c4 == 0 )
 | 
						|
      {
 | 
						|
         error4( c4, e4info, "OS/2 Semaphore Failure" ) ;
 | 
						|
         return ;
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   DosReleaseMutexSem( c4->hmtxMem ) ;
 | 
						|
}
 | 
						|
#endif /* S4WIN32 */
 | 
						|
#endif /* S4SEMAPHORE */
 | 
						|
 | 
						|
#ifdef E4MISC
 | 
						|
 | 
						|
static char **mem4testPointers ;
 | 
						|
static int mem4numPointer = -1 ;
 | 
						|
static int mem4numUsed = 0 ;
 | 
						|
 | 
						|
#ifdef S4DATA_ALIGN
 | 
						|
   #define mem4extraChars 12
 | 
						|
#else
 | 
						|
   #define mem4extraChars 10
 | 
						|
#endif
 | 
						|
#define mem4extraTot (mem4extraChars*2 + sizeof(unsigned))
 | 
						|
#define mem4checkChar 0x55
 | 
						|
 | 
						|
#define MEM4INC 500
 | 
						|
 | 
						|
/* Returns the pointer to be returned; is passed the pointer allocated by malloc ... */
 | 
						|
static char *mem4fixPointer( char *startPtr, unsigned largeLen )
 | 
						|
{
 | 
						|
   char *returnPtr ;
 | 
						|
   unsigned pos ;
 | 
						|
 | 
						|
   memset( startPtr, mem4checkChar, mem4extraChars ) ;
 | 
						|
   returnPtr = startPtr + mem4extraChars ;
 | 
						|
 | 
						|
   memcpy( returnPtr, (void *)&largeLen, sizeof(largeLen) ) ;
 | 
						|
   pos = largeLen - mem4extraChars ;
 | 
						|
   memset( startPtr+ pos, mem4checkChar, mem4extraChars ) ;
 | 
						|
 | 
						|
   return returnPtr + sizeof(unsigned) ;
 | 
						|
}
 | 
						|
 | 
						|
/* Returns the pointer allocated by malloc; */
 | 
						|
/* passed by pointer returned by 'mem4fixPointer' */
 | 
						|
static char *mem4checkPointer( char *returnPtr, int clear )
 | 
						|
{
 | 
						|
   unsigned *largeLenPtr ;
 | 
						|
   char *mallocPtr, *testPtr ;
 | 
						|
   int i, j ;
 | 
						|
 | 
						|
   largeLenPtr = (unsigned *)(returnPtr - sizeof(unsigned)) ;
 | 
						|
   mallocPtr = returnPtr - sizeof(unsigned) - mem4extraChars ;
 | 
						|
 | 
						|
   for ( j = 0; j < 2; j++ )
 | 
						|
   {
 | 
						|
      if (j == 0)
 | 
						|
         testPtr = mallocPtr ;
 | 
						|
      else
 | 
						|
         testPtr = mallocPtr + *largeLenPtr - mem4extraChars ;
 | 
						|
 | 
						|
      for ( i = 0 ; i < mem4extraChars ; i++ )
 | 
						|
         if ( testPtr[i] != mem4checkChar )
 | 
						|
         {
 | 
						|
            #ifdef S4MEM_PRINT
 | 
						|
               if ( v4print != -1 )
 | 
						|
               {
 | 
						|
                  #ifdef S4WINDOWS
 | 
						|
                     #ifdef S4TESTING
 | 
						|
                        d4displayStr( mem4displayPtr, "corrupt memory: ", 1 ) ;
 | 
						|
                        d4displayPtr( mem4displayPtr, mallocPtr- sizeof(unsigned) - mem4extraChars, 0 ) ;
 | 
						|
                     #endif
 | 
						|
                  #else
 | 
						|
                     if ( v4print )
 | 
						|
                        fprintf( stdprn, "\r\ncorrupt memory: %p", mallocPtr- sizeof(unsigned) - mem4extraChars ) ;
 | 
						|
                     else
 | 
						|
                        printf( "\r\ncorrupt memory: %p", mallocPtr- sizeof(unsigned) - mem4extraChars ) ;
 | 
						|
                  #endif
 | 
						|
               }
 | 
						|
            #endif
 | 
						|
            error4( 0, e4result, E85901 ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
   }
 | 
						|
   if ( clear == 1 ) /* null the memory to potentially detect re-use, including clearing check chars */
 | 
						|
      memset( mallocPtr, 0, *largeLenPtr ) ;
 | 
						|
   return mallocPtr ;
 | 
						|
}
 | 
						|
 | 
						|
static int mem4pushPointer( char *ptr )
 | 
						|
{
 | 
						|
   #ifdef S4WINDOWS
 | 
						|
      HANDLE handle, *hPtr, *oldHPtr ;
 | 
						|
      hPtr = (HANDLE *)0 ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( mem4numPointer < 0 )
 | 
						|
   {
 | 
						|
      #ifdef S4WINDOWS
 | 
						|
         #ifdef __DLL__
 | 
						|
            handle = GlobalAlloc( GMEM_MOVEABLE | GMEM_DDESHARE | GMEM_ZEROINIT, (DWORD) sizeof(char *) * MEM4INC + sizeof(HANDLE) ) ;
 | 
						|
         #else
 | 
						|
            handle = GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, (DWORD) sizeof(char *) * MEM4INC + sizeof(HANDLE) ) ;
 | 
						|
         #endif
 | 
						|
 | 
						|
         if ( handle == (HANDLE) 0 )
 | 
						|
            return error4( 0, e4memory, E95901 ) ;
 | 
						|
 | 
						|
         hPtr = (HANDLE *)GlobalLock( handle ) ;
 | 
						|
         *hPtr++ = handle ;
 | 
						|
         mem4testPointers = (char **)hPtr ;
 | 
						|
      #else
 | 
						|
         mem4testPointers = (char **)malloc( sizeof(char *) * MEM4INC ) ;
 | 
						|
      #endif
 | 
						|
      mem4numPointer = MEM4INC ;
 | 
						|
   }
 | 
						|
   if ( mem4numPointer == mem4numUsed )
 | 
						|
   {
 | 
						|
      mem4numPointer += MEM4INC ;
 | 
						|
      if ( mem4numPointer > MEM4MAX_POINTERS )
 | 
						|
         return error4( 0, e4result, E95901 ) ;
 | 
						|
 | 
						|
      #ifdef S4WINDOWS
 | 
						|
         oldHPtr = (HANDLE *)(mem4testPointers) ;
 | 
						|
         oldHPtr-- ;  /* get the actual handle */
 | 
						|
 | 
						|
         #ifdef __DLL__
 | 
						|
            handle = GlobalReAlloc( *oldHPtr, (DWORD)sizeof(char *) * mem4numPointer + sizeof( HANDLE ), GMEM_MOVEABLE ) ;
 | 
						|
         #else
 | 
						|
            handle = GlobalReAlloc( *oldHPtr, (DWORD)sizeof(char *) * mem4numPointer + sizeof( HANDLE ), GMEM_MOVEABLE ) ;
 | 
						|
         #endif
 | 
						|
 | 
						|
         if ( handle == (HANDLE) 0 )
 | 
						|
            return error4( 0, e4memory, E95901 ) ;
 | 
						|
 | 
						|
         hPtr = (HANDLE *)GlobalLock( handle ) ;
 | 
						|
         *hPtr++ = handle ;
 | 
						|
         mem4testPointers = (char **)hPtr ;
 | 
						|
      #else
 | 
						|
         mem4testPointers = (char **)realloc( (void *)mem4testPointers, sizeof(char *)*mem4numPointer ) ;
 | 
						|
      #endif
 | 
						|
   }
 | 
						|
 | 
						|
   if ( mem4testPointers == 0 )
 | 
						|
      return error4( 0, e4memory, E95901 ) ;
 | 
						|
 | 
						|
   mem4testPointers[mem4numUsed++] = ptr ;
 | 
						|
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
static int mem4popPointer( char *ptr )
 | 
						|
{
 | 
						|
   int i ;
 | 
						|
 | 
						|
   if ( mem4testPointers == 0 )   /* failure in allocating tracking memory, so allow shutdown */
 | 
						|
   {
 | 
						|
      mem4numUsed-- ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   for ( i = mem4numUsed - 1 ; i >= 0 ; i-- )
 | 
						|
      if ( mem4testPointers[i] == ptr )
 | 
						|
      {
 | 
						|
         /* This 'memmove' may create compile warning */
 | 
						|
         c4memmove( mem4testPointers+i, mem4testPointers+i+1, (size_t) (sizeof(char *) * (mem4numUsed-i-1))) ;
 | 
						|
         mem4numUsed-- ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
 | 
						|
   return error4( 0, e4result, E95902 ) ;
 | 
						|
}
 | 
						|
 | 
						|
int S4FUNCTION mem4checkMemory()
 | 
						|
{
 | 
						|
   int i ;
 | 
						|
   char *ptr ;
 | 
						|
 | 
						|
   if ( code4numCodeBase() == 0 )
 | 
						|
      return 0 ;
 | 
						|
 | 
						|
   #ifdef S4SEMAPHORE
 | 
						|
      mem4start( 0 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   for ( i = 0; i < mem4numUsed; i++ )
 | 
						|
   {
 | 
						|
      ptr = mem4checkPointer( mem4testPointers[i], 0 ) ;
 | 
						|
      if ( ptr == 0 )
 | 
						|
         return error4( 0, e4result, E95903 ) ;
 | 
						|
   }
 | 
						|
 | 
						|
   #ifdef S4SEMAPHORE
 | 
						|
      mem4stop( 0 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
int S4FUNCTION mem4freeCheck( const int maxLeft )
 | 
						|
{
 | 
						|
   #ifdef S4MEM_PRINT
 | 
						|
      int i ;
 | 
						|
      if ( v4print != -1 )
 | 
						|
      {
 | 
						|
         #ifdef S4WINDOWS
 | 
						|
            #ifdef S4TESTING
 | 
						|
               for ( i = 0; i < mem4numUsed; i++ )
 | 
						|
               {
 | 
						|
                  d4displayStr( mem4displayPtr, "mem4freeCheck: ", 1 ) ;
 | 
						|
                  d4displayPtr( mem4displayPtr, mem4testPointers[i], 0 ) ;
 | 
						|
               }
 | 
						|
            #endif
 | 
						|
         #else
 | 
						|
            if ( v4print )
 | 
						|
               for ( i = 0; i < mem4numUsed; i++ )
 | 
						|
                  fprintf( stdprn, "\r\nmem4freeCheck: %p", mem4testPointers[i] ) ;
 | 
						|
            else
 | 
						|
               for ( i = 0; i < mem4numUsed; i++ )
 | 
						|
                  printf( "\r\nmem4freeCheck: %p", mem4testPointers[i] ) ;
 | 
						|
         #endif
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( mem4numUsed > maxLeft )
 | 
						|
      return error4( 0, e4result, 95904 ) ;
 | 
						|
 | 
						|
   return ( mem4numUsed ) ;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
void *S4FUNCTION mem4allocDefault( MEM4 *memoryType )
 | 
						|
{
 | 
						|
   #ifdef E4PARM_HIGH
 | 
						|
      if ( memoryType == 0 )
 | 
						|
      {
 | 
						|
         error4( 0, e4parm_null, E95905 ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   return mem4alloc2Default( memoryType, 0 ) ;
 | 
						|
}
 | 
						|
 | 
						|
static Y4CHUNK *mem4allocChunkDefault( MEM4 *typePtr )
 | 
						|
{
 | 
						|
   Y4CHUNK *chunkPtr ;
 | 
						|
   int  nAllocate, i ;
 | 
						|
   char *ptr ;
 | 
						|
   long allocSize ;
 | 
						|
 | 
						|
   nAllocate = typePtr->unitExpand ;
 | 
						|
   if ( l4last( &typePtr->chunks ) == 0 )
 | 
						|
      nAllocate = typePtr->unitStart ;
 | 
						|
 | 
						|
   for ( ;; )
 | 
						|
   {
 | 
						|
      allocSize = (long)sizeof( LINK4 ) + (long)nAllocate * typePtr->unitSize ;
 | 
						|
      if ( allocSize < UINT_MAX )
 | 
						|
         break ;
 | 
						|
      if ( nAllocate <= 1 )
 | 
						|
         return 0 ;
 | 
						|
      nAllocate = nAllocate / 2 ;
 | 
						|
   }
 | 
						|
 | 
						|
   #ifdef S4DOS    /* no memory sharing under DOS, so can use a CODE4 for limited memory */
 | 
						|
      chunkPtr = (Y4CHUNK *)u4allocFreeDefault( typePtr->codeBase, allocSize ) ;
 | 
						|
   #else
 | 
						|
      chunkPtr = (Y4CHUNK *)u4alloc( allocSize ) ;
 | 
						|
   #endif
 | 
						|
   if ( chunkPtr == 0 )
 | 
						|
      return 0 ;
 | 
						|
   ptr = (char *)&chunkPtr->data ;
 | 
						|
   for ( i = 0 ; i < nAllocate ; i++ )
 | 
						|
      l4add( &typePtr->pieces, (LINK4 *)( ptr + i * typePtr->unitSize ) ) ;
 | 
						|
 | 
						|
   return  chunkPtr ;
 | 
						|
}
 | 
						|
 | 
						|
static void *mem4allocLow( MEM4 *memoryType )
 | 
						|
{
 | 
						|
   LINK4 *nextPiece ;
 | 
						|
   Y4CHUNK *newChunk ;
 | 
						|
   #ifdef E4MISC
 | 
						|
      char *ptr ;
 | 
						|
   #endif
 | 
						|
   #ifdef S4OS2_SEMAPHORE
 | 
						|
      #ifdef __DLL__
 | 
						|
         ULONG flags ;
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( memoryType == 0 )
 | 
						|
      return 0 ;
 | 
						|
   nextPiece = (LINK4 *)l4pop( &memoryType->pieces ) ;
 | 
						|
 | 
						|
   if ( nextPiece != 0 )
 | 
						|
   {
 | 
						|
      #ifdef S4SEMAPHORE
 | 
						|
         #ifdef S4OS2
 | 
						|
            #ifdef __DLL__
 | 
						|
               /* get access to the memory */
 | 
						|
               flags = PAG_WRITE | PAG_READ  ;
 | 
						|
               if ( DosGetSharedMem( nextPiece, flags ) != 0 )
 | 
						|
                  return 0 ;
 | 
						|
            #endif
 | 
						|
         #endif
 | 
						|
      #endif
 | 
						|
      #ifdef E4MISC
 | 
						|
         memoryType->nUsed++ ;
 | 
						|
         ptr = mem4fixPointer( (char *)nextPiece, memoryType->unitSize ) ;
 | 
						|
 | 
						|
         if ( mem4pushPointer( ptr ) == e4memory )
 | 
						|
         {
 | 
						|
            memoryType->nUsed-- ;
 | 
						|
            l4add( &memoryType->pieces, nextPiece ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
 | 
						|
         #ifdef S4MEM_PRINT
 | 
						|
            if ( v4print != -1 )
 | 
						|
            {
 | 
						|
               #ifdef S4WINDOWS
 | 
						|
                  #ifdef S4TESTING
 | 
						|
                     {
 | 
						|
                        d4displayStr( mem4displayPtr, "  Y4ALLOC:  ", 1 ) ;
 | 
						|
                        d4displayPtr( mem4displayPtr, ptr, 0 ) ;
 | 
						|
                        d4displayStr( mem4displayPtr, "  file:  ", 0 ) ;
 | 
						|
                        d4displayStr( mem4displayPtr, m4fileName, 0 ) ;
 | 
						|
                        d4displayStr( mem4displayPtr, "  line:  ", 0 ) ;
 | 
						|
                        d4displayNum( mem4displayPtr, m4lineNo, 0 ) ;
 | 
						|
                     }
 | 
						|
                  #endif
 | 
						|
               #else
 | 
						|
                  if ( v4print )
 | 
						|
                     fprintf( stdprn, "\r\n  Y4ALLOC:  %lx  file:  %s  line:  %12d", ptr, m4fileName, m4lineNo ) ;
 | 
						|
                  else
 | 
						|
                     printf( "\r\n  Y4ALLOC:  %lx  file:  %s  line:  %12d", ptr, m4fileName, m4lineNo  ) ;
 | 
						|
               #endif
 | 
						|
            }
 | 
						|
         #endif
 | 
						|
 | 
						|
         return (void *)ptr ;
 | 
						|
      #else
 | 
						|
         return nextPiece ;
 | 
						|
      #endif
 | 
						|
   }
 | 
						|
 | 
						|
   if ( (newChunk = mem4allocChunkDefault( memoryType )) == 0 )
 | 
						|
      return 0 ;
 | 
						|
   l4add( &memoryType->chunks, &newChunk->link ) ;
 | 
						|
 | 
						|
   memoryType->nUsed++ ;
 | 
						|
   #ifdef E4MISC
 | 
						|
      ptr = mem4fixPointer( (char *)l4pop(&memoryType->pieces),
 | 
						|
                            memoryType->unitSize ) ;
 | 
						|
      #ifdef S4MEM_PRINT
 | 
						|
         if ( v4print != -1 )
 | 
						|
         {
 | 
						|
            #ifdef S4WINDOWS
 | 
						|
               #ifdef S4TESTING
 | 
						|
                  {
 | 
						|
                     d4displayStr( mem4displayPtr, "  Y4ALLOC:  ", 1 ) ;
 | 
						|
                     d4displayPtr( mem4displayPtr, ptr, 0 ) ;
 | 
						|
                     d4displayStr( mem4displayPtr, "  file:  ", 0 ) ;
 | 
						|
                     d4displayStr( mem4displayPtr, m4fileName, 0 ) ;
 | 
						|
                     d4displayStr( mem4displayPtr, "  line:  ", 0 ) ;
 | 
						|
                     d4displayNum( mem4displayPtr, m4lineNo, 0 ) ;
 | 
						|
                  }
 | 
						|
               #endif
 | 
						|
            #else
 | 
						|
               if ( v4print )
 | 
						|
                  fprintf( stdprn, "\r\n  Y4ALLOC:  %lx  file:  %s  line:  %12d", ptr, m4fileName, m4lineNo ) ;
 | 
						|
               else
 | 
						|
                  printf( "\r\n  Y4ALLOC:  %lx  file:  %s  line:  %12d", ptr, m4fileName, m4lineNo  ) ;
 | 
						|
            #endif
 | 
						|
         }
 | 
						|
      #endif
 | 
						|
 | 
						|
      mem4pushPointer( ptr ) ;
 | 
						|
      return (void *)ptr ;
 | 
						|
   #else
 | 
						|
      return l4pop( &memoryType->pieces ) ;
 | 
						|
   #endif
 | 
						|
}
 | 
						|
 | 
						|
void *S4FUNCTION mem4alloc2Default( MEM4 *memoryType, CODE4 *c4 )
 | 
						|
{
 | 
						|
   void *ptr ;
 | 
						|
 | 
						|
   if ( code4numCodeBase() == 0 )
 | 
						|
      return 0 ;
 | 
						|
 | 
						|
   if ( c4 )
 | 
						|
      if ( error4code( c4 ) < 0 )
 | 
						|
         return 0 ;
 | 
						|
 | 
						|
   #ifdef S4SEMAPHORE
 | 
						|
      mem4start( c4 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   ptr = mem4allocLow( memoryType ) ;
 | 
						|
 | 
						|
   #ifdef S4SEMAPHORE
 | 
						|
      #ifdef S4WIN32
 | 
						|
         mem4stop( c4 ) ;
 | 
						|
      #else
 | 
						|
         mem4stop( memoryType->codeBase ) ;
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( ptr == 0 )
 | 
						|
   {
 | 
						|
      if ( c4 )
 | 
						|
         error4set( c4, e4memory ) ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
   #ifdef E4MISC
 | 
						|
      memset( ptr, 0, memoryType->unitSize - mem4extraTot ) ;
 | 
						|
   #else
 | 
						|
      memset( ptr, 0, memoryType->unitSize ) ;
 | 
						|
   #endif
 | 
						|
   return ptr ;
 | 
						|
}
 | 
						|
 | 
						|
MEM4 *S4FUNCTION mem4createDefault( CODE4 *c4, int start, const unsigned int uSize, int expand, const int isTemp )
 | 
						|
{
 | 
						|
   MEM4 *onType ;
 | 
						|
   unsigned int unitSize ;
 | 
						|
   #ifdef S4SEMAPHORE
 | 
						|
      #ifdef S4OS2
 | 
						|
         #ifdef __DLL__
 | 
						|
            ULONG flags ;
 | 
						|
         #endif
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef E4PARM_HIGH
 | 
						|
      /* c4 == 0 is allowable */
 | 
						|
      if (  start < 1 || expand < 1 )
 | 
						|
      {
 | 
						|
         error4( c4, e4parm, E95906 ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( code4numCodeBase() == 0 )
 | 
						|
      return 0 ;
 | 
						|
 | 
						|
   if ( uSize < sizeof( LINK4 ) )   /* ensure enough so that we can keep track of the memory */
 | 
						|
      unitSize = sizeof( LINK4 ) ;
 | 
						|
   else
 | 
						|
      unitSize = uSize ;
 | 
						|
 | 
						|
   #ifdef E4MISC
 | 
						|
      unitSize += 2 * mem4extraChars + sizeof( unsigned ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( c4 )
 | 
						|
      if ( error4code( c4 ) < 0 )
 | 
						|
         return 0 ;
 | 
						|
 | 
						|
   #ifdef S4SEMAPHORE
 | 
						|
      mem4start( c4 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( !isTemp )
 | 
						|
      for( onType = 0 ;; )
 | 
						|
      {
 | 
						|
         onType = (MEM4 *)l4next( &used, onType ) ;
 | 
						|
         if ( onType == 0 )
 | 
						|
            break ;
 | 
						|
 | 
						|
         #ifdef S4SEMAPHORE
 | 
						|
            #ifdef S4OS2
 | 
						|
               #ifdef __DLL__
 | 
						|
                  /* get access to the memory */
 | 
						|
                  flags = PAG_WRITE | PAG_READ  ;
 | 
						|
                  if ( DosGetSharedMem( onType, flags ) != 0 )
 | 
						|
                     return 0 ;
 | 
						|
               #endif
 | 
						|
            #endif
 | 
						|
         #endif
 | 
						|
 | 
						|
         #ifdef S4DOS    /* no memory sharing under DOS, so can use a CODE4 for limited memory */
 | 
						|
            if ( onType->codeBase == c4 || onType->codeBase == 0 )
 | 
						|
         #endif
 | 
						|
         if ( onType->unitSize == unitSize && onType->nRepeat > 0 )
 | 
						|
         {
 | 
						|
            /* Match */
 | 
						|
            if ( start > onType->unitStart )
 | 
						|
               onType->unitStart = start ;
 | 
						|
            if ( expand > onType->unitExpand)
 | 
						|
               onType->unitExpand = expand ;
 | 
						|
            onType->nRepeat++ ;
 | 
						|
            #ifdef S4SEMAPHORE
 | 
						|
               mem4stop( c4 ) ;
 | 
						|
            #endif
 | 
						|
            #ifdef S4DOS
 | 
						|
               if ( onType->codeBase == 0 )  /* set to avoid code4initUndo() errors */
 | 
						|
                  onType->codeBase = c4 ;
 | 
						|
            #endif
 | 
						|
            return onType ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
 | 
						|
   /* Allocate memory for another MEM4 */
 | 
						|
 | 
						|
   onType = (MEM4 *)l4last( &avail ) ;
 | 
						|
   if ( onType == 0 )
 | 
						|
   {
 | 
						|
      MEMORY4GROUP *group ;
 | 
						|
      int i ;
 | 
						|
 | 
						|
      #ifdef S4MEM_PRINT
 | 
						|
         char *nullPtr = 0 ;
 | 
						|
 | 
						|
         if ( v4print != -1 )
 | 
						|
         {
 | 
						|
            #ifdef S4WINDOWS
 | 
						|
               #ifdef S4TESTING
 | 
						|
                  {
 | 
						|
                     d4displayStr( mem4displayPtr, "  MEM4:  ", 1 ) ;
 | 
						|
                     d4displayPtr( mem4displayPtr, nullPtr, 0 ) ;
 | 
						|
                     d4displayStr( mem4displayPtr, "  file:  ", 0 ) ;
 | 
						|
                     d4displayStr( mem4displayPtr, "ignoreNextLine", 0 ) ;
 | 
						|
                     d4displayStr( mem4displayPtr, "  line:  ", 0 ) ;
 | 
						|
                     d4displayNum( mem4displayPtr, 0, 0 ) ;
 | 
						|
                     d4displayStr( mem4displayPtr, "  num bytes:  ", 0 ) ;
 | 
						|
                     d4displayNum( mem4displayPtr, 0, 0 ) ;
 | 
						|
                  }
 | 
						|
               #endif
 | 
						|
            #else
 | 
						|
               if ( v4print )
 | 
						|
                  fprintf( stdprn, "\r\n  MEM4:  %lx  file:  ignoreNextLine  line:  %12d  num bytes:  %12d", nullPtr, 0, 0 ) ;
 | 
						|
               else
 | 
						|
                  printf("\r\n  MEM4:  %lx  file:  ignoreNextLine  line:  %12d  num bytes:  %12d", nullPtr, 0, 0 ) ;
 | 
						|
            #endif
 | 
						|
         }
 | 
						|
      #endif
 | 
						|
 | 
						|
      group = (MEMORY4GROUP *)u4allocFreeDefault( c4, (long)sizeof( MEMORY4GROUP ) ) ;
 | 
						|
      if ( group == 0 )
 | 
						|
      {
 | 
						|
         if ( c4 )
 | 
						|
            error4set( c4, e4memory ) ;
 | 
						|
         #ifdef S4SEMAPHORE
 | 
						|
            mem4stop( c4 ) ;
 | 
						|
         #endif
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
 | 
						|
      for ( i = 0 ; i < mem4numTypes ; i++ )
 | 
						|
         l4add( &avail, group->types + i ) ;
 | 
						|
      onType = (MEM4 *)l4last( &avail ) ;
 | 
						|
      l4add( &groups, group ) ;
 | 
						|
   }
 | 
						|
 | 
						|
   l4remove( &avail, onType ) ;
 | 
						|
   memset( (void *)onType, 0, sizeof( MEM4 ) ) ;
 | 
						|
   l4add( &used, onType ) ;
 | 
						|
 | 
						|
   onType->unitStart = start ;
 | 
						|
   onType->unitSize = unitSize ;
 | 
						|
   onType->unitExpand= expand ;
 | 
						|
   onType->nRepeat = 1 ;
 | 
						|
   onType->nUsed = 0 ;
 | 
						|
   if ( isTemp )
 | 
						|
      onType->nRepeat = -1 ;
 | 
						|
 | 
						|
   #ifdef S4SEMAPHORE
 | 
						|
      mem4stop( c4 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef S4MEM_PRINT
 | 
						|
      if ( v4print != -1 )
 | 
						|
      {
 | 
						|
         #ifdef S4WINDOWS
 | 
						|
            #ifdef S4TESTING
 | 
						|
               {
 | 
						|
                  d4displayStr( mem4displayPtr, "  MEM4:     ", 1 ) ;
 | 
						|
                  d4displayPtr( mem4displayPtr, onType, 0 ) ;
 | 
						|
                  d4displayStr( mem4displayPtr, "  file:  ", 0 ) ;
 | 
						|
                  d4displayStr( mem4displayPtr, m4fileName, 0 ) ;
 | 
						|
                  d4displayStr( mem4displayPtr, "  line:  ", 0 ) ;
 | 
						|
                  d4displayNum( mem4displayPtr, m4lineNo, 0 ) ;
 | 
						|
               }
 | 
						|
            #endif
 | 
						|
         #else
 | 
						|
            if ( v4print )
 | 
						|
               fprintf( stdprn, "\r\n  MEM4:     %lx  file:  %s  line:  %12d", onType, m4fileName, m4lineNo ) ;
 | 
						|
            else
 | 
						|
               printf( "\r\n  MEM4:     %lx  file:  %s  line:  %12d", onType, m4fileName, m4lineNo ) ;
 | 
						|
         #endif
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef S4DOS    /* no memory sharing under DOS, so can use a CODE4 for limited memory */
 | 
						|
      onType->codeBase = c4 ;
 | 
						|
   #endif
 | 
						|
   return onType ;
 | 
						|
}
 | 
						|
 | 
						|
void *S4FUNCTION mem4createAllocDefault( CODE4 *c4, MEM4 **typePtrPtr, int start, const unsigned int unitSize, int expand, const int isTemp)
 | 
						|
{
 | 
						|
   if ( *typePtrPtr == 0 )
 | 
						|
   {
 | 
						|
      *typePtrPtr = mem4createDefault( c4, start, unitSize, expand, isTemp ) ;
 | 
						|
      if ( *typePtrPtr == 0 )
 | 
						|
         return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   return mem4alloc2Default( *typePtrPtr, c4 ) ;
 | 
						|
}
 | 
						|
 | 
						|
int S4FUNCTION mem4freeDefault( MEM4 *memoryType, void *freePtr )
 | 
						|
{
 | 
						|
   #ifdef E4MISC
 | 
						|
      int rc ;
 | 
						|
      LINK4 *holdPtr ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( freePtr == 0 )  /* as documented */
 | 
						|
      return 0 ;
 | 
						|
 | 
						|
   if ( memoryType == 0 )
 | 
						|
      return error4( 0, e4parm_null, E95907 ) ;
 | 
						|
 | 
						|
   if ( code4numCodeBase() == 0 )
 | 
						|
      return 0 ;
 | 
						|
 | 
						|
   #ifdef S4SEMAPHORE
 | 
						|
      mem4start( 0 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   memoryType->nUsed-- ;
 | 
						|
   #ifdef E4MISC
 | 
						|
      if ( memoryType->nUsed < 0 )
 | 
						|
      {
 | 
						|
         #ifdef S4SEMAPHORE
 | 
						|
            mem4stop( 0 ) ;
 | 
						|
         #endif
 | 
						|
         return error4( 0, e4result, E95907 ) ;
 | 
						|
      }
 | 
						|
 | 
						|
      rc = mem4popPointer( (char *)freePtr ) ;
 | 
						|
      holdPtr = (LINK4 *)mem4checkPointer( (char *)freePtr, 0 ) ;
 | 
						|
      if ( holdPtr != 0 )
 | 
						|
      {
 | 
						|
         l4add( &memoryType->pieces, holdPtr ) ;
 | 
						|
         #ifdef S4MEM_PRINT
 | 
						|
            if ( v4print != -1 )
 | 
						|
            {
 | 
						|
               #ifdef S4WINDOWS
 | 
						|
                  #ifdef S4TESTING
 | 
						|
                     {
 | 
						|
                        d4displayStr( mem4displayPtr, "  Y4FREE:   ", 1 ) ;
 | 
						|
                        d4displayPtr( mem4displayPtr, freePtr, 0 ) ;
 | 
						|
                        d4displayStr( mem4displayPtr, "  file:  ", 0 ) ;
 | 
						|
                        d4displayStr( mem4displayPtr, m4fileName, 0 ) ;
 | 
						|
                        d4displayStr( mem4displayPtr, "  line:  ", 0 ) ;
 | 
						|
                        d4displayNum( mem4displayPtr, m4lineNo, 0 ) ;
 | 
						|
                     }
 | 
						|
                  #endif
 | 
						|
               #else
 | 
						|
                  if ( v4print )
 | 
						|
                     fprintf(stdprn, "\r\n  Y4FREE:   %lx  file:  %s  line:  %12d", freePtr, m4fileName, m4lineNo ) ;
 | 
						|
                  else
 | 
						|
                     printf( "\r\n  Y4FREE:   %lx  file:  %s  line:  %12d", freePtr, m4fileName, m4lineNo ) ;
 | 
						|
               #endif
 | 
						|
            }
 | 
						|
         #endif
 | 
						|
      }
 | 
						|
 | 
						|
      memset( ((char *)freePtr), 0, memoryType->unitSize - 2 * mem4extraChars - sizeof( unsigned ) ) ;
 | 
						|
      #ifdef S4SEMAPHORE
 | 
						|
         mem4stop( 0 ) ;
 | 
						|
      #endif
 | 
						|
      return rc ;
 | 
						|
   #else
 | 
						|
      l4add( &memoryType->pieces, (LINK4 *)freePtr ) ;
 | 
						|
      #ifdef S4SEMAPHORE
 | 
						|
         mem4stop( 0 ) ;
 | 
						|
      #endif
 | 
						|
      return 0 ;
 | 
						|
   #endif
 | 
						|
}
 | 
						|
 | 
						|
void S4FUNCTION mem4release( MEM4 *memoryType )
 | 
						|
{
 | 
						|
   void *ptr ;
 | 
						|
 | 
						|
   if ( memoryType == 0 )
 | 
						|
      return ;
 | 
						|
 | 
						|
   if ( code4numCodeBase() == 0 )
 | 
						|
      return ;
 | 
						|
 | 
						|
   #ifdef S4SEMAPHORE
 | 
						|
      mem4start( 0 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   memoryType->nRepeat-- ;
 | 
						|
   if ( memoryType->nRepeat <= 0 )
 | 
						|
   {
 | 
						|
      for(;;)
 | 
						|
      {
 | 
						|
         ptr = l4pop( &memoryType->chunks) ;
 | 
						|
         if ( ptr == 0 )
 | 
						|
            break ;
 | 
						|
         u4freeDefault( ptr ) ;
 | 
						|
      }
 | 
						|
 | 
						|
      l4remove( &used, memoryType ) ;
 | 
						|
      l4add( &avail, memoryType ) ;
 | 
						|
 | 
						|
      #ifdef S4MEM_PRINT
 | 
						|
         if ( v4print != -1 )
 | 
						|
         {
 | 
						|
            #ifdef S4WINDOWS
 | 
						|
               #ifdef S4TESTING
 | 
						|
                  {
 | 
						|
                     d4displayStr( mem4displayPtr, "  Y4RELEASE:  ", 1 ) ;
 | 
						|
                     d4displayPtr( mem4displayPtr, memoryType, 0 ) ;
 | 
						|
                  }
 | 
						|
               #endif
 | 
						|
            #else
 | 
						|
               if ( v4print )
 | 
						|
                  fprintf( stdprn, "\r\n  Y4RELEASE:  %lx", memoryType ) ;
 | 
						|
               else
 | 
						|
                  printf( "\r\n  Y4RELEASE:  %lx", memoryType ) ;
 | 
						|
            #endif
 | 
						|
         }
 | 
						|
      #endif
 | 
						|
   }
 | 
						|
 | 
						|
   #ifdef S4SEMAPHORE
 | 
						|
      mem4stop( 0 ) ;
 | 
						|
   #endif
 | 
						|
}
 | 
						|
 | 
						|
#ifdef S4TESTING
 | 
						|
   int s4allocOff = 0 ;
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef S4MAX
 | 
						|
   static long mem4maxMemory = 16384 ;
 | 
						|
   static long mem4allocated = 0L ;
 | 
						|
 | 
						|
   long u4allocated( void )
 | 
						|
   {
 | 
						|
      return mem4allocated ;
 | 
						|
   }
 | 
						|
 | 
						|
   long u4max( void )
 | 
						|
   {
 | 
						|
      return mem4maxMemory ;
 | 
						|
   }
 | 
						|
#endif
 | 
						|
 | 
						|
void *S4FUNCTION u4allocDefault( long n )
 | 
						|
{
 | 
						|
   size_t s ;
 | 
						|
   char *ptr ;
 | 
						|
   #ifdef S4SEMAPHORE
 | 
						|
      #ifdef S4OS2
 | 
						|
         #ifdef __DLL__
 | 
						|
            ULONG    flags;
 | 
						|
            APIRET   rc;
 | 
						|
         #endif
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
   #ifdef S4WINDOWS
 | 
						|
      HANDLE  handle, *hPtr ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef S4TESTING
 | 
						|
      if ( s4allocOff == 1 )   /* for testing, emulate out of memory conditions */
 | 
						|
         return 0 ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef E4PARM_HIGH
 | 
						|
      if ( n == 0L )
 | 
						|
      {
 | 
						|
         error4( 0, e4parm, E85903 ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
      #ifdef E4MISC
 | 
						|
         n += mem4extraChars*2 + sizeof(unsigned) ;
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef S4MAX
 | 
						|
      n += sizeof( long ) ;   /* room for length */
 | 
						|
      if ( mem4allocated + n > mem4maxMemory )
 | 
						|
         return 0 ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   s = (size_t) n ;
 | 
						|
   if ( n > (long) s )
 | 
						|
      return 0 ;
 | 
						|
 | 
						|
   #ifdef S4WINDOWS
 | 
						|
      #ifdef __DLL__
 | 
						|
         handle = GlobalAlloc( GMEM_MOVEABLE | GMEM_DDESHARE | GMEM_ZEROINIT, (DWORD) s+ sizeof(HANDLE) ) ;
 | 
						|
      #else
 | 
						|
         handle = GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, (DWORD) s+ sizeof(HANDLE) ) ;
 | 
						|
      #endif
 | 
						|
 | 
						|
      if ( handle == (HANDLE)0 )
 | 
						|
         return 0 ;
 | 
						|
 | 
						|
      hPtr = (HANDLE *)GlobalLock( handle ) ;
 | 
						|
      *hPtr++ = handle ;
 | 
						|
      ptr = (char *)hPtr ;
 | 
						|
   #else
 | 
						|
      #ifdef __DLL__
 | 
						|
         #ifdef S4OS2_SEMAPHORE
 | 
						|
            flags = PAG_WRITE | PAG_READ | OBJ_GETTABLE ;
 | 
						|
            rc = DosAllocSharedMem( (void *)&ptr, 0, s, flags ) ;
 | 
						|
 | 
						|
            if (rc != 0)
 | 
						|
               return 0 ;
 | 
						|
            flags = PAG_WRITE | PAG_READ ;
 | 
						|
            rc = DosGetSharedMem( ptr, flags ) ;
 | 
						|
            if ( rc != 0 )
 | 
						|
               return 0 ;
 | 
						|
         #else
 | 
						|
            ptr = (char *)malloc( s ) ;
 | 
						|
 | 
						|
            if ( ptr == 0 )
 | 
						|
               return 0 ;
 | 
						|
 | 
						|
            #ifndef S4PASCAL_WIN
 | 
						|
               memset( ptr, 0, s ) ;
 | 
						|
            #endif
 | 
						|
         #endif
 | 
						|
      #else
 | 
						|
         ptr = (char *)malloc( s ) ;
 | 
						|
 | 
						|
         if ( ptr == 0 )
 | 
						|
            return 0 ;
 | 
						|
 | 
						|
                              /* Borland malloc of 64K (or close to) will */
 | 
						|
         #ifdef __TURBOC__    /* result in corruption of segment memory due */
 | 
						|
            if ( (ptr+s-1 <= ptr) && (s > 1 ))    /* to wrap-around problems  */
 | 
						|
            {
 | 
						|
               free( ptr ) ;
 | 
						|
               return 0 ;
 | 
						|
            }
 | 
						|
         #endif
 | 
						|
 | 
						|
         #ifndef S4PASCAL_WIN
 | 
						|
            memset( ptr, 0, s ) ;
 | 
						|
         #endif
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef S4MEM_PRINT
 | 
						|
      if ( v4print != -1 )
 | 
						|
      {
 | 
						|
         #ifdef S4WINDOWS
 | 
						|
            #ifdef S4TESTING
 | 
						|
               {
 | 
						|
                  d4displayStr( mem4displayPtr, "  U4ALLOC:  ", 1 ) ;
 | 
						|
                  d4displayPtr( mem4displayPtr, ptr, 0 ) ;
 | 
						|
                  d4displayStr( mem4displayPtr, "  file:  ", 0 ) ;
 | 
						|
                  d4displayStr( mem4displayPtr, m4fileName, 0 ) ;
 | 
						|
                  d4displayStr( mem4displayPtr, "  line:  ", 0 ) ;
 | 
						|
                  d4displayNum( mem4displayPtr, m4lineNo, 0 ) ;
 | 
						|
                  d4displayStr( mem4displayPtr, "  num bytes:  ", 0 ) ;
 | 
						|
                  d4displayNum( mem4displayPtr, n, 0 ) ;
 | 
						|
               }
 | 
						|
            #endif
 | 
						|
         #else
 | 
						|
            if ( v4print )
 | 
						|
               fprintf( stdprn, "\r\n  U4ALLOC:  %lx  file:  %s  line:  %12d  num bytes:  %12ld", ptr, m4fileName, m4lineNo, n ) ;
 | 
						|
            else
 | 
						|
               printf("\r\n  U4ALLOC:  %lx  file:  %s  line:  %12d  num bytes:  %12ld", ptr, m4fileName, m4lineNo, n ) ;
 | 
						|
         #endif
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef E4MISC
 | 
						|
      #ifdef S4SEMAPHORE
 | 
						|
         mem4start( 0 ) ;
 | 
						|
      #endif
 | 
						|
      ptr = mem4fixPointer( ptr, s ) ;
 | 
						|
      mem4pushPointer( ptr ) ;
 | 
						|
      memset( ptr, 0, s-mem4extraChars*2 - sizeof(unsigned) ) ;
 | 
						|
      #ifdef S4SEMAPHORE
 | 
						|
         mem4stop( 0 ) ;
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef S4MAX
 | 
						|
      #ifdef S4SEMAPHORE
 | 
						|
         mem4start( 0 ) ;
 | 
						|
      #endif
 | 
						|
      mem4allocated += n ;
 | 
						|
      #ifdef S4SEMAPHORE
 | 
						|
         mem4stop( 0 ) ;
 | 
						|
      #endif
 | 
						|
      *((long *)ptr) = n ;
 | 
						|
      ptr += sizeof( long ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   return (void *)ptr ;
 | 
						|
}
 | 
						|
 | 
						|
void S4FUNCTION u4freeFixedDefault( FIXED4MEM fixedMem )
 | 
						|
{
 | 
						|
   #ifdef S4USE_LOW_MEMORY
 | 
						|
      if ( ( GetWinFlags() & WF_ENHANCED ) == WF_ENHANCED )
 | 
						|
         GlobalPageUnlock( (HGLOBAL)s4protected( fixedMem ) ) ;
 | 
						|
      GlobalDosFree( (HGLOBAL)s4protected( fixedMem ) ) ;
 | 
						|
   #else
 | 
						|
      u4freeDefault( fixedMem ) ;
 | 
						|
   #endif
 | 
						|
}
 | 
						|
 | 
						|
/* u4alloc_fixed() allocates fixed memory blocks in the lower 1 MEG of ram.
 | 
						|
   It is used for allocating memory that is to be used with DOS interrupts.
 | 
						|
*/
 | 
						|
FIXED4MEM S4FUNCTION u4allocFixedDefault( CODE4 *c4, long n )
 | 
						|
{
 | 
						|
   #ifdef S4USE_LOW_MEMORY
 | 
						|
      size_t s ;
 | 
						|
      FIXED4MEM fixedMem ;
 | 
						|
 | 
						|
      memset( &fixedMem, 0, sizeof( FIXED4MEM ) ) ;
 | 
						|
 | 
						|
      #ifdef E4PARM_LOW
 | 
						|
         if ( c4 == 0 )
 | 
						|
         {
 | 
						|
            error4( 0, e4parm_null, E95908 ) ;
 | 
						|
            return fixedMem ;
 | 
						|
         }
 | 
						|
 | 
						|
         if ( n == 0L )
 | 
						|
         {
 | 
						|
            error4( c4, e4parm, E85903 ) ;
 | 
						|
            return fixedMem ;
 | 
						|
         }
 | 
						|
         n += mem4extraChars*2 + sizeof(unsigned) ;
 | 
						|
      #endif
 | 
						|
 | 
						|
      s = (size_t)n ;
 | 
						|
      if ( n > (long)s )
 | 
						|
         return fixedMem ;
 | 
						|
 | 
						|
      #ifdef __DLL__
 | 
						|
         fixedMem.block = GlobalDosAlloc( (DWORD)s + sizeof(HANDLE) ) ;
 | 
						|
      #else
 | 
						|
         fixedMem.block = GlobalDosAlloc( (DWORD)s + sizeof(HANDLE) ) ;
 | 
						|
      #endif
 | 
						|
 | 
						|
      if ( fixedMem.block == 0 )
 | 
						|
         return fixedMem ;
 | 
						|
 | 
						|
      if ( ( GetWinFlags() & WF_ENHANCED ) == WF_ENHANCED )
 | 
						|
         GlobalPageLock( (HGLOBAL)s4protected( fixedMem ) ) ;
 | 
						|
 | 
						|
      memset( (void *)s4protected( fixedMem ), 0, (size_t)n ) ;
 | 
						|
      return fixedMem ;
 | 
						|
   #else
 | 
						|
      return u4allocFreeDefault( c4, n ) ;
 | 
						|
   #endif
 | 
						|
}
 | 
						|
 | 
						|
void *S4FUNCTION u4allocErDefault( CODE4 *c4, long n )
 | 
						|
{
 | 
						|
   void *ptr = (void *)u4allocFreeDefault( c4, n ) ;
 | 
						|
   if ( ptr == 0 && c4 )
 | 
						|
      error4( c4, e4memory, E95909 ) ;
 | 
						|
 | 
						|
   return ptr ;
 | 
						|
}
 | 
						|
 | 
						|
int S4FUNCTION u4freeDefault( void *ptr )
 | 
						|
{
 | 
						|
   int rc ;
 | 
						|
   #ifdef S4WINDOWS
 | 
						|
      HANDLE  hand ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef S4MAX
 | 
						|
      long amount ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   rc = 0 ;
 | 
						|
 | 
						|
   if ( code4numCodeBase() == 0 )
 | 
						|
      return 0 ;
 | 
						|
 | 
						|
   if ( ptr == 0 )
 | 
						|
      return 0 ;
 | 
						|
 | 
						|
   #ifdef S4MAX
 | 
						|
      ptr = ((char *)ptr) - sizeof( long ) ;
 | 
						|
      amount = *((long *)ptr) ;
 | 
						|
      #ifdef S4SEMAPHORE
 | 
						|
         mem4start( 0 ) ;
 | 
						|
      #endif
 | 
						|
      mem4allocated -= amount ;
 | 
						|
      #ifdef S4SEMAPHORE
 | 
						|
         mem4stop( 0 ) ;
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef S4WINDOWS
 | 
						|
      #ifdef E4MISC
 | 
						|
         rc = mem4popPointer( (char *)ptr ) ;
 | 
						|
         ptr = mem4checkPointer( (char *)ptr, 1 ) ;
 | 
						|
         if ( (char *)ptr == 0 )  /* error during mem check */
 | 
						|
            return -1 ;
 | 
						|
         hand = ((HANDLE *)(char *)ptr)[-1] ;
 | 
						|
      #else
 | 
						|
         hand = ((HANDLE *)ptr)[-1] ;
 | 
						|
      #endif
 | 
						|
 | 
						|
      #ifdef S4MEM_PRINT
 | 
						|
         if ( v4print != -1 )
 | 
						|
         {
 | 
						|
            #ifdef S4WINDOWS
 | 
						|
               #ifdef S4TESTING
 | 
						|
                  d4displayStr( mem4displayPtr, "  U4FREE:   ", 1 ) ;
 | 
						|
                  d4displayPtr( mem4displayPtr, ptr, 0 ) ;
 | 
						|
                  d4displayStr( mem4displayPtr, "  file:  ", 0 ) ;
 | 
						|
                  d4displayStr( mem4displayPtr, m4fileName, 0 ) ;
 | 
						|
                  d4displayStr( mem4displayPtr, "  line:  ", 0 ) ;
 | 
						|
                  d4displayNum( mem4displayPtr, m4lineNo, 0 ) ;
 | 
						|
               #endif
 | 
						|
            #endif
 | 
						|
         }
 | 
						|
      #endif
 | 
						|
      GlobalUnlock( hand ) ;
 | 
						|
      hand = GlobalFree( hand ) ;
 | 
						|
 | 
						|
      if ( hand != (HANDLE) 0 )
 | 
						|
         return error4( 0, e4memory, E95910 ) ;
 | 
						|
   #else
 | 
						|
      #ifdef E4MISC
 | 
						|
         #ifdef S4SEMAPHORE
 | 
						|
            mem4start( 0 ) ;
 | 
						|
         #endif
 | 
						|
         rc = mem4popPointer( (char *)ptr ) ;
 | 
						|
         ptr = mem4checkPointer( (char *)ptr, 1 ) ;
 | 
						|
         #ifdef S4SEMAPHORE
 | 
						|
            mem4stop( 0 ) ;
 | 
						|
         #endif
 | 
						|
 | 
						|
         #ifdef S4MEM_PRINT
 | 
						|
            if ( v4print != -1 )
 | 
						|
            {
 | 
						|
               #ifdef S4WINDOWS
 | 
						|
                  #ifdef S4TESTING
 | 
						|
                     {
 | 
						|
                        d4displayStr( mem4displayPtr, "  U4FREE:  ", 1 ) ;
 | 
						|
                        d4displayPtr( mem4displayPtr, ptr, 0 ) ;
 | 
						|
                        d4displayStr( mem4displayPtr, "  file:  ", 0 ) ;
 | 
						|
                        d4displayStr( mem4displayPtr, m4fileName, 0 ) ;
 | 
						|
                        d4displayStr( mem4displayPtr, "  line:  ", 0 ) ;
 | 
						|
                        d4displayNum( mem4displayPtr, m4lineNo, 0 ) ;
 | 
						|
                     }
 | 
						|
                  #endif
 | 
						|
               #else
 | 
						|
                  if ( v4print )
 | 
						|
                     fprintf( stdprn, "\r\n  U4FREE:  %lx  file:  %s  line:  %12d", ptr, m4fileName, m4lineNo  ) ;
 | 
						|
                  else
 | 
						|
                     printf( "\r\n U4FREE:  %lx  file:  %s  line:  %12d", ptr, m4fileName, m4lineNo  );
 | 
						|
               #endif
 | 
						|
            }
 | 
						|
         #endif
 | 
						|
 | 
						|
         free( ptr ) ;
 | 
						|
      #else
 | 
						|
         #ifdef S4MEM_PRINT
 | 
						|
            if ( v4print != -1 )
 | 
						|
            {
 | 
						|
               #ifdef S4WINDOWS
 | 
						|
                  #ifdef S4TESTING
 | 
						|
                     {
 | 
						|
                        d4displayStr( mem4displayPtr, "  U4FREE:  ", 1 ) ;
 | 
						|
                        d4displayPtr( mem4displayPtr, ptr, 0 ) ;
 | 
						|
                        d4displayStr( mem4displayPtr, "  file:  ", 0 ) ;
 | 
						|
                        d4displayStr( mem4displayPtr, m4fileName, 0 ) ;
 | 
						|
                        d4displayStr( mem4displayPtr, "  line:  ", 0 ) ;
 | 
						|
                        d4displayNum( mem4displayPtr, m4lineNo, 0 ) ;
 | 
						|
                     }
 | 
						|
                  #endif
 | 
						|
               #else
 | 
						|
                  if ( v4print )
 | 
						|
                     fprintf( stdprn, "\r\n  U4FREE:  %lx  file:  %s  line:  %12d", ptr, m4fileName, m4lineNo  ) ;
 | 
						|
                  else
 | 
						|
                     printf( "\r\n  U4FREE:  %lx  file:  %s  line:  %12d", ptr, m4fileName, m4lineNo  );
 | 
						|
               #endif
 | 
						|
            }
 | 
						|
         #endif
 | 
						|
 | 
						|
         free( ptr ) ;
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   return rc ;
 | 
						|
}
 | 
						|
 | 
						|
int mem4reset( void )
 | 
						|
{
 | 
						|
   MEM4 *onType ;
 | 
						|
   LINK4 *onChunk, *onGroup ;
 | 
						|
   #ifdef S4WINDOWS
 | 
						|
      #ifdef E4MISC
 | 
						|
         HANDLE hand ;
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
   #ifdef S4LOCK_CHECK
 | 
						|
      return error4( 0, e4result, E85904 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   for( onType = 0 ;; )
 | 
						|
   {
 | 
						|
      onType = (MEM4 *)l4next(&used,onType) ;
 | 
						|
      if ( onType == 0 )
 | 
						|
         break ;
 | 
						|
      do
 | 
						|
      {
 | 
						|
         onChunk = (LINK4 *)l4pop( &onType->chunks) ;
 | 
						|
         u4freeDefault( onChunk ) ;  /* free of 0 still succeeds */
 | 
						|
      } while ( onChunk ) ;
 | 
						|
   }
 | 
						|
 | 
						|
   for( ;; )
 | 
						|
   {
 | 
						|
      onGroup = (LINK4 *)l4pop( &groups ) ;
 | 
						|
      if ( onGroup == 0 )
 | 
						|
         break ;
 | 
						|
      u4freeDefault( onGroup ) ;
 | 
						|
   }
 | 
						|
 | 
						|
   #ifdef E4MISC
 | 
						|
      if ( mem4numPointer > 0 )
 | 
						|
      {
 | 
						|
         #ifdef S4WINDOWS
 | 
						|
            hand = ((HANDLE *)mem4testPointers)[-1] ;
 | 
						|
 | 
						|
            GlobalUnlock( hand ) ;
 | 
						|
            hand = GlobalFree( hand ) ;
 | 
						|
 | 
						|
            if ( hand != (HANDLE)0 )
 | 
						|
               return error4( 0, e4memory, E95911 ) ;
 | 
						|
         #else
 | 
						|
            #ifdef S4MEM_PRINT
 | 
						|
               if ( v4print != -1 )
 | 
						|
               {
 | 
						|
                  #ifdef S4WINDOWS
 | 
						|
                     #ifdef S4TESTING
 | 
						|
                        {
 | 
						|
                           d4displayStr( mem4displayPtr, "  MEM4RESET:  ", 1 ) ;
 | 
						|
                           d4displayPtr( mem4displayPtr, mem4testPointers, 0 ) ;
 | 
						|
                     #endif
 | 
						|
                  #else
 | 
						|
                     if ( v4print )
 | 
						|
                        fprintf( stdprn, "\r\n  MEM4RESET:  %lx", mem4testPointers ) ;
 | 
						|
                     else
 | 
						|
                        printf( "\r\n  MEM4RESET:  %lx", mem4testPointers );
 | 
						|
                  #endif
 | 
						|
               }
 | 
						|
            #endif
 | 
						|
 | 
						|
            free( (void *)mem4testPointers ) ;
 | 
						|
         #endif
 | 
						|
 | 
						|
         mem4testPointers = 0 ;
 | 
						|
         mem4numPointer = -1 ;
 | 
						|
         mem4numUsed = 0 ;
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   mem4init() ;
 | 
						|
 | 
						|
   #ifdef S4SEMAPHORE
 | 
						|
      #ifdef S4WIN32
 | 
						|
         DeleteCriticalSection( &critical4memory ) ;
 | 
						|
         DeleteCriticalSection( &critical4expression ) ;
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef S4SEMAPHORE
 | 
						|
      #ifdef S4WIN32
 | 
						|
         memoryInitialized = 0 ;
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
void mem4init( void )
 | 
						|
{
 | 
						|
   if ( code4numCodeBase() != 0 )
 | 
						|
      return ;
 | 
						|
 | 
						|
   #ifdef S4SEMAPHORE
 | 
						|
      #ifdef S4WIN32
 | 
						|
         memoryInitialized = 1 ;
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef S4SEMAPHORE
 | 
						|
      #ifdef S4WIN32
 | 
						|
         InitializeCriticalSection( &critical4memory ) ;
 | 
						|
         InitializeCriticalSection( &critical4expression ) ;
 | 
						|
      #endif
 | 
						|
      mem4start( 0 ) ;
 | 
						|
   #endif
 | 
						|
   memset( (void *)&avail, 0, sizeof( avail ) ) ;
 | 
						|
   memset( (void *)&used, 0, sizeof( used ) ) ;
 | 
						|
   memset( (void *)&groups, 0, sizeof( groups ) ) ;
 | 
						|
   #ifdef S4SEMAPHORE
 | 
						|
      mem4stop( 0 ) ;
 | 
						|
   #endif
 | 
						|
}
 | 
						|
 |