#include <stdio.h>
#include <stdlib.h>
#ifdef SYSV
      int zc_alloc(nelem,elsize,array,address,offset)
#else
      int zc_alloc_(nelem,elsize,array,address,offset)
#endif

      unsigned *nelem,*elsize,*address,*offset ;
      void *array;
/*
C----------------------------------------------------------------------
C
C.IDENTIFICATION: INTEGER Function ZC_ALLOC
C.LIBRARY:        VOS (experimental version)
C.AUTHOR:         L.Chiappetti - IFCTR Milano
C.VERSIONS:       0.0 - 21 Jul 92 - Original attempt
C.                0.1 - 1 Jun 94 - POSIX.1 attempt (DDF)
C 
C.PURPOSE:        Fortran-C-interface for malloc (NOT TO BE CALLED PUBLICLY)
C.METHOD:         call malloc plus bookkeeping
C
C.SYNTAX:         I = ZC_ALLOC(nelem,elsize,array,address,offset)
C.PARAMETERS:     see description of Z_ALLOC
C-                returns 0 for no error, -1 for memory allocation error
C.RESTRICTIONS:   use nelem as number of array elements and elsize=2,4,8 for 
C                 INTEGER(*2,*4) and REAL(*4,*8) values
C                 use nelem as string length and elsize=1 for CHARACTER*nelem
C                 (CHARACTER*n arrays are not supported) 
C.NOTES:          none
C.FILES:          none
C.REFERENCES:     C routine calloc
C
C----------------------------------------------------------------------
*/
      {
      size_t     loc_nelem,loc_elsize,loc_offset,i,j ;
      char *loc_address ;
      loc_nelem = *nelem;
      loc_elsize = *elsize;
/*
C     do the actual allocation 
*/ 
      loc_address= (char*) calloc(loc_nelem,loc_elsize) ;
      if (loc_address == NULL) return -1;
/*
C     prepare returned value if allocation successful
C     use a cast to unsigned INTEGER*4 
*/
      *address = (unsigned) loc_address;
/*
C     use a cast also for pointer arithmetics
C     the offset is normalized to "size" units
*/
      i = (unsigned) loc_address ;
      j = (unsigned) array ; 
      loc_offset = i - j ;
      loc_offset = loc_offset / loc_elsize; 
      *offset = loc_offset;
      return 0 ;
      }
