/******************************************************************************
                              XALLOC.C
*******************************************************************************

File Name               : XALLOC.C
Project                 : Not Applicable
Revision Number         : 1.01
File Creation Date/Time : 04/15/92  
Programmer              : John E. Boon, Jr.
                          Copyright (c) John E. Boon, Jr. 1992
                          All Rights Reserved
Program Description     : This file contains functions that work in
                          conjunction with EXCEPT.H and EXCEPT.C to
                          implement Eiffel-like error handling.

                          The functions contained in this file are
                          for allocation and reallocation of dynamic
                          memory.
Runtime Environment
  Platform              : DOS 3.3
  Compiler Used         : Borland C++ Version 3.0
  Memory Required       : 640 K + recommended extended memory
  Math co-processor     : Compiled with Emulate Floating Point setting
Input Files Needed      : None
Temporary Files Needed  : None
Output Files Needed     : None
Error Processing        : 
  Condition Checked     :
  Handling Process      :
Updates Log             : 
  Change Number         : CH#1 7/10/92
  Change Description    : I modified the assertion mechanisms in the code
                          to account for realloc.  Realloc can take as a size
                          parameter the larger of the core left as reported
                          by farcoreleft() or the current block in use in
                          the heap for this structure, or the largest free
                          block in the heap.  The heap won't put free blocks
                          together.
******************************************************************************
                              XALLOC.C
*****************************************************************************/
#ifndef XALLOC_CODE

#define XALLOC_CODE

#include <alloc.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "except.c"

void* xcalloc(unsigned long int nitems, unsigned long int size);
void* xrealloc(void *block, unsigned long int size);

/******************************* XCALLOC *********************************/
void *xcalloc(unsigned long int nitems, unsigned long int size) {

   void *p;

   assert(size && nitems && ((nitems * size) < farcoreleft()));

   BEGIN_TRY {
      p = farcalloc(nitems, size);
      if (p == NULL) {
         assert(farheapcheck() !=_HEAPCORRUPT);
         FAIL(X_ERRNO);
      }
   }
   FAIL_TRY {
      if (X_Error == X_ERRNO)
         if ((heapcheck() != _HEAPCORRUPT) &&
            ((nitems * size) < farcoreleft()))
               RETRY;
   }
   END_TRY;

   assert(p);
   return(p);

}  /* END OF XCALLOC */

/******************************* XREALLOC ********************************/
void *xrealloc(void *block, unsigned long int size) {

   void *p;
   struct farheapinfo heapinfo;
   unsigned long int heap_in_use = 0L, largest_free = 0L, limit = 0L;

   heapinfo.ptr = NULL;
   while(farheapwalk(&heapinfo) == _HEAPOK) {
     if (!heapinfo.in_use) largest_free = max(heapinfo.size, largest_free);
     if (heapinfo.ptr == block) heap_in_use = heapinfo.size;
   }

   limit = max(farcoreleft(), heap_in_use);
   limit = max(limit, largest_free);

   assert((size > 0) && (size < limit));

   BEGIN_TRY {
      p = farrealloc(block, size);
      if (p == NULL) {
         assert(farheapcheck() !=_HEAPCORRUPT);
         FAIL(X_ERRNO);
      }
   }
   FAIL_TRY {
      if (X_Error == X_ERRNO)
         if (farheapcheck() != _HEAPCORRUPT)
            RETRY;
   }
   END_TRY;

   assert(p);
   return(p);

} /* END OF XREALLOC */
#endif