/* @(#)lpimemm.t	128.1 1/20/93 17:57:07  */
/************************************************************************\
   Copyright (C) 1990 Lotus Development Corporation.  All rights reserved.
   Name:    lpimemm.t
   Date:    17 Aug 1988
   Description:  define memory allocation and deallocation macros
\************************************************************************/
#if !defined(LPIMEMM_T)
#define LPIMEMM_T
#define AUTOMAP_H
/* in general MAP_REQUIRED is required for EMS memory use.  It is not
   normally required for allocation systems that return real pointers, or
   for systems whose mapping is automatically done, such as protected-mode
   286 and 386 systems such as OS/2  */
#define MAP_REQUIRED
/* can also #define UNMAP_REQUIRED  */
/**************************************************************************/
/*
This file uses some specific defines:
The following two are defined in ltsdefs.h:
to get the most effective type checking, declare pointers and mptrs using
these macros and the specific type of memory to be used.
lptr(x)  far pointer to type x
lmhdl(x) mptr which, when mapped, points to type x
The following are function-like defines used to control the interface to the
memory-management functions:
LpiAllocMem(t,l,v)  allocates a tag to memory of type t, of length l, using
map VMR v.  v is generally irrelevant in OS/2 but necessary in DOS.  These
macros cast l to a lulong since short lengths are common.  This means that
there is little typechecking on this argument.
Returns:  lmhdl(t), a tag to the allocated memory area
LpiFreeMem(m,l)   deallocates memory tag m of length l.  The Blueprint
scheme allows the return of a status.  however, it should always work.  test
with something like:
  status = (LpiFreeMem(...) == 0); assert(status);
Returns:  boolean:  LFALSE if deallocation FAILED
LpiCheckMem(m)  is LTRUE if memory tag m is the NULL memory tag - i.e no memory
LpiMapMem(m,v) maps a generic memory tag to a generic pointer using VMR v
  mapping should always work.  test with something like:
  assert(LpiMapMem(...) != NULL);
Returns: lptr(void), a real pointer to the memory area
LpiUnmapMem(m,v) unmaps a generic memory tag using VMR v.  This tells the
memory manager that the program no longer needs the mapped pointer.
Returns: void
The following are equivalent function calls for macros that map memory tags
to real pointers of the same memory types.
returned            macro name and type of argument
 -------            --------------
lptr(char)        CHAR_PTR(lmhdl(char));          (source) char string
lptr(char)        CHARD_PTR(lmhdl(char));         (dest) char string
lptr(LpiADTUTIL)   LpiADTUTL_PTR(lmhdl(LpiADTUTIL)); LpiADTUTIL structure
lptr(struct adt_inst_) LpiADTI_PTR(lmhdl(struct adt_inst_);
lptr(struct adt_inst_) LpiADTIS_PTR(lmhdl(struct adt_inst_);
       an ADT instance, if struct adt_inst_ is defined for the ADT
Unmap macros for the respective maps
void    CHAR_UNMP(lmhdl(char));
void    CHARD_UNMP(lmhdl(char));
void    LpiADTUTL_UNMP(lmhdl(LpiADTUTIL));
void    LpiADTI_UNMP(lmhdl(struct adt_inst_));
void    LpiADTIS_UNMP(lmhdl(struct adt_inst_));
*/
/**************************************************************************/
/* map registers defined for LIMspec use.  not relevant in OS/2           */
#define CHAR_REG     0      /* string pointer */
#define CHARD_REG    1      /* second string pointer, dest in copies */
#define MBCSS_REG    0      /* general mbcs use, source in copies    */
#define MBCSD_REG    1      /* general mbcs use, dest in copies      */
#define LpiADTUTL_REG 0      /* utility vector for an ADT             */
#define LpiADTI_REG   3      /* ADT instance                          */
#define LpiADTIS_REG  0      /* second (source) ADT reg for copying   */
#define INDATA_REG   0      /* for calling into other LPI routines  */
#define OUTDATA_REG  3      /* for returns from other LPI routines  */
/**************************************************************************/
#if defined(SYM_CHK)   /* prototypes for type checking, NOT code generation */
#include "chkmmem.t"
#else                  /* if !defined(SYM_CHK)  */
/**************************************************************************/
#if LPI_ENVIRONMENT == LPI_123R3PC  /* 123R3  memory management */
#if LTRUE              /* DataLens-like environment block calls */
/**************************************************************************/
/* LpiPEnvblk is a pointer to the environment block; a standard
   definition is given in lpiprim.h
*/
#define LpiAllocMem(t,l,v) (lmhdl(t))((*(LpiPEnvblk->get))\
                                                   ((lulong)l,v))
#define LpiFreeMem(m,l)  (*(LpiPEnvblk->free))(m,(lulong)l)
#define NULL_MEM_HANDLE  (LpiPEnvblk->nulh)
#define LpiCheckMem(m)  (NULL_MEM_HANDLE==(lmhdl(void))(m))
#if defined(MAP_REQUIRED)
#define LpiMapMem(m,v) ((*(LpiPEnvblk->map))(m,v))
#if defined(UNMAP_REQUIRED)
#define LpiUnmapMem(m,v) ((*(LpiPEnvblk->unmap))(m,v))
#else                    /* mapping but no unmapping required */
#define LpiUnmapMem(m,v)
#endif                   /* unmapping choices */
#else                     /* no mapping required */
#define LpiMapMem(m,v) (m)
#define LpiUnmapMem(m,v)
#endif                    /*  mapping/no mapping choices */
/**************************************************************************/
#endif                 /* #if LTRUE */
/**************************************************************************/
/**************************************************************************/
#else
#if (LPI_ENVIRONMENT == LPI_GPLATFORM)  /* G environment */
/* for the following we need specific allocator and deallocator refs */
#define LpiAllocMem(t,l,v)   (lmhdl(t))MMBlkAlloc(l,0)
#define LpiFreeMem(m,l)    MMBlkFree(m)
#define LpiCheckMem(m)       (NULL==(m))
#define LpiMapMem(m,v)     (m)
#define LpiUnmapMem(m,v)
#define AMPautoMapInit(x,y)
#define AMPgetMem(x) LpiAllocMem(void,x,0)
#define AMPmap(x)  (x)
#define AMPmapLock(x) (x)
#define AMPunMap(x)
#define AMPunMapAll()
#define AMPfree(x,l) LpiFreeMem(x,l)
#else                  /* not portable but general system definitions */
/**************************************************************************/
/* for the following we need specific allocator and deallocator refs */
#define LpiAllocMem(t,l,v)   (lmhdl(t))malloc(l)
#define LpiFreeMem(m,l)    free(m)
#define LpiCheckMem(m)       (NULL==(m))
#define LpiMapMem(m,v)     (m)
#define LpiUnmapMem(m,v)
#define AMPautoMapInit(x,y)
#define AMPgetMem(x) LpiAllocMem(void,x,0)
#define AMPmap(x)  (x)
#define AMPmapLock(x) (x)
#define AMPunMap(x)
#define AMPunMapAll()
#define AMPfree(x,l) LpiFreeMem(x,l)
/**************************************************************************/
#endif                 /* general system definitions */
#endif                 /* general system definitions */
/**************************************************************************/
/* specific maps/unmaps */
#define CHAR_PTR(m)      (lptr(char))LpiMapMem(m,CHAR_REG)
#define CHARD_PTR(m)     (lptr(char))LpiMapMem(m,CHARD_REG)
#define LpiADTUTL_PTR(m)  (lptr(LpiADTUTIL))LpiMapMem(m,LpiADTUTL_REG)
#define LpiADTI_PTR(m)    (lptr(struct adt_inst_))LpiMapMem(m,LpiADTI_REG)
#define LpiADTIS_PTR(m)   (lptr(struct adt_inst_))LpiMapMem(m,LpiADTIS_REG)
#define INDATA_PTR(m)    (lptr(LpiDATA))LpiMapMem(m,INDATA_REG)
#define OUTDATA_PTR(m)   (lptr(LpiDATA))LpiMapMem(m,OUTDATA_REG)
#define CHAR_UNMP(m)     LpiUnmapMem(m,CHAR_REG)
#define CHARD_UNMP(m)    LpiUnmapMem(m,CHARD_REG)
#define LpiADTUTL_UNMP(m) LpiUnmapMem(m,LpiADTUTL_REG)
#define LpiADTI_UNMP(m)   LpiUnmapMem(m,LpiADTI_REG)
#define LpiADTIS_UNMP(m)  LpiUnmapMem(m,LpiADTIS_REG)
#define INDATA_UNMP(m)   LpiUnmapMem(m,INDATA_REG)
#define OUTDATA_UNMP(m)  LpiUnmapMem(m,OUTDATA_REG)
/* Automap defines to perform proper type casting */
#define AMPtypeGet(t,l)      ((lmhdl(t))AMPgetMem((lulong)l))
#define AMPtypeMap(t,h)      ((lptr(t))AMPmap(h))
#define AMPtypeMapLock(t,h)  ((lptr(t))AMPmapLock(h))
/**************************************************************************/
#endif                 /* !SYM_CHK  (real) macros */
/* Translate a pointer to a stack variable to an lmhdl
*
*  lmhdl = LpiLptrToLmhdl (sptr)
*
*  mptr: lmhdl(void) equivalent
*  sptr: stack pointer
*/
#define LpiLptrToLmhdl(x) ((lmhdl(void))x)

#if !C_PROGRAMMABILITY
/* Copy a pointer to a new lmhdl
 *
 * retval = LpiMakeLmhdl ( type, ph_new, p_old, length );
 *
 * Inputs:
 * -------
 *   type:      type of the memory to be allocated (ex. lmbcs, lushort)
 *   ph_new:    lptr(lmhdl(type))   - pointer to lmhdl to type, this is the
 *                  lmhdl that will be allocated
 *   p_old:     lptr(type)      - pointer to variable which will be copied
 *                  into ph_new
 *   length:    lushort - length (in bytes) of item to be copied
 *
 * Returns:
 * --------
 *   LEXIT_GOOD if successful
 *   LEXIT_BAD  if not successful (ie. unable to allocate memory)
 *
 */
/* include lpimemm.h if this is used */
#define LpiMakeLmhdl(t,mp,p,l) pl_mk_mptr(LpiPEnvblk,mp,p,(lushort)l)
#endif /* !C_PROGRAMMABILITY */

#endif                 /* LPIMEMM_T */
