/* Copyright (C) 1993 by Thomas Glen Smith. All Rights Reserved. */
/* getcb APL2 V1.0.1 ***************************************************
* Called to obtain an initialized APLCB. *
* 971211 Smitty changed to handle bus errors on HPUX. *
***********************************************************************/
#define INCLUDES APLMEM+APLCB
#include "includes.h"
#include <limits.h>
Aplcb getcb(dataptr,datacnt,datatyp,rank,dimptr)
void *dataptr; /* data address */
int datacnt, datatyp, rank, *dimptr /* dimensions */;
{
Chrcopy; Intcopy;
extern int aplerr;
Aplcb out;
long int ilong,jlong;
int bump=0,datasize,i,*ip,protocnt=0,typ,unitsize;
char *cp;
void **vp;
if (datacnt < 0) { aplerr = 92; return(NULL); } /* too big */
switch (typ = datatyp & (APLMASK + APLAPL)) {
case APLCPLX:
unitsize=sizeof(double);
datasize=unitsize*2;
break;
case APLNUMB:
unitsize=datasize=sizeof(double);
break;
case APLINT:
unitsize=datasize=sizeof(int);
break;
case APLCHAR:
unitsize=datasize=sizeof(char);
bump=1; /* Allow room for \0 at end. */
break;
case APLAPL:
unitsize=datasize=sizeof(Aplcb);
if (datacnt == 0) protocnt = 1;
break;
default: aplerr=999; return(NULL);
} /* end switch */
jlong = sizeof(struct aplcb) + rank*sizeof(int);
if (jlong % (long int) unitsize)
jlong = ((jlong / (long int) datasize)+1)*(long int) datasize;
/* jlong is size before data starts. */
ilong = (long int) datasize * ((long int) datacnt
+ (long int) protocnt) + jlong + (long int) bump;
/* ilong is size to allocate. */
if (ilong > INT_MAX) { aplerr = 92; return(NULL); } /* too big */
if (NULL == (out=malloc((int) ilong))) return(NULL);
cp = jlong + (char *)out; /* Point where data starts. */
out->aplsize = datasize;
out->aplcount = datacnt;
out->aplflags = datatyp;
out->aplrank = rank;
out->aplptr.aplchar = (datacnt + protocnt) ? cp : NULL;
out->apldim = (rank) ? ((int *)(out+1)) : NULL;
if (bump) *(cp + datacnt) = '\0'; /* Delimit string. */
if (dataptr != NULL && (datacnt + protocnt) != 0) {
cp = chrcopy(out->aplptr.aplchar,dataptr,datasize*datacnt,1);
free(dataptr); /* copy, then free data */
}
else if (protocnt) *((void **)out->aplptr.aplchar) = NULL;
else if (typ == APLAPL && datacnt)
for (i=datacnt, vp = (void **)cp; i; i--) *vp++ = NULL;
if (rank != 0) {
if (dimptr != NULL) {
ip = intcopy(out->apldim,dimptr,rank,1);
free(dimptr); /* copy, then free input dimensions */
}
else if (rank==1) *(out->apldim)=datacnt; /* vector */
}
if (aplerr) { endoper(out); out = NULL; }
return(out);
}