/******************************************************************************
*
*  NSSDC/CDF						IDL/CDF interface.
*
*  Version 1.5a, 21-Feb-97, Hughes STX.
*
*  Modification history:
*
*   V1.0   4-Sep-92, H Leckner	Original version.
*   V1.1  24-Jan-94, J Love	CDF V2.4.
*   V1.1a  6-Feb-94, J Love	DEC Alpha/OpenVMS port.
*   V1.1b 22-Feb-94, J Love	Spelling lesson.
*   V1.2  21-Dec-94, J Love	CDF V2.5.
*   V1.3  19-Jan-95, J Love	IRIX 6.0 (64-bit) although IDL isn't supported
*				on the Iris yet.  Fixed bug in `StoreLongArray'
*				involving the allocation of zero bytes (which
*				causes unpredictable results from `malloc').
*   V1.4  13-Mar-95, J Love	Solaris 2.3.  Moved inclusion of library
*				source files to end of this file.  IDL 4.0.
*   V1.4a 23-Mar-95, J Love	Changed to the IDL 4.0 macros/functions.
*				IDL 3.x is now a special case.
*   V1.4b 25-May-95, J Love	Added `cdfmem.c' to library sources.
*   V1.4c 12-Jun-95, J Love	EPOCH custom format.
*   V1.4d  8-Sep-95, J Love	Compilation with non-ANSI C compilers.
*   V1.5   9-Sep-96, J Love	CDF V2.6.
*   V1.5a 21-Feb-97, J Love	Removed RICE.
*
******************************************************************************/

#define BUILDINGforIDL

#include "cdflib.h"

#if !defined(PROTOs_)
#define IDL_CC_NOT_ANSI
#endif

#include "export.h"

#if !defined(IDL_TYP_LONG)
#define IDL_STRING STRING
#define IDL_ALLTYPES ALLTYPES
#define IDL_STRING_STR STRING_STR
#define IDL_BARR_INI_NOP BASICARR_INI_NOP
#define IDL_LONG LONG
#define IDL_VPTR VPTR
#define IDL_VARIABLE VARIABLE
#define IDL_TYP_BYTE TYP_BYTE
#define IDL_TYP_INT TYP_INT
#define IDL_TYP_LONG TYP_LONG
#define IDL_TYP_FLOAT TYP_FLOAT
#define IDL_TYP_DOUBLE TYP_DOUBLE
#define IDL_TYP_STRING TYP_STRING
#define IDL_TYP_STRUCT TYP_STRUCT
#define IDL_TYP_COMPLEX TYP_COMPLEX
#define IDL_TYP_UNDEF TYP_UNDEF
#define IDL_V_ARR V_ARR
#define IDL_StoreScalar store_scalar
#define IDL_VarCopy var_copy
#define IDL_StrStore str_store
#define IDL_StrDelete del_str
#define IDL_MakeTempArray make_temp_array
#endif

/******************************************************************************
* Miscellaneous macros.
******************************************************************************/

#define RETURNs2(_status,_argv) {StoreLong(_argv[2],(long)_status);return;}
#define sRETURN(_arg,_status) {StoreLong(_arg,(long)_status);return;}
#define strRETURN(_arg,_string) {StoreString(_arg,_string);return;}

#define eRETURN(_arg,_epoch) \
{double _tEpoch = (double) _epoch; \
StoreScalar (_arg, CDF_EPOCH, &_tEpoch); \
return;}

#define RETURNsX(_status,_cur,_argv) \
{StoreCDFid (_argv[0], _cur.cdf); \
StoreLong (_argv[1], (long) _cur.status); \
StoreLong (_argv[2], (long) _status); \
return;}

#define CSC(_status,_pStatus,_cur,_argv) { \
CDFstatus _tStatus = _status; \
if (_tStatus != CDF_OK) \
  if (_tStatus < CDF_WARN) { /* ERROR */ \
    RETURNsX(_tStatus,_cur,_argv) \
  } \
  else \
    if (_tStatus > CDF_OK) {  /* INFO */ \
      if (_pStatus >= CDF_OK) _pStatus = _tStatus; \
    } \
    else  /* WARNING */ \
      _pStatus = _tStatus; \
}

/******************************************************************************
* Function prototypes.
******************************************************************************/

STATICforIDL CDFstatus CDFlib PROTOARGs((
  struct CurStruct *Cur, long requiredFnc, ...
));

/******************************************************************************
* CastToCDFid.
******************************************************************************/

Logical CastToCDFid (idlVar, id)
IDL_VPTR idlVar;
CDFid *id;
{
  if ((idlVar->flags & IDL_V_ARR) != 0)
    return FALSE;
  else {
    switch (idlVar->type) {
      case IDL_TYP_LONG:
        *id = Int32toCDFid ((Int32) idlVar->value.l);
	break;
      default:
	return FALSE;
    }
  }
  return TRUE;
}

/******************************************************************************
* CastToLong.
******************************************************************************/

Logical CastToLong (idlVar, value)
IDL_VPTR idlVar;
long *value;
{
  if ((idlVar->flags & IDL_V_ARR) != 0)
    return FALSE;
  else {
    switch (idlVar->type) {
      case IDL_TYP_BYTE:
        *value = (long) idlVar->value.c;
	break;
      case IDL_TYP_INT:
        *value = (long) idlVar->value.i;
	break;
      case IDL_TYP_LONG:
        *value = (long) idlVar->value.l;
	break;
      case IDL_TYP_FLOAT:
        *value = (long) idlVar->value.f;
	break;
      case IDL_TYP_DOUBLE:
        *value = (long) idlVar->value.d;
	break;
      default:
	return FALSE;
    }
  }
  return TRUE;
}

/******************************************************************************
* CastToDouble.
******************************************************************************/

Logical CastToDouble (idlVar, value)
IDL_VPTR idlVar;
double *value;
{
  if ((idlVar->flags & IDL_V_ARR) != 0)
    return FALSE;
  else {
    switch (idlVar->type) {
      case IDL_TYP_BYTE:
        *value = (double) idlVar->value.c;
	break;
      case IDL_TYP_INT:
        *value = (double) idlVar->value.i;
	break;
      case IDL_TYP_LONG:
        *value = (double) idlVar->value.l;
	break;
      case IDL_TYP_FLOAT:
        *value = (double) idlVar->value.f;
	break;
      case IDL_TYP_DOUBLE:
        *value = (double) idlVar->value.d;
	break;
      default:
	return FALSE;
    }
  }
  return TRUE;
}

/******************************************************************************
* CastToCur.
******************************************************************************/

Logical CastToCUR (argv, Cur)
IDL_VPTR argv[];
struct CurStruct *Cur;
{
  long status;
  if (!CastToCDFid(argv[0],&Cur->cdf)) return FALSE;
  if (!CastToLong(argv[1],&status)) return FALSE;
  Cur->status = (CDFstatus) status;
  return TRUE;
}

/******************************************************************************
* BuildLongArray.
******************************************************************************/

Logical BuildLongArray (idlVar, array, maxElems)
IDL_VPTR idlVar;
long array[];
int maxElems;
{
  int n, i;
  if ((idlVar->flags & IDL_V_ARR) == 0) return FALSE;
  switch (idlVar->type) {
    case IDL_TYP_COMPLEX:
    case IDL_TYP_STRING:
    case IDL_TYP_STRUCT:
    case IDL_TYP_UNDEF:
      return FALSE;
  }
  if (idlVar->value.arr->n_dim > 1) return FALSE;
  if (idlVar->value.arr->n_elts == 0) return FALSE;
  n = MINIMUM (maxElems, idlVar->value.arr->n_elts);
  for (i = 0; i < n; i++) {
     switch (idlVar->type) {
       case IDL_TYP_BYTE:
	 array[i] = (long) (((char *) (idlVar->value.arr->data))[i]);
	 break;
       case IDL_TYP_INT:
	 array[i] = (long) (((short *) (idlVar->value.arr->data))[i]);
	 break;
       case IDL_TYP_LONG:
	 array[i] = (long) (((IDL_LONG *) (idlVar->value.arr->data))[i]);
	 break;
       case IDL_TYP_FLOAT:
	 array[i] = (long) (((float *) (idlVar->value.arr->data))[i]);
	 break;
       case IDL_TYP_DOUBLE:
	 array[i] = (long) ((double *) (idlVar->value.arr->data))[i];
	 break;
     }     
  }
  return TRUE;
}

/******************************************************************************
* StringPtr.
******************************************************************************/

Logical StringPtr (idlVar, string)
IDL_VPTR idlVar;
char **string;
{
  if ((idlVar->flags & IDL_V_ARR) == 0 && idlVar->type == IDL_TYP_STRING) {
    *string = IDL_STRING_STR (&(idlVar->value.str));
    return TRUE;
  }
  return FALSE;
}

/******************************************************************************
* DataPtr.
******************************************************************************/

Logical DataPtr (idlVar, data)
IDL_VPTR idlVar;
void **data;
{
  if ((idlVar->flags & IDL_V_ARR) != 0)
    *data = idlVar->value.arr->data;
  else
    switch (idlVar->type) {
      case IDL_TYP_BYTE:
        *data = &(idlVar->value.c);
	break;
      case IDL_TYP_INT:
        *data = &(idlVar->value.i);
	break;
      case IDL_TYP_LONG:
        *data = &(idlVar->value.l);
	break;
      case IDL_TYP_FLOAT:
        *data = &(idlVar->value.f);
	break;
      case IDL_TYP_DOUBLE:
        *data = &(idlVar->value.d);
	break;
      case IDL_TYP_COMPLEX:
        *data = &(idlVar->value.cmp);
	break;
      case IDL_TYP_STRING:
        *data = idlVar->value.str.s;
	break;
      case IDL_TYP_STRUCT:
	*data = idlVar->value.s.arr;
	break;
      case IDL_TYP_UNDEF:
	return FALSE;
    }
  return TRUE;
}

/******************************************************************************
* IDLdataType.
******************************************************************************/

int IDLdataType (cdfDataType)
long cdfDataType;
{
  switch (cdfDataType) {
    case CDF_BYTE:
    case CDF_INT1:
    case CDF_UINT1:
      return IDL_TYP_BYTE;
    case CDF_INT2:
    case CDF_UINT2:
      return IDL_TYP_INT;
    case CDF_INT4:
    case CDF_UINT4:
      return IDL_TYP_LONG;
    case CDF_REAL4:
    case CDF_FLOAT:
      return IDL_TYP_FLOAT;
    case CDF_REAL8:
    case CDF_DOUBLE:
    case CDF_EPOCH:
      return IDL_TYP_DOUBLE;
    case CDF_CHAR:
    case CDF_UCHAR:
      return IDL_TYP_STRING;
    default:
      return IDL_TYP_UNDEF;
  }
}

/******************************************************************************
* StoreMultiArray.
******************************************************************************/

Logical StoreMultiArray (idlVar, dataType, numElems, numDims, dimSizes, buffer)
IDL_VPTR idlVar;
long dataType;
long numElems;
long numDims;
long dimSizes[];
void *buffer;
{
  IDL_VPTR tempVar;
  long nValues, valueN;
  void *data;
  int dimN;
  IDL_LONG dimSizesT[CDF_MAX_DIMS];
  /****************************************************************************
  * If there are zero dimensions or the size of one of the dimensions is zero,
  * return without creating/loading an array.
  ****************************************************************************/
  if (numDims == 0) return TRUE;
  for (dimN = 0; dimN < numDims; dimN++) if (dimSizes[dimN] == 0) return TRUE;
  /****************************************************************************
  * Count the number of values to be stored.
  ****************************************************************************/
  nValues = 1;
  for (dimN = 0; dimN < numDims; dimN++) {
     nValues *= dimSizes[dimN];
     dimSizesT[dimN] = (IDL_LONG) dimSizes[dimN];
  }
  /****************************************************************************
  * Allocate a temporary IDL variable.
  ****************************************************************************/
  data = IDL_MakeTempArray (IDLdataType(dataType), (int) numDims, dimSizesT,
			    IDL_BARR_INI_NOP, &tempVar);
  if (data == NULL) return FALSE;
  /****************************************************************************
  * Load the temporary IDL variable.
  ****************************************************************************/
  if (STRINGdataType(dataType)) {
    IDL_STRING *str = data;
    char *buf = buffer;
    char *tmp = (char *) malloc (numElems + 1);
    if (tmp == NULL) return FALSE;
    for (valueN = 0; valueN < nValues; valueN++, str++, buf += numElems) {
       memmove (tmp, buf, numElems);
       tmp[numElems] = NUL;
       IDL_StrStore (str, tmp);
    }
    free (tmp);
    IDL_VarCopy (tempVar, idlVar);
  }
  else {
    size_t nBytes = nValues * CDFelemSize(dataType);
    memmove (data, buffer, nBytes);
    IDL_VarCopy (tempVar, idlVar);
  }
  return TRUE;
}

/******************************************************************************
* StoreLongArray.
*   IMPORTANT: Note that `count' is assumed to be CDF_MAX_DIMS or less.
******************************************************************************/

Logical StoreLongArray (idlVar, count, buffer)
IDL_VPTR idlVar;	/* IDL variable to create/recreate. */
long count;	/* Assumed to be CDF_MAX_DIMS or less. */
long buffer[];	/* Values to be assigned to the array. */
{
  Int32 tBuffer[CDF_MAX_DIMS]; int i;
  for (i = 0; i < count; i++) tBuffer[i] = (Int32) buffer[i];
  return StoreMultiArray (idlVar, CDF_INT4, 1L, 1L, &count, tBuffer);
}

/******************************************************************************
* StoreCDFid.
******************************************************************************/

void StoreCDFid (idlVar, id)
IDL_VPTR idlVar;
CDFid id;
{
  IDL_ALLTYPES temp;
  temp.l = (IDL_LONG) CDFidToInt32 (id);
  IDL_StoreScalar (idlVar, IDL_TYP_LONG, &temp);
  return;
}

/******************************************************************************
* StoreLong.
******************************************************************************/

void StoreLong (idlVar, value)
IDL_VPTR idlVar;
long value;
{
  IDL_ALLTYPES temp;
  temp.l = (IDL_LONG) value;
  IDL_StoreScalar (idlVar, IDL_TYP_LONG, &temp);
  return;
}

/******************************************************************************
* StoreScalar.
******************************************************************************/

void StoreScalar(tmp, data_type, value)
IDL_VPTR tmp;
long data_type;
void *value;
{
  IDL_ALLTYPES temp;
  switch(data_type){
    case CDF_REAL4:
    case CDF_FLOAT:
      temp.f = *((float *) value);
      IDL_StoreScalar (tmp, IDL_TYP_FLOAT, &temp);
      break;
    case CDF_REAL8:
    case CDF_DOUBLE:
    case CDF_EPOCH:
      temp.d = *((double *) value);
      IDL_StoreScalar (tmp, IDL_TYP_DOUBLE, &temp);
      break;
    case CDF_INT4:
    case CDF_UINT4:
      temp.l = *((IDL_LONG *) value);
      IDL_StoreScalar (tmp, IDL_TYP_LONG, &temp);
      break;
    case CDF_INT2:
    case CDF_UINT2:
      temp.i = *((short *) value);
      IDL_StoreScalar (tmp, IDL_TYP_INT, &temp);
      break;
    case CDF_BYTE:
    case CDF_INT1:
    case CDF_UINT1:
      temp.c = *((UCHAR *) value);
      IDL_StoreScalar (tmp, IDL_TYP_BYTE, &temp);
      break;
  }
  return;
}

/******************************************************************************
* StoreString.
******************************************************************************/

void StoreString (idlVar, str)
IDL_VPTR idlVar;
char *str;
{
  IDL_ALLTYPES temp;
  IDL_StrStore (&temp.str, str);
  IDL_StoreScalar (idlVar, IDL_TYP_STRING, &temp);
  IDL_StrDelete (&temp.str, (IDL_LONG) 1);
}

/******************************************************************************
* idl_cdfopen.
******************************************************************************/

void idl_cdfopen (argc, argv)
int argc;
IDL_VPTR argv[];
{
  char *CDF_name; CDFid id; CDFstatus status; struct CurStruct Cur;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!StringPtr(argv[3],&CDF_name)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   OPEN_, CDF_, CDF_name, &id, 
		   NULL_);
  if (StatusBAD(status)) RETURNsX(status,Cur,argv)
  StoreCDFid (argv[4], id);
  RETURNsX(status,Cur,argv)
}

/******************************************************************************
* idl_cdfdelete.
******************************************************************************/

void idl_cdfdelete (argc, argv)
int argc;
IDL_VPTR argv[];
{
  CDFid id; CDFstatus status; struct CurStruct Cur;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToCDFid(argv[3],&id)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id, 
		   DELETE_, CDF_,
		   NULL_);
  RETURNsX(status,Cur,argv)
}

/******************************************************************************
* idl_cdfinquire.
******************************************************************************/

void idl_cdfinquire (argc, argv)
int argc;
IDL_VPTR argv[];
{
  CDFid id; CDFstatus status; struct CurStruct Cur;
  long num_dims, dim_sizes[CDF_MAX_DIMS], encoding, majority;
  long max_record_num, num_vars, num_attrs;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToCDFid(argv[3],&id)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id, 
		   GET_, rVARs_NUMDIMS_, &num_dims,
		         rVARs_DIMSIZES_, dim_sizes,
		         CDF_ENCODING_, &encoding,
		         CDF_MAJORITY_, &majority,
		         rVARs_MAXREC_, &max_record_num,
		         CDF_NUMrVARS_, &num_vars,
		         CDF_NUMATTRS_, &num_attrs,
		   NULL_);
  if (StatusBAD(status)) RETURNsX(status,Cur,argv)
  StoreLong (argv[4], num_dims);
  if (!StoreLongArray(argv[5],
		      num_dims,
		      dim_sizes)) RETURNsX(BAD_MALLOC,Cur,argv)
  StoreLong (argv[6], encoding);
  StoreLong (argv[7], majority);
  StoreLong (argv[8], max_record_num);
  StoreLong (argv[9], num_vars);
  StoreLong (argv[10], num_attrs);
  RETURNsX(status,Cur,argv)
}

/******************************************************************************
* idl_cdfvarinq.
******************************************************************************/

void idl_cdfvarinq (argc, argv)
int argc;
IDL_VPTR argv[];
{
  CDFid id; CDFstatus status; struct CurStruct Cur;
  char var_mnemonic[CDF_VAR_NAME_LEN+1];
  long var_num, data_type, num_bytes, record_variance;
  long dim_variances[CDF_MAX_DIMS];
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToCDFid(argv[3],&id)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[4],&var_num)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id, 
			    rVAR_, var_num,
		   GET_, rVAR_NAME_, var_mnemonic,
		         rVAR_DATATYPE_, &data_type,
		         rVAR_NUMELEMS_, &num_bytes,
		         rVAR_RECVARY_, &record_variance,
		         rVAR_DIMVARYS_, dim_variances,
		   NULL_);
  if (StatusBAD(status)) RETURNsX(status,Cur,argv)
  StoreString (argv[5], var_mnemonic);
  StoreLong (argv[6], data_type);
  StoreLong (argv[7], num_bytes);
  StoreLong (argv[8], record_variance);
  if (!StoreLongArray(argv[9],
		      (long)CDF_MAX_DIMS,
		      dim_variances)) RETURNsX(BAD_MALLOC,Cur,argv)
  RETURNsX(status,Cur,argv)
}

/******************************************************************************
* idl_cdfvarclose.
******************************************************************************/

void idl_cdfvarclose (argc, argv)
int argc;
IDL_VPTR argv[];
{
  CDFid id; long var_num; CDFstatus status; struct CurStruct Cur;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToCDFid(argv[3],&id)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[4],&var_num)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id, 
			    rVAR_, var_num,
		   CLOSE_, rVAR_,
		   NULL_);
  RETURNsX(status,Cur,argv)
}

/******************************************************************************
* idl_cdfclose.
******************************************************************************/

void idl_cdfclose (argc, argv)
int argc;
IDL_VPTR argv[];
{
  CDFid id; CDFstatus status; struct CurStruct Cur;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToCDFid(argv[3],&id)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id, 
		   CLOSE_, CDF_,
		   NULL_);
  RETURNsX(status,Cur,argv)
}

/******************************************************************************
* idl_cdferror.
******************************************************************************/

void idl_cdferror(argc, argv)
int argc;
IDL_VPTR argv[];
{
  long error_code; char error_mes[CDF_STATUSTEXT_LEN+1];
  CDFstatus status; struct CurStruct Cur;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToLong(argv[3],&error_code)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_STATUS_, (CDFstatus) error_code,
		   GET_, STATUS_TEXT_, error_mes,
		   NULL_);
  if (StatusBAD(status)) RETURNsX(status,Cur,argv)
  StoreString (argv[4], error_mes);
  RETURNsX(status,Cur,argv)
}

/******************************************************************************
* idl_cdfdoc.
******************************************************************************/

void idl_cdfdoc (argc, argv)
int argc;
IDL_VPTR argv[];
{
  CDFid id; long version, release; CDFstatus status;
  char text[CDF_DOCUMENT_LEN+1]; struct CurStruct Cur;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToCDFid(argv[3],&id)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id, 
		   GET_, CDF_VERSION_, &version,
		         CDF_RELEASE_, &release,
		         CDF_COPYRIGHT_, text,
		   NULL_);
  if (StatusBAD(status)) RETURNsX(status,Cur,argv)
  StoreLong (argv[4], version);
  StoreLong (argv[5], release);
  StoreString(argv[6], text);
  RETURNsX(status,Cur,argv)
}

/******************************************************************************
* idl_cdfattrinq.
******************************************************************************/

void idl_cdfattrinq (argc, argv)
int argc;
IDL_VPTR argv[];
{
  CDFid id; CDFstatus status; char attr_mnemonic[CDF_ATTR_NAME_LEN+1];
  long attr_num, attr_scope, max_entry; struct CurStruct Cur;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToCDFid(argv[3],&id)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[4],&attr_num)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id, 
			    ATTR_, attr_num,
		   GET_, ATTR_SCOPE_, &attr_scope,
		   NULL_);
  if (StatusBAD(status)) RETURNsX(status,Cur,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id, 
			    ATTR_, attr_num,
		   GET_, ATTR_NAME_, attr_mnemonic,
		         ATTR_SCOPE_, &attr_scope,
		         BOO(attr_scope == GLOBAL_SCOPE,
			     ATTR_MAXgENTRY_,ATTR_MAXrENTRY_), &max_entry,
		   NULL_);
  if (StatusBAD(status)) RETURNsX(status,Cur,argv)
  StoreString(argv[5], attr_mnemonic);
  StoreLong (argv[6], attr_scope);
  StoreLong (argv[7], max_entry);
  RETURNsX(status,Cur,argv)
}

/******************************************************************************
* idl_cdfattreinq.
******************************************************************************/

void idl_cdfattreinq (argc, argv)
int argc;
IDL_VPTR argv[];
{
  CDFid id; CDFstatus status; struct CurStruct Cur;
  long attr_num, entry_num, data_type, num_elements, scope;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToCDFid(argv[3],&id)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[4],&attr_num)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[5],&entry_num)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id, 
			    ATTR_, attr_num,
		   GET_, ATTR_SCOPE_, &scope,
		   NULL_);
  if (StatusBAD(status)) RETURNsX(status,Cur,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id, 
			    ATTR_, attr_num,
			    BOO(scope == GLOBAL_SCOPE,
			        gENTRY_,rENTRY_), entry_num,
		   GET_, BOO(scope == GLOBAL_SCOPE,
			     gENTRY_DATATYPE_,rENTRY_DATATYPE_), &data_type,
		         BOO(scope == GLOBAL_SCOPE,
			     gENTRY_NUMELEMS_,rENTRY_NUMELEMS_),&num_elements,
		   NULL_);
  if (StatusBAD(status)) RETURNsX(status,Cur,argv)
  StoreLong (argv[6], data_type);
  StoreLong (argv[7], num_elements);
  RETURNsX(status,Cur,argv)
}

/******************************************************************************
* idl_cdfvarnum.
******************************************************************************/

void idl_cdfvarnum (argc, argv)
int argc;
IDL_VPTR argv[];
{
  CDFid id; char *var_mnemonic; long var_num;
  CDFstatus status; struct CurStruct Cur;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToCDFid(argv[3],&id)) RETURNs2(BAD_ARGUMENT,argv)
  if (!StringPtr(argv[4],&var_mnemonic)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id,
		   GET_, rVAR_NUMBER_, var_mnemonic, &var_num,
		   NULL_);
  if (StatusBAD(status)) RETURNsX(status,Cur,argv)
  RETURNsX(var_num,Cur,argv)
}

/******************************************************************************
* idl_cdfattrnum.
******************************************************************************/

void idl_cdfattrnum (argc, argv)
int argc;
IDL_VPTR argv[];
{
  CDFid id; char *attr_mnemonic; long attr_num;
  CDFstatus status; struct CurStruct Cur;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToCDFid(argv[3],&id)) RETURNs2(BAD_ARGUMENT,argv)
  if (!StringPtr(argv[4],&attr_mnemonic)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id,
		   GET_, ATTR_NUMBER_, attr_mnemonic, &attr_num,
		   NULL_);
  if (StatusBAD(status)) RETURNsX(status,Cur,argv)
  RETURNsX(attr_num,Cur,argv)
}

/******************************************************************************
* idl_cdfattrget.
******************************************************************************/

void idl_cdfattrget(argc, argv)
int argc;
IDL_VPTR argv[];
{
  void *value; CDFid id; void *data; CDFstatus status; char *tmp;
  size_t nBytes; long attr_num, entry_num, dataType, numElems, scope;
  struct CurStruct Cur;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToCDFid(argv[3],&id)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[4],&attr_num)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[5],&entry_num)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id, 
			    ATTR_, attr_num,
		   GET_, ATTR_SCOPE_, &scope,
		   NULL_);
  if (StatusBAD(status)) RETURNsX(status,Cur,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id, 
			    ATTR_, attr_num,
			    BOO(scope == GLOBAL_SCOPE,
			        gENTRY_,rENTRY_), entry_num,
		   GET_, BOO(scope == GLOBAL_SCOPE,
			     gENTRY_DATATYPE_,rENTRY_DATATYPE_), &dataType,
		         BOO(scope == GLOBAL_SCOPE,
			     gENTRY_NUMELEMS_,rENTRY_NUMELEMS_), &numElems,
		   NULL_);
  if (StatusBAD(status)) RETURNsX(status,Cur,argv)
  nBytes = (CDFelemSize(dataType)*numElems) +
	   BOO(STRINGdataType(dataType),1,0);
  value = (void *) malloc (nBytes);
  if (value == NULL) RETURNsX(BAD_MALLOC,Cur,argv)
  status = CDFlib (&Cur,
		   GET_, BOO(scope == GLOBAL_SCOPE,
			     gENTRY_DATA_,rENTRY_DATA_), value,
		   NULL_);
  if (StatusBAD(status)) {
    free (value);
    RETURNsX(status,Cur,argv)
  }
  if (STRINGdataType(dataType)) {
    ((char *) value)[numElems] = NUL;
    StoreString (argv[6], value);
  }
  else
    if (numElems > 1) {
      if (!StoreMultiArray(argv[6],dataType,1L,1L,&numElems,value)) {
        free (value);
        RETURNsX(BAD_MALLOC,Cur,argv)
      }
    }
    else
      StoreScalar (argv[6], dataType, value);
  free (value);
  RETURNsX(status,Cur,argv)
}

/******************************************************************************
* idl_cdfvarget.
******************************************************************************/

void idl_cdfvarget (argc, argv)
int argc;
IDL_VPTR argv[];
{
  void *value; CDFid id; size_t nBytes; CDFstatus status;
  long var_num, record_num, indices[CDF_MAX_DIMS], data_type, num_elems;
  struct CurStruct Cur;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToCDFid(argv[3],&id)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[4],&var_num)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[5],&record_num)) RETURNs2(BAD_ARGUMENT,argv)
  if (!BuildLongArray(argv[6],
		      indices,
		      CDF_MAX_DIMS)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id, 
			    rVAR_, var_num,
		   GET_, rVAR_DATATYPE_, &data_type,
		         rVAR_NUMELEMS_, &num_elems,
		   NULL_);
  if (StatusBAD(status)) RETURNsX(status,Cur,argv)
  nBytes = BOO(STRINGdataType(data_type),num_elems+1,CDFelemSize(data_type));
  value = (void *) malloc (nBytes);
  if (value == NULL) RETURNsX(BAD_MALLOC,Cur,argv)
  status = CDFlib (&Cur,
		   SELECT_, rVARs_RECNUMBER_,  record_num,
			    rVARs_DIMINDICES_, indices,
		   GET_, rVAR_DATA_, value,
		   NULL_);
  if (StatusBAD(status)) {
    free (value);
    RETURNsX(status,Cur,argv)
  }
  if (STRINGdataType(data_type)) {
    ((char *) value)[num_elems] = NUL;
    StoreString (argv[7], (char *) value);
  }
  else
    StoreScalar (argv[7], data_type, value);
  free (value);
  RETURNsX(status,Cur,argv)
}

/******************************************************************************
* idl_cdfvarput.
******************************************************************************/

void idl_cdfvarput (argc, argv)
int argc;
IDL_VPTR argv[];
{
  CDFid id; CDFstatus status; void *value;
  long var_num, record_num, indices[CDF_MAX_DIMS]; struct CurStruct Cur;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToCDFid(argv[3],&id)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[4],&var_num)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[5],&record_num)) RETURNs2(BAD_ARGUMENT,argv)
  if (!BuildLongArray(argv[6],
		      indices,
		      CDF_MAX_DIMS)) RETURNs2(BAD_ARGUMENT,argv)
  if (!DataPtr(argv[7],&value)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id, 
			    rVAR_, var_num,
		            rVARs_RECNUMBER_, record_num,
			    rVARs_DIMINDICES_, indices,
		   PUT_, rVAR_DATA_, value,
		   NULL_);
  RETURNsX(status,Cur,argv)
}

/******************************************************************************
* idl_cdfhypget.
******************************************************************************/

void idl_cdfhypget (argc, argv)
int argc;
IDL_VPTR argv[];
{
  CDFid id; CDFstatus status; void *buffer; int dimN;
  long indices[CDF_MAX_DIMS], counts[CDF_MAX_DIMS], intervals[CDF_MAX_DIMS];
  long nRecValues, nValueBytes, nRecBytes, nBytes, tCounts[CDF_MAX_DIMS+1];
  long var_num, recStart, recCount, recInterval;
  long num_dims, data_type, num_elems; struct CurStruct Cur;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToCDFid(argv[3],&id)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[4],&var_num)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[5],&recStart)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[6],&recCount)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[7],&recInterval)) RETURNs2(BAD_ARGUMENT,argv)
  if (!BuildLongArray(argv[8],
		      indices,
		      CDF_MAX_DIMS)) RETURNs2(BAD_ARGUMENT,argv)
  if (!BuildLongArray(argv[9],
		      counts,
		      CDF_MAX_DIMS)) RETURNs2(BAD_ARGUMENT,argv)
  if (!BuildLongArray(argv[10],
		      intervals,
		      CDF_MAX_DIMS)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id, 
			    rVAR_, var_num,
		         GET_, rVARs_NUMDIMS_, &num_dims,
		         rVAR_DATATYPE_, &data_type,
		         rVAR_NUMELEMS_, &num_elems,
		   NULL_);
  if (StatusBAD(status)) RETURNsX(status,Cur,argv)
  nRecValues = 1;
  for (dimN = 0; dimN < num_dims; dimN++) nRecValues *= counts[dimN];
  nValueBytes = CDFelemSize(data_type) * num_elems;
  nRecBytes = nRecValues * nValueBytes;
  nBytes = nRecBytes * recCount;
  buffer = (void *) malloc (nBytes);
  if (buffer == NULL) RETURNsX(BAD_MALLOC,Cur,argv)
  status = CDFlib (&Cur,
		   SELECT_, rVARs_RECNUMBER_, recStart,
		            rVARs_RECCOUNT_, recCount,
		            rVARs_RECINTERVAL_, recInterval,
			    rVARs_DIMINDICES_, indices,
			    rVARs_DIMCOUNTS_, counts,
			    rVARs_DIMINTERVALS_, intervals,
		   GET_, rVAR_HYPERDATA_, buffer,
		   NULL_);
  if (StatusBAD(status)) {
    free (buffer);
    RETURNsX(status,Cur,argv)
  }
  for (dimN = 0; dimN < num_dims; dimN++) tCounts[dimN] = counts[dimN];
  tCounts[(int)num_dims] = recCount;
  if (!StoreMultiArray(argv[11],data_type,num_elems,
		       num_dims+1,tCounts,buffer)) {
    free (buffer);
    RETURNsX(BAD_MALLOC,Cur,argv)
  }
  free (buffer);
  RETURNsX(status,Cur,argv)
}

/******************************************************************************
* idl_cdfhypput.
******************************************************************************/

void idl_cdfhypput (argc, argv)
int argc;
IDL_VPTR argv[];
{
  CDFid id; CDFstatus status; void *buffer, *xBuffer; int dimN;
  long recStart, recCount, recInterval, num_dims, data_type, num_elems;
  long indices[CDF_MAX_DIMS], counts[CDF_MAX_DIMS], intervals[CDF_MAX_DIMS];
  long nRecValues, nValueBytes, nRecBytes, nBytes, valueN, nValues, var_num;
  struct CurStruct Cur;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToCDFid(argv[3],&id)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[4],&var_num)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[5],&recStart)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[6],&recCount)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[7],&recInterval)) RETURNs2(BAD_ARGUMENT,argv)
  if (!BuildLongArray(argv[8],
		      indices,
		      CDF_MAX_DIMS)) RETURNs2(BAD_ARGUMENT,argv)
  if (!BuildLongArray(argv[9],
		      counts,
		      CDF_MAX_DIMS)) RETURNs2(BAD_ARGUMENT,argv)
  if (!BuildLongArray(argv[10],
		      intervals,
		      CDF_MAX_DIMS)) RETURNs2(BAD_ARGUMENT,argv)
  if (!DataPtr(argv[11],&buffer)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id, 
			    rVAR_, var_num,
		   GET_, rVARs_NUMDIMS_, &num_dims,
		         rVAR_DATATYPE_, &data_type,
		         rVAR_NUMELEMS_, &num_elems,
		   NULL_);
  if (StatusBAD(status)) RETURNsX(status,Cur,argv)
  nRecValues = 1;
  for (dimN = 0; dimN < num_dims; dimN++) nRecValues *= counts[dimN];
  nValues = nRecValues * recCount;
  nValueBytes = CDFelemSize(data_type) * num_elems;
  nRecBytes = nRecValues * nValueBytes;
  nBytes = nRecBytes * recCount;
  if (STRINGdataType(data_type)) {
    IDL_STRING *str; char *tBuffer;
    xBuffer = (char *) malloc (nBytes);
    if (xBuffer == NULL) RETURNsX(BAD_MALLOC,Cur,argv)
    str = (IDL_STRING *) buffer;
    tBuffer = xBuffer;
    for (valueN = 0; valueN < nValues;
         valueN++, str++, tBuffer += num_elems) {
       strcpyX (tBuffer, IDL_STRING_STR(str), num_elems);
    }
  }
  else
    xBuffer = buffer;
  status = CDFlib (&Cur,
		   SELECT_, rVARs_RECNUMBER_, recStart,
		            rVARs_RECCOUNT_, recCount,
		            rVARs_RECINTERVAL_, recInterval,
			    rVARs_DIMINDICES_, indices,
			    rVARs_DIMCOUNTS_, counts,
			    rVARs_DIMINTERVALS_, intervals,
		   PUT_, rVAR_HYPERDATA_, xBuffer,
		   NULL_);
  if (StatusBAD(status)) {
    if (xBuffer != buffer) free (xBuffer);
    RETURNsX(status,Cur,argv)
  }
  if (xBuffer != buffer) free (xBuffer);
  RETURNsX(status,Cur,argv)
}

/******************************************************************************
* idl_cdfcreate.
******************************************************************************/

void idl_cdfcreate(argc, argv)
int argc;
IDL_VPTR argv[];
{
  char *CDF_name; CDFid id; CDFstatus status; struct CurStruct Cur;
  long num_dims, dim_sizes[CDF_MAX_DIMS], encoding, majority;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!StringPtr(argv[3],&CDF_name)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[4],&num_dims)) RETURNs2(BAD_ARGUMENT,argv)
  if (!BuildLongArray(argv[5],
		      dim_sizes,
		      CDF_MAX_DIMS)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[6],&encoding)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[7],&majority)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   CREATE_, CDF_, CDF_name, num_dims, dim_sizes, &id,
		   PUT_, CDF_ENCODING_, encoding,
		         CDF_MAJORITY_, majority,
		   NULL_);
  if (StatusBAD(status)) RETURNsX(status,Cur,argv)
  StoreCDFid (argv[8], id);
  RETURNsX(status,Cur,argv)
}

/******************************************************************************
* idl_cdfvarcre.
******************************************************************************/

void idl_cdfvarcre(argc, argv)
int argc;
IDL_VPTR argv[];
{
  CDFid id; CDFstatus status; char *var_mnemonic; long out_var_num;
  long data_type, num_bytes, record_variance, dim_variances[CDF_MAX_DIMS];
  struct CurStruct Cur;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToCDFid(argv[3],&id)) RETURNs2(BAD_ARGUMENT,argv)
  if (!StringPtr(argv[4],&var_mnemonic)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[5],&data_type)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[6],&num_bytes)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[7],&record_variance)) RETURNs2(BAD_ARGUMENT,argv)
  if (!BuildLongArray(argv[8],
		      dim_variances,
		      CDF_MAX_DIMS)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id, 
		   CREATE_, rVAR_, var_mnemonic, data_type, num_bytes,
		                   record_variance, dim_variances,
				   &out_var_num,
		   NULL_);
  if (StatusBAD(status)) RETURNsX(status,Cur,argv)
  StoreLong (argv[9], out_var_num);
  RETURNsX(status,Cur,argv)
}

/******************************************************************************
* idl_cdfvarren.
******************************************************************************/

void idl_cdfvarren (argc, argv)
int argc;
IDL_VPTR argv[];
{
  CDFid id; long var_num; char *var_mnemonic; CDFstatus status;
  struct CurStruct Cur;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToCDFid(argv[3],&id)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[4],&var_num)) RETURNs2(BAD_ARGUMENT,argv)
  if (!StringPtr(argv[5],&var_mnemonic)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id, 
			    rVAR_, var_num,
		   PUT_, rVAR_NAME_, var_mnemonic,
		   NULL_);
  RETURNsX(status,Cur,argv)
}

/******************************************************************************
* idl_cdfattrren.
******************************************************************************/

void idl_cdfattrren (argc, argv)
int argc;
IDL_VPTR argv[];
{
  CDFid id; long attr_num; char *attr_mnemonic; CDFstatus status;
  struct CurStruct Cur;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToCDFid(argv[3],&id)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[4],&attr_num)) RETURNs2(BAD_ARGUMENT,argv)
  if (!StringPtr(argv[5],&attr_mnemonic)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id, 
			    ATTR_, attr_num,
		   PUT_, ATTR_NAME_, attr_mnemonic,
		   NULL_);
  RETURNsX(status,Cur,argv)
}

/******************************************************************************
* idl_cdfattrcre.
******************************************************************************/

void idl_cdfattrcre (argc, argv)
int argc;
IDL_VPTR argv[];
{
  CDFid id; char *attr_mnemonic; CDFstatus status;
  long attr_scope, out_attr_num; struct CurStruct Cur;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToCDFid(argv[3],&id)) RETURNs2(BAD_ARGUMENT,argv)
  if (!StringPtr(argv[4],&attr_mnemonic)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[5],&attr_scope)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_,  id, 
		   CREATE_, ATTR_, attr_mnemonic, attr_scope, &out_attr_num,
		   NULL_);
  if (StatusBAD(status)) RETURNsX(status,Cur,argv)
  StoreLong (argv[6], out_attr_num);
  RETURNsX(status,Cur,argv)
}

/******************************************************************************
* idl_cdfattrput.
******************************************************************************/

void idl_cdfattrput (argc, argv)
int argc;
IDL_VPTR argv[];
{
  CDFid id; CDFstatus status; void *value; struct CurStruct Cur;
  long attr_num, entry_num, data_type, num_elements, scope;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToCDFid(argv[3],&id)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[4],&attr_num)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[5],&entry_num)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[6],&data_type)) RETURNs2(BAD_ARGUMENT,argv)
  if (!CastToLong(argv[7],&num_elements)) RETURNs2(BAD_ARGUMENT,argv)
  if (!DataPtr(argv[8],&value)) RETURNs2(BAD_ARGUMENT,argv)
  status = CDFlib (&Cur,
		   SELECT_, CDF_, id, 
			    ATTR_, attr_num,
		   GET_, 	    ATTR_SCOPE_, &scope,
		   NULL_);
  if (StatusBAD(status)) RETURNsX(status,Cur,argv)
  status = CDFlib (&Cur,
		   SELECT_, BOO(scope == GLOBAL_SCOPE,
			        gENTRY_,rENTRY_), entry_num,
		   PUT_, BOO(scope == GLOBAL_SCOPE,
			     gENTRY_DATA_, rENTRY_DATA_), data_type,
							  num_elements, value,
		   NULL_);
  RETURNsX(status,Cur,argv)
}
/******************************************************************************
* idl_cdflib.
* NOTES:
* GET_,[r|z]VARs_RECDATA_ and PUT_,[r|z]VARs_RECDATA_ are not supported
* because different data types may be returned.  If IDL has something like
* a Fortran EQUIVALENCE then perhaps they could be supported.
******************************************************************************/

void idl_cdflib (argc, argv)
int argc;
IDL_VPTR argv[];
{
  CDFstatus status, pStatus = CDF_OK; int argX = 3;
  struct CurStruct Cur; long item, fnc;
  if (!CastToCUR(argv,&Cur)) RETURNs2(CDF_INTERNAL_ERROR,argv)
  if (!CastToLong(argv[argX++],&fnc)) RETURNs2(BAD_ARGUMENT,argv)
  while (fnc != NULL_) {
    switch (fnc) {
      /************************************************************************
      * CREATE_, create an item.
      ************************************************************************/
      case CREATE_:
	for (;;) {
	   if (!CastToLong(argv[argX++],&item)) RETURNsX(BAD_ARGUMENT,Cur,argv)
	   switch (item) {
	     /*****************************************************************
	     * CREATE_,CDF_: create a CDF.
	     *****************************************************************/
	     case CDF_: {
	       CDFid id; char *CDFname; long dimSizes[CDF_MAX_DIMS], numDims;
	       if (!StringPtr(argv[argX++],&CDFname)) RETURNsX(BAD_ARGUMENT,
							       Cur,argv)
	       if (!CastToLong(argv[argX++],&numDims)) RETURNsX(BAD_ARGUMENT,
								Cur,argv)
	       if (!BuildLongArray(argv[argX++],
				   dimSizes,
				   CDF_MAX_DIMS)) RETURNsX(BAD_ARGUMENT,
							   Cur,argv)
	       status = CDFlib (&Cur,
				CREATE_, CDF_, CDFname, numDims, dimSizes, &id,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       StoreCDFid (argv[argX++], id);
	       break;
	     }
	     /*****************************************************************
	     * CREATE_,rVAR_/zVAR_: create a variable.
	     *****************************************************************/
	     case rVAR_:
	     case zVAR_: {
	       Logical Zop = (item == zVAR_); char *varName;
	       long dimSizes[CDF_MAX_DIMS], dimVarys[CDF_MAX_DIMS];
	       long dataType, numElems, recVary, varNum, numDims;
	       if (!StringPtr(argv[argX++],
			      &varName)) RETURNsX(BAD_ARGUMENT,Cur,argv)
	       if (!CastToLong(argv[argX++],
			       &dataType)) RETURNsX(BAD_ARGUMENT,Cur,argv)
	       if (!CastToLong(argv[argX++],
			       &numElems)) RETURNsX(BAD_ARGUMENT,Cur,argv)
	       if (Zop) {
	         if (!CastToLong(argv[argX++],
				 &numDims)) RETURNsX(BAD_ARGUMENT,Cur,argv)
		 if (!BuildLongArray(argv[argX++],
				     dimSizes,
				     CDF_MAX_DIMS)) RETURNsX(BAD_ARGUMENT,
							     Cur,argv)
	       }
	       if (!CastToLong(argv[argX++],
			       &recVary)) RETURNsX(BAD_ARGUMENT,Cur,argv)
	       if (!BuildLongArray(argv[argX++],
				   dimVarys,
				   CDF_MAX_DIMS)) RETURNsX(BAD_ARGUMENT,
							   Cur,argv)
	       if (Zop)
		 status = CDFlib (&Cur,
				  CREATE_, zVAR_, varName, dataType, numElems,
						  numDims, dimSizes,
						  recVary, dimVarys, &varNum,
				  NULL_);
	       else
		 status = CDFlib (&Cur,
				  CREATE_, rVAR_, varName, dataType, numElems,
						  recVary, dimVarys, &varNum,
				  NULL_);
	       CSC (status,pStatus,Cur,argv)
	       StoreLong (argv[argX++], varNum);
	       break;
	     }
	     /*****************************************************************
	     * CREATE_,ATTR_: create an attribute.
	     *****************************************************************/
	     case ATTR_: {
	       long attrNum, scope; char *attrName;
	       if (!StringPtr(argv[argX++],
			      &attrName)) RETURNsX(BAD_ARGUMENT,Cur,argv)
	       if (!CastToLong(argv[argX++],
			       &scope)) RETURNsX(BAD_ARGUMENT,Cur,argv)
	       status = CDFlib (&Cur,
				CREATE_, ATTR_, attrName, scope, &attrNum,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       StoreLong (argv[argX++], attrNum);
	       break;
	     }
	     /*****************************************************************
	     * Unknown item - hopefully the next operation.
	     *****************************************************************/
	     default: {
	       fnc = item;
	       break;
	     }
	   }
	   if (fnc == item) break;
        }
        break;
      /************************************************************************
      * OPEN_, open an item.
      ************************************************************************/
      case OPEN_:
	for (;;) {
	   if (!CastToLong(argv[argX++],&item)) RETURNsX(BAD_ARGUMENT,Cur,argv)
	   switch (item) {
	     /*****************************************************************
	     * OPEN_,CDF_: open a CDF.
	     *****************************************************************/
	     case CDF_: {
	       CDFid id; char *CDFname;
	       if (!StringPtr(argv[argX++],
			      &CDFname)) RETURNsX(BAD_ARGUMENT,Cur,argv)
	       status = CDFlib (&Cur,
				OPEN_, CDF_, CDFname, &id,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       StoreCDFid (argv[argX++], id);
	       break;
	     }
	     /*****************************************************************
	     * Unknown item - hopefully the next operation.
	     *****************************************************************/
	     default: {
	       fnc = item;
	       break;
	     }
	   }
	   if (fnc == item) break;
        }
        break;
      /************************************************************************
      * DELETE_, delete an item.
      ************************************************************************/
      case DELETE_:
	for (;;) {
	   if (!CastToLong(argv[argX++],&item)) RETURNsX(BAD_ARGUMENT,Cur,argv)
	   switch (item) {
	     /*****************************************************************
	     * DELETE_,<object>:  Delete an object.
	     *****************************************************************/
	     case CDF_:
	     case zVAR_:
	     case rVAR_:
	     case ATTR_:
	     case gENTRY_:
	     case zENTRY_:
	     case rENTRY_:
	       status = CDFlib (&Cur,
				DELETE_, item,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       break;
	     /*****************************************************************
	     * DELETE_,r|zVAR_RECORDS_: delete variable records.
	     *****************************************************************/
	     case rVAR_RECORDS_:
	     case zVAR_RECORDS_: {
	       long rec1, rec2;
	       if (!CastToLong(argv[argX++],&rec1)) RETURNsX(BAD_ARGUMENT,
							     Cur,argv)
	       if (!CastToLong(argv[argX++],&rec2)) RETURNsX(BAD_ARGUMENT,
							     Cur,argv)
	       status = CDFlib (&Cur,
				DELETE_, item, rec1, rec2,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * Unknown item - hopefully the next operation.
	     *****************************************************************/
	     default: {
	       fnc = item;
	       break;
	     }
	   }
	   if (fnc == item) break;
        }
        break;
      /************************************************************************
      * CLOSE_, close an item.
      ************************************************************************/
      case CLOSE_:
	for (;;) {
	   if (!CastToLong(argv[argX++],&item)) RETURNsX(BAD_ARGUMENT,Cur,argv)
	   switch (item) {
	     /*****************************************************************
	     * CLOSE_,CDF_: close a CDF.
	     *****************************************************************/
	     case CDF_: {
	       status = CDFlib (&Cur,
				CLOSE_, CDF_,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * CLOSE_,rVAR_/zVAR_: close a variable.
	     *****************************************************************/
	     case rVAR_:
	     case zVAR_: {
	       status = CDFlib (&Cur,
				CLOSE_, item,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * Unknown item - hopefully the next operation.
	     *****************************************************************/
	     default: {
	       fnc = item;
	       break;
	     }
	   }
	   if (fnc == item) break;
        }
        break;
      /************************************************************************
      * SELECT_, select an item.
      ************************************************************************/
      case SELECT_:
	for (;;) {
	   if (!CastToLong(argv[argX++],&item)) RETURNsX(BAD_ARGUMENT,Cur,argv)
	   switch (item) {
	     /*****************************************************************
	     * SELECT_,<`long' value>
	     *****************************************************************/
	     case CDF_READONLY_MODE_:
	     case CDF_zMODE_:
	     case CDF_NEGtoPOSfp0_MODE_:
	     case CDF_DECODING_:
	     case CDF_CACHESIZE_:
	     case STAGE_CACHESIZE_:
	     case COMPRESS_CACHESIZE_:
	     case rVARs_CACHESIZE_:
	     case zVARs_CACHESIZE_:
	     case rVAR_CACHESIZE_:
	     case zVAR_CACHESIZE_:
	     case rVAR_:
	     case zVAR_:
	     case rVARs_RECNUMBER_:
	     case zVARs_RECNUMBER_:
	     case zVAR_RECNUMBER_:
	     case rVARs_RECCOUNT_:
	     case zVAR_RECCOUNT_:
	     case rVARs_RECINTERVAL_:
	     case zVAR_RECINTERVAL_:
	     case rVAR_RESERVEPERCENT_:
	     case zVAR_RESERVEPERCENT_:
	     case ATTR_:
	     case gENTRY_:
	     case rENTRY_:
	     case zENTRY_: {
	       long value;
	       if (!CastToLong(argv[argX++],&value)) RETURNsX(BAD_ARGUMENT,
							      Cur,argv)
	       status = CDFlib (&Cur,
				SELECT_, item, value,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * SELECT_,<array of `long' values>
	     *****************************************************************/
	     case rVARs_DIMINDICES_:
	     case zVAR_DIMINDICES_:
	     case rVARs_DIMCOUNTS_:
	     case zVAR_DIMCOUNTS_:
	     case rVARs_DIMINTERVALS_:
	     case zVAR_DIMINTERVALS_: {
	       long values[CDF_MAX_DIMS];
	       if (!BuildLongArray(argv[argX++],
				   values,
				   CDF_MAX_DIMS)) RETURNsX(BAD_ARGUMENT,
							   Cur,argv)
	       status = CDFlib (&Cur,
				SELECT_, item, values,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * SELECT_,<`long' value, array of `long' values>
	     *****************************************************************/
	     case rVAR_SEQPOS_:
	     case zVAR_SEQPOS_: {
	       long value, values[CDF_MAX_DIMS];
	       if (!CastToLong(argv[argX++],&value)) RETURNsX(BAD_ARGUMENT,
							      Cur,argv)
	       if (!BuildLongArray(argv[argX++],
				   values,
				   CDF_MAX_DIMS)) RETURNsX(BAD_ARGUMENT,
							   Cur,argv)
	       status = CDFlib (&Cur,
				SELECT_, item, value, values,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * SELECT_,<character string>
	     *****************************************************************/
	     case CDF_SCRATCHDIR_:
	     case rVAR_NAME_:
	     case zVAR_NAME_:
	     case ATTR_NAME_:
	     case rENTRY_NAME_:
	     case zENTRY_NAME_: {
	       char *string;
	       if (!StringPtr(argv[argX++],&string)) RETURNsX(BAD_ARGUMENT,
							      Cur,argv)
	       status = CDFlib (&Cur,
				SELECT_, item, string,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * SELECT_,CDF_: select the current CDF.
	     *****************************************************************/
	     case CDF_: {
	       CDFid id;
	       if (!CastToCDFid(argv[argX++],&id)) RETURNsX(BAD_ARGUMENT,
							    Cur,argv)
	       status = CDFlib (&Cur,
				SELECT_, CDF_, id,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * SELECT_,CDF_STATUS_: select the current CDF status code.
	     *****************************************************************/
	     case CDF_STATUS_: {
	       long cStatus;
	       if (!CastToLong(argv[argX++],
			       &cStatus)) RETURNsX(BAD_ARGUMENT,Cur,argv)
	       status = CDFlib (&Cur,
				SELECT_, CDF_STATUS_, (CDFstatus) cStatus,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * Unknown item - hopefully the next operation.
	     *****************************************************************/
	     default: {
	       fnc = item;
	       break;
	     }
	   }
	   if (fnc == item) break;
        }
        break;
      /************************************************************************
      * CONFIRM_, confirm an item.
      ************************************************************************/
      case CONFIRM_:
	for (;;) {
	   if (!CastToLong(argv[argX++],&item)) RETURNsX(BAD_ARGUMENT,Cur,argv)
	   switch (item) {
	     /*****************************************************************
	     * CONFIRM_,<no arguments>
	     *****************************************************************/
	     case CURgENTRY_EXISTENCE_:
	     case CURrENTRY_EXISTENCE_:
	     case CURzENTRY_EXISTENCE_: {
	       status = CDFlib (&Cur,
				CONFIRM_, item,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * CONFIRM_,<out: `long' value>
	     *****************************************************************/
	     case CDF_READONLY_MODE_:
	     case CDF_zMODE_:
	     case CDF_NEGtoPOSfp0_MODE_:
	     case CDF_DECODING_:
	     case CDF_CACHESIZE_:
	     case STAGE_CACHESIZE_:
	     case COMPRESS_CACHESIZE_:
	     case rVAR_CACHESIZE_:
	     case zVAR_CACHESIZE_:
	     case rVAR_:
	     case zVAR_:
	     case rVARs_RECNUMBER_:
	     case zVAR_RECNUMBER_:
	     case rVARs_RECCOUNT_:
	     case zVAR_RECCOUNT_:
	     case rVARs_RECINTERVAL_:
	     case zVAR_RECINTERVAL_:
	     case rVAR_RESERVEPERCENT_:
	     case zVAR_RESERVEPERCENT_:
	     case ATTR_:
	     case gENTRY_:
	     case rENTRY_:
	     case zENTRY_: {
	       long value;
	       status = CDFlib (&Cur,
				CONFIRM_, item, &value,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       StoreLong (argv[argX++], value);
	       break;
	     }
	     /*****************************************************************
	     * CONFIRM_,<in: `long' value>
	     *****************************************************************/
	     case gENTRY_EXISTENCE_:
	     case rENTRY_EXISTENCE_:
	     case zENTRY_EXISTENCE_: {
	       long value;
	       if (!CastToLong(argv[argX++],&value)) RETURNsX(BAD_ARGUMENT,
							      Cur,argv)
	       status = CDFlib (&Cur,
				CONFIRM_, item, value,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * CONFIRM_,<array of `long' values>
	     *****************************************************************/
	     case rVARs_DIMINDICES_:
	     case zVAR_DIMINDICES_:
	     case rVARs_DIMCOUNTS_:
	     case zVAR_DIMCOUNTS_:
	     case rVARs_DIMINTERVALS_:
	     case zVAR_DIMINTERVALS_: {
	       long values[CDF_MAX_DIMS];	/* CDF_MAX_DIMS is only case.*/
	       status = CDFlib (&Cur,
				CONFIRM_, item, values,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       if (!StoreLongArray(argv[argX++],
				   CDF_MAX_DIMS,
				   values)) RETURNsX(BAD_MALLOC,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * CONFIRM_,<`long' value, array of `long' values>
	     *****************************************************************/
	     case rVAR_SEQPOS_:
	     case zVAR_SEQPOS_: {
	       long value;
	       long values[CDF_MAX_DIMS];	/* CDF_MAX_DIMS is only case.*/
	       status = CDFlib (&Cur,
				CONFIRM_, item, &value, values,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       StoreLong (argv[argX++], value);
	       if (!StoreLongArray(argv[argX++],
				   CDF_MAX_DIMS,
				   values)) RETURNsX(BAD_MALLOC,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * CONFIRM_,<out: character string>
	     *****************************************************************/
	     case CDF_NAME_: {
	       char string[CDF_PATHNAME_LEN+1];	/* Currently the only case. */
	       status = CDFlib (&Cur,
				CONFIRM_, item, string,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       StoreString (argv[argX++], string);
	       break;
	     }
	     /*****************************************************************
	     * CONFIRM_,<in: character string>
	     *****************************************************************/
	     case rVAR_EXISTENCE_:
	     case zVAR_EXISTENCE_:
	     case ATTR_EXISTENCE_: {
	       char *string;
	       if (!StringPtr(argv[argX++],&string)) RETURNsX(BAD_ARGUMENT,
							      Cur,argv)
	       status = CDFlib (&Cur,
				CONFIRM_, item, string,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * Unknown item - hopefully the next operation.
	     *****************************************************************/
	     default: {
	       fnc = item;
	       break;
	     }
	   }
	   if (fnc == item) break;
        }
        break;
      /************************************************************************
      * GET_, get an item.
      ************************************************************************/
      case GET_:
	for (;;) {
	   if (!CastToLong(argv[argX++],&item)) RETURNsX(BAD_ARGUMENT,Cur,argv)
	   switch (item) {
	     /*****************************************************************
	     * GET_,<longword value>
	     *****************************************************************/
	     case rVARs_NUMDIMS_:
	     case zVAR_NUMDIMS_:
	     case CDF_ENCODING_:
	     case CDF_MAJORITY_:
	     case CDF_FORMAT_:
	     case CDF_NUMrVARS_:
	     case CDF_NUMzVARS_:
	     case CDF_NUMATTRS_:
	     case CDF_NUMgATTRS_:
	     case CDF_NUMvATTRS_:
	     case CDF_VERSION_:
	     case CDF_RELEASE_:
	     case CDF_INCREMENT_:
	     case LIB_VERSION_:
	     case LIB_RELEASE_:
	     case LIB_INCREMENT_:
	     case rVARs_MAXREC_:
	     case zVARs_MAXREC_:
	     case rVAR_DATATYPE_:
	     case zVAR_DATATYPE_:
	     case rVAR_NUMELEMS_:
	     case zVAR_NUMELEMS_:
	     case rVAR_RECVARY_:
	     case zVAR_RECVARY_:
	     case rVAR_MAXREC_:
	     case zVAR_MAXREC_:
	     case rVAR_MAXallocREC_:
	     case zVAR_MAXallocREC_:
	     case rVAR_NUMRECS_:
	     case zVAR_NUMRECS_:
	     case rVAR_NUMallocRECS_:
	     case zVAR_NUMallocRECS_:
	     case rVAR_BLOCKINGFACTOR_:
	     case zVAR_BLOCKINGFACTOR_:
	     case rVAR_nINDEXRECORDS_:
	     case zVAR_nINDEXRECORDS_:
	     case rVAR_nINDEXENTRIES_:
	     case zVAR_nINDEXENTRIES_:
	     case rVAR_nINDEXLEVELS_:
	     case zVAR_nINDEXLEVELS_:
	     case rVAR_SPARSERECORDS_:
	     case zVAR_SPARSERECORDS_:
	     case ATTR_SCOPE_:
	     case ATTR_MAXgENTRY_:
	     case ATTR_MAXrENTRY_:
	     case ATTR_MAXzENTRY_:
	     case ATTR_NUMgENTRIES_:
	     case ATTR_NUMrENTRIES_:
	     case ATTR_NUMzENTRIES_:
	     case gENTRY_DATATYPE_:
	     case rENTRY_DATATYPE_:
	     case zENTRY_DATATYPE_:
	     case gENTRY_NUMELEMS_:
	     case rENTRY_NUMELEMS_:
	     case zENTRY_NUMELEMS_: {
	       long value;
	       status = CDFlib (&Cur,
				GET_, item, &value,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       StoreLong (argv[argX++], value);
	       break;
	     }
	     /*****************************************************************
	     * GET_,<longword value In, longword value Out>
	     *****************************************************************/
	     case DATATYPE_SIZE_:
	     case rVAR_ALLOCATEDFROM_:
	     case zVAR_ALLOCATEDFROM_:
	     case rVAR_ALLOCATEDTO_:
	     case zVAR_ALLOCATEDTO_: {
	       long value1, value2;
	       if (!CastToLong(argv[argX++],&value1)) RETURNsX(BAD_ARGUMENT,
							       Cur,argv)
	       status = CDFlib (&Cur,
				GET_, item, value1, &value2,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       StoreLong (argv[argX++], value2);
	       break;
	     }
	     /*****************************************************************
	     * GET_,<longword array of values>
	     *****************************************************************/
	     case rVARs_DIMSIZES_:
	     case zVAR_DIMSIZES_:
	     case rVAR_DIMVARYS_:
	     case zVAR_DIMVARYS_: {
	       long values[CDF_MAX_DIMS];	/* CDF_MAX_DIMS is only case.*/
	       status = CDFlib (&Cur,
				GET_, item, values,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       if (!StoreLongArray(argv[argX++],
				   CDF_MAX_DIMS,
				   values)) RETURNsX(BAD_MALLOC,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * GET_,<character string>
	     *****************************************************************/
	     case CDF_COPYRIGHT_:
	     case LIB_COPYRIGHT_:
	     case rVAR_NAME_:
	     case zVAR_NAME_:
	     case ATTR_NAME_: {
	       char *string; size_t nChars;
	       switch (item) {
		 case CDF_COPYRIGHT_:
		 case LIB_COPYRIGHT_:
		   nChars = CDF_COPYRIGHT_LEN;
		   break;
		 case rVAR_NAME_:
		 case zVAR_NAME_:
		   nChars = CDF_VAR_NAME_LEN;
		   break;
		 case ATTR_NAME_:
		   nChars = CDF_ATTR_NAME_LEN;
		   break;
	       }
	       string = (char *) malloc (nChars + 1);
	       if (string == NULL) RETURNsX(BAD_MALLOC,Cur,argv)
	       status = CDFlib (&Cur,
				GET_, item, string,
				NULL_);
	       StoreString (argv[argX++], string);
	       free (string);
	       CSC (status,pStatus,Cur,argv)	/* Check after freeing. */
	       break;
	     }
	     /*****************************************************************
	     * GET_,<character string in/longword out>
	     *****************************************************************/
	     case rVAR_NUMBER_:
	     case zVAR_NUMBER_:
	     case ATTR_NUMBER_: {
	       char *valueIn; long valueOut;
	       if (!StringPtr(argv[argX++],&valueIn)) RETURNsX(BAD_ARGUMENT,
							       Cur,argv)
	       status = CDFlib (&Cur,
				GET_, item, valueIn, &valueOut,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       StoreLong (argv[argX++], valueOut);
	       break;
	     }
	     /*****************************************************************
	     * GET_,<longword>,<longword array[CDF_MAX_PARMS]>,<longword>
	     *****************************************************************/
	     case CDF_COMPRESSION_:
	     case rVAR_COMPRESSION_:
	     case zVAR_COMPRESSION_:
	     case rVAR_SPARSEARRAYS_:
	     case zVAR_SPARSEARRAYS_: {
	       long values[CDF_MAX_PARMS], value1, value2; int i;
	       for (i = 0; i < CDF_MAX_PARMS; i++) values[i] = 0;
	       status = CDFlib (&Cur,
				GET_, item, &value1, values, &value2,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       StoreLong (argv[argX++], value1);
	       if (!StoreLongArray(argv[argX++],
				   CDF_MAX_PARMS,
				   values)) RETURNsX(BAD_MALLOC,Cur,argv)
	       StoreLong (argv[argX++], value2);
	       break;
	     }
	     /*****************************************************************
	     * GET_,CDF_INFO_:
	     *****************************************************************/
	     case CDF_INFO_: {
	       long cType, cParms[CDF_MAX_PARMS], cSize, uSize;
	       char *path; int i;
	       for (i = 0; i < CDF_MAX_PARMS; i++) cParms[i] = 0;
	       if (!StringPtr(argv[argX++],&path)) RETURNsX(BAD_ARGUMENT,
							    Cur,argv)
	       status = CDFlib (&Cur,
				GET_, CDF_INFO_, path, &cType, cParms,
						 &cSize, &uSize,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       StoreLong (argv[argX++], cType);
	       if (!StoreLongArray(argv[argX++],
				   CDF_MAX_PARMS,
				   cParms)) RETURNsX(BAD_MALLOC,Cur,argv)
	       StoreLong (argv[argX++], cSize);
	       StoreLong (argv[argX++], uSize);
	       break;
	     }
	     /*****************************************************************
	     * GET_,LIB_subINCREMENT_: get the library's sub-increment
	     * character.
	     *****************************************************************/
	     case LIB_subINCREMENT_: {
	       char subIncrement[1+1];
	       status = CDFlib (&Cur,
				GET_, LIB_subINCREMENT_, &(subIncrement[0]),
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       subIncrement[1] = NUL;
	       StoreString (argv[argX++], subIncrement);
	       break;
	     }
	     /*****************************************************************
	     * GET_,rVAR_PADVALUE_/zVAR_PADVALUE_: get the variable pad value.
	     *	    rVAR_DATA_/zVAR_DATA_:	   get a variable single value.
	     *	    rVAR_SEQDATA_/zVAR_SEQDATA_:   get a variable sequential
	     *					   value.
	     *****************************************************************/
	     case rVAR_PADVALUE_:
	     case zVAR_PADVALUE_:
	     case rVAR_DATA_:
	     case zVAR_DATA_:
	     case rVAR_SEQDATA_:
	     case zVAR_SEQDATA_: {
	       Logical Zop = (item == zVAR_PADVALUE_ || item == zVAR_DATA_ ||
			      item == zVAR_SEQDATA_);
	       long dataType, numElems, nBytes; void *value;
	       status = CDFlib (&Cur,
				GET_, VAR_DATATYPE(Zop), &dataType,
				      VAR_NUMELEMS(Zop), &numElems,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       nBytes = (STRINGdataType(dataType) ?
			 numElems + 1 : CDFelemSize(dataType));
	       value = (void *) malloc (nBytes);
	       if (value == NULL) RETURNsX(BAD_MALLOC,Cur,argv)
	       status = CDFlib (&Cur,
				GET_, item, value,
				NULL_);
	       if (STRINGdataType(dataType)) {
		 ((char *) value)[numElems] = NUL;
		 StoreString (argv[argX++], value);
	       }
	       else
		 StoreScalar (argv[argX++], dataType, value);
	       free (value);
	       CSC (status,pStatus,Cur,argv)	/* Check after freeing. */
	       break;
	     }
	     /*****************************************************************
	     * GET_,rVAR_HYPERDATA_/zVAR_HYPERDATA_: get a variable hyper
	     * buffer of values.
	     *****************************************************************/
	     case rVAR_HYPERDATA_:
	     case zVAR_HYPERDATA_: {
	       Logical Zop = (item == zVAR_HYPERDATA_);
	       long numDims, dataType, numElems, nValueBytes, nRecBytes;
	       long nRecValues, recX, nBytes;
	       long recCount, dimCounts[CDF_MAX_DIMS], tCounts[CDF_MAX_DIMS+1];
	       int dimN; void *buffer;
	       status = CDFlib (&Cur,
				GET_, BOO(Zop,zVAR_NUMDIMS_,
					      rVARs_NUMDIMS_), &numDims,
				      VAR_DATATYPE(Zop), &dataType,
				      VAR_NUMELEMS(Zop), &numElems,
				CONFIRM_, BOO(Zop,zVAR_RECCOUNT_,
					          rVARs_RECCOUNT_), &recCount,
					  BOO(Zop,zVAR_DIMCOUNTS_,
					          rVARs_DIMCOUNTS_), dimCounts,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       nRecValues = 1;
	       for (dimN = 0; dimN < numDims; dimN++)
		  nRecValues *= dimCounts[dimN];
	       nValueBytes = CDFelemSize(dataType) * numElems;
	       nRecBytes = nRecValues * nValueBytes;
	       nBytes = nRecBytes * recCount;
	       buffer = (void *) malloc (nBytes);
	       if (buffer == NULL) RETURNsX(BAD_MALLOC,Cur,argv)
	       status = CDFlib (&Cur,
				GET_, item, buffer,
				NULL_);
	       for (dimN = 0; dimN < numDims; dimN++) {
		  tCounts[dimN] = dimCounts[dimN];
	       }
	       tCounts[numDims] = recCount;
	       if (!StoreMultiArray(argv[argX++],dataType,numElems,
				    numDims+1,tCounts,buffer)) {
		 free (buffer);
		 RETURNsX(BAD_MALLOC,Cur,argv)
	       }
	       free (buffer);
	       CSC (status,pStatus,Cur,argv)	/* Check after freeing. */
	       break;
	     }
	     /*****************************************************************
	     * GET_,rVARs_RECDATA_/zVARs_RECDATA_: Unsupported.
	     *****************************************************************/
	     case rVARs_RECDATA_:
	     case zVARs_RECDATA_: {
	       RETURNsX(UNSUPPORTED_OPERATION,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * GET_,gENTRY_DATA_/rENTRY_DATA_/zENTRY_DATA_: get an entry value.
	     *****************************************************************/
	     case gENTRY_DATA_:
	     case rENTRY_DATA_:
	     case zENTRY_DATA_: {
	       int Et = E3p(item,gENTRY_DATA_,rENTRY_DATA_,zENTRY_DATA_);
	       long dataType, numElems; size_t nBytes; void *value;
	       status = CDFlib (&Cur,
				GET_, ENTRY_DATATYPE(Et), &dataType,
				      ENTRY_NUMELEMS(Et), &numElems,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       nBytes = (CDFelemSize(dataType) * numElems) +
			(STRINGdataType(dataType) ? 1 : 0);
	       value = (void *) malloc (nBytes);
	       if (value == NULL) RETURNsX(BAD_MALLOC,Cur,argv)
	       status = CDFlib (&Cur,
				GET_, item, value,
				NULL_);
	       if (STRINGdataType(dataType)) {
		 ((char *) value)[numElems] = NUL;
		 StoreString (argv[argX++], value);
	       }
	       else
		 if (numElems > 1) {
		   if (!StoreMultiArray(argv[argX++],dataType,
					1L,1L,&numElems,value)) {
		     free (value);
		     RETURNsX(BAD_MALLOC,Cur,argv)
		   }
		 }
		 else
		   StoreScalar (argv[argX++], dataType, value);
	       free (value);
	       CSC (status,pStatus,Cur,argv)	/* Check after freeing. */
	       break;
	     }
	     /*****************************************************************
	     * GET_,STATUS_TEXT_: get text for a status code.
	     *****************************************************************/
	     case STATUS_TEXT_: {
	       char text[CDF_STATUSTEXT_LEN+1];
	       status = CDFlib (&Cur,
				GET_, STATUS_TEXT_, text,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       StoreString (argv[argX++], text);
	       break;
	     }
	     /*****************************************************************
	     * Unknown item - hopefully the next operation.
	     *****************************************************************/
	     default: {
	       fnc = item;
	       break;
	     }
	   }
	   if (fnc == item) break;
        }
        break;
      /************************************************************************
      * PUT_, put an item.
      ************************************************************************/
      case PUT_:
	for (;;) {
	   if (!CastToLong(argv[argX++],&item)) RETURNsX(BAD_ARGUMENT,Cur,argv)
	   switch (item) {
	     /*****************************************************************
	     * PUT_,<long value>
	     *****************************************************************/
	     case CDF_ENCODING_:
	     case CDF_MAJORITY_:
	     case CDF_FORMAT_:
	     case rVAR_RECVARY_:
	     case zVAR_RECVARY_:
	     case rVAR_ALLOCATERECS_:
	     case zVAR_ALLOCATERECS_:
	     case rVAR_INITIALRECS_:
	     case zVAR_INITIALRECS_:
	     case rVAR_BLOCKINGFACTOR_:
	     case zVAR_BLOCKINGFACTOR_:
	     case rVAR_SPARSERECORDS_:
	     case zVAR_SPARSERECORDS_:
	     case ATTR_SCOPE_: {
	       long value;
	       if (!CastToLong(argv[argX++],&value)) RETURNsX(BAD_ARGUMENT,
							      Cur,argv)
	       status = CDFlib (&Cur,
				PUT_, item, value,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * PUT_,<2 long values>
	     *****************************************************************/
	     case rVAR_ALLOCATEBLOCK_:
	     case zVAR_ALLOCATEBLOCK_:
	     case rVAR_DATASPEC_:
	     case zVAR_DATASPEC_:
	     case gENTRY_DATASPEC_:
	     case rENTRY_DATASPEC_:
	     case zENTRY_DATASPEC_: {
	       long value1, value2;
	       if (!CastToLong(argv[argX++],&value1)) RETURNsX(BAD_ARGUMENT,
							       Cur,argv)
	       if (!CastToLong(argv[argX++],&value2)) RETURNsX(BAD_ARGUMENT,
							       Cur,argv)
	       status = CDFlib (&Cur,
				PUT_, item, value1, value2,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * PUT_,<array of long values>
	     *****************************************************************/
	     case rVAR_DIMVARYS_:
	     case zVAR_DIMVARYS_: {
	       long values[CDF_MAX_DIMS];
	       if (!BuildLongArray(argv[argX++],
				   values,
				   CDF_MAX_DIMS)) RETURNsX(BAD_ARGUMENT,
							   Cur,argv)
	       status = CDFlib (&Cur,
				PUT_, item, values,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * PUT_,<long value>,<array[CDF_MAX_PARMS] of long values>
	     *****************************************************************/
	     case CDF_COMPRESSION_:
	     case rVAR_COMPRESSION_:
	     case zVAR_COMPRESSION_:
	     case rVAR_SPARSEARRAYS_:
	     case zVAR_SPARSEARRAYS_: {
	       long value, values[CDF_MAX_PARMS];
	       if (!CastToLong(argv[argX++],&value)) RETURNsX(BAD_ARGUMENT,
							      Cur,argv)
	       if (!BuildLongArray(argv[argX++],
				   values,
				   CDF_MAX_PARMS)) RETURNsX(BAD_ARGUMENT,
							    Cur,argv)
	       status = CDFlib (&Cur,
				PUT_, item, value, values,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * PUT_,<character string>
	     *****************************************************************/
	     case rVAR_NAME_:
	     case zVAR_NAME_:
	     case ATTR_NAME_: {
	       char *string;
	       if (!StringPtr(argv[argX++],&string)) RETURNsX(BAD_ARGUMENT,
							      Cur,argv)
	       status = CDFlib (&Cur,
				PUT_, item, string,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * PUT_,rVAR_PADVALUE_/zVAR_PADVALUE_: put a variable pad value
	     *	    rVAR_DATA_/zVAR_DATA_: put a variable single value
	     *	    rVAR_SEQDATA_/zVAR_SEQDATA_: put a variable sequential
	     *					 value
	     *****************************************************************/
	     case rVAR_PADVALUE_:
	     case zVAR_PADVALUE_:
	     case rVAR_DATA_:
	     case zVAR_DATA_:
	     case rVAR_SEQDATA_:
	     case zVAR_SEQDATA_: {
	       void *value;
	       if (!DataPtr(argv[argX++],&value)) RETURNsX(BAD_ARGUMENT,
							   Cur,argv)
	       status = CDFlib (&Cur,
				PUT_, item, value,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * PUT_,rVAR_HYPERDATA_/zVAR_HYPERDATA_: put a buffer of values.
	     *****************************************************************/
	     case rVAR_HYPERDATA_:
	     case zVAR_HYPERDATA_: {
	       Logical Zop = (item == zVAR_HYPERDATA_);
	       void *buffer, *xBuffer; int dimN;
	       long numDims, dataType, numElems;
	       long recCount, dimCounts[CDF_MAX_DIMS];
	       long nRecValues, recX, valueN, nValues;
	       long nValueBytes, nRecBytes, nBytes;
	       if (!DataPtr(argv[argX++],&buffer)) RETURNsX(BAD_ARGUMENT,
							    Cur,argv)
	       status = CDFlib (&Cur,
				GET_, BOO(Zop,zVAR_NUMDIMS_,
					      rVARs_NUMDIMS_), &numDims,
				      VAR_DATATYPE(Zop), &dataType,
				      VAR_NUMELEMS(Zop), &numElems,
				CONFIRM_, BOO(Zop,zVAR_RECCOUNT_,
						  rVARs_RECCOUNT_), &recCount,
					  BOO(Zop,zVAR_DIMCOUNTS_,
						  rVARs_DIMCOUNTS_), dimCounts,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       nRecValues = 1;
	       for (dimN = 0; dimN < numDims; dimN++) {
		  nRecValues *= dimCounts[dimN];
	       }
	       nValues = nRecValues * recCount;
	       nValueBytes = CDFelemSize(dataType) * numElems;
	       nRecBytes = nRecValues * nValueBytes;
	       nBytes = nRecBytes * recCount;
	       if (STRINGdataType(dataType)) {
		 IDL_STRING *str = (IDL_STRING *) buffer; char *tBuffer;
		 xBuffer = (char *) malloc (nBytes);
		 if (xBuffer == NULL) RETURNsX(BAD_MALLOC,Cur,argv)
		 for (valueN = 0, tBuffer = xBuffer; valueN < nValues;
		      valueN++, str++, tBuffer += numElems) {
		    strcpyX (tBuffer, IDL_STRING_STR(str), numElems);
		 }
	       }
	       else
		 xBuffer = buffer;
	       status = CDFlib (&Cur,
				PUT_, item, xBuffer,
				NULL_);
	       if (xBuffer != buffer) free (xBuffer);
	       CSC (status,pStatus,Cur,argv)	/* Check after freeing. */
	       break;
	     }
	     /*****************************************************************
	     * PUT_,rVARs_RECDATA_/zVARs_RECDATA_: Unsupported.
	     *****************************************************************/
	     case rVARs_RECDATA_:
	     case zVARs_RECDATA_: {
	       RETURNsX(UNSUPPORTED_OPERATION,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * PUT_,gENTRY_DATA_/rENTRY_DATA/zENTRY_DATA_: put an entry value
	     *****************************************************************/
	     case gENTRY_DATA_:
	     case rENTRY_DATA_:
	     case zENTRY_DATA_: {
	       long dataType, numElems; void *value;
	       if (!CastToLong(argv[argX++],
			       &dataType)) RETURNsX(BAD_ARGUMENT,Cur,argv)
	       if (!CastToLong(argv[argX++],
			       &numElems)) RETURNsX(BAD_ARGUMENT,Cur,argv)
	       if (!DataPtr(argv[argX++],
			    &value)) RETURNsX(BAD_ARGUMENT,Cur,argv)
	       status = CDFlib (&Cur,
				PUT_, item, dataType, numElems, value,
				NULL_);
	       CSC (status,pStatus,Cur,argv)
	       break;
	     }
	     /*****************************************************************
	     * Unknown item - hopefully the next operation.
	     *****************************************************************/
	     default: {
	       fnc = item;
	       break;
	     }
	   }
	   if (fnc == item) break;
        }
        break;
      /************************************************************************
      * Unknown function.
      ************************************************************************/
      default:
	RETURNsX(BAD_FNC_OR_ITEM,Cur,argv)
    }
  }
  RETURNsX(pStatus,Cur,argv)
}

/******************************************************************************
* idl_epochbreak.
******************************************************************************/

void idl_epochbreak (argc, argv)
int argc;
IDL_VPTR argv[];
{
  long year, month, day, hour, minute, second, msec; double epoch;
  if (!CastToDouble(argv[0],&epoch)) epoch = 0.0;
  EPOCHbreakdown (epoch, &year, &month, &day, &hour, &minute, &second, &msec);
  StoreLong (argv[1], year);
  StoreLong (argv[2], month);
  StoreLong (argv[3], day);
  StoreLong (argv[4], hour);
  StoreLong (argv[5], minute);
  StoreLong (argv[6], second);
  StoreLong (argv[7], msec);
  return;
}

/******************************************************************************
* idl_computepoch.
******************************************************************************/

void idl_computepoch (argc, argv)
int argc;
IDL_VPTR argv[];
{
  long year, month, day, hour, minute, second, msec; double epoch;
  if (!CastToLong(argv[0],&year)) eRETURN(argv[7],ILLEGAL_EPOCH_VALUE)
  if (!CastToLong(argv[1],&month)) eRETURN(argv[7],ILLEGAL_EPOCH_VALUE)
  if (!CastToLong(argv[2],&day)) eRETURN(argv[7],ILLEGAL_EPOCH_VALUE)
  if (!CastToLong(argv[3],&hour)) eRETURN(argv[7],ILLEGAL_EPOCH_VALUE)
  if (!CastToLong(argv[4],&minute)) eRETURN(argv[7],ILLEGAL_EPOCH_VALUE)
  if (!CastToLong(argv[5],&second)) eRETURN(argv[7],ILLEGAL_EPOCH_VALUE)
  if (!CastToLong(argv[6],&msec)) eRETURN(argv[7],ILLEGAL_EPOCH_VALUE)
  epoch = computeEPOCH(year,month,day,hour,minute,second,msec);
  eRETURN(argv[7],epoch)
}

/******************************************************************************
* idl_parseepoch.
******************************************************************************/

void idl_parsepoch (argc, argv)
int argc;
IDL_VPTR argv[];
{
  char *epString; double epoch;
  if (!StringPtr(argv[0],&epString)) eRETURN(argv[1],ILLEGAL_EPOCH_VALUE);
  epoch = parseEPOCH(epString);
  eRETURN(argv[1],epoch)
}

/******************************************************************************
* idl_parseepoch1.
******************************************************************************/

void idl_parsepoch1 (argc, argv)
int argc;
IDL_VPTR argv[];
{
  char *epString; double epoch;
  if (!StringPtr(argv[0],&epString)) eRETURN(argv[1],ILLEGAL_EPOCH_VALUE);
  epoch = parseEPOCH1(epString);
  eRETURN(argv[1],epoch)
}

/******************************************************************************
* idl_parseepoch2.
******************************************************************************/

void idl_parsepoch2 (argc, argv)
int argc;
IDL_VPTR argv[];
{
  char *epString; double epoch;
  if (!StringPtr(argv[0],&epString)) eRETURN(argv[1],ILLEGAL_EPOCH_VALUE);
  epoch = parseEPOCH2(epString);
  eRETURN(argv[1],epoch)
}

/******************************************************************************
* idl_parseepoch3.
******************************************************************************/

void idl_parsepoch3 (argc, argv)
int argc;
IDL_VPTR argv[];
{
  char *epString; double epoch;
  if (!StringPtr(argv[0],&epString)) eRETURN(argv[1],ILLEGAL_EPOCH_VALUE);
  epoch = parseEPOCH3(epString);
  eRETURN(argv[1],epoch)
}

/******************************************************************************
* idl_encodepoch.
******************************************************************************/

void idl_encodepoch (argc, argv)
int argc;
IDL_VPTR argv[];
{
  double epoch; char epString[EPOCH_STRING_LEN+1];
  if (!CastToDouble(argv[0],&epoch)) strRETURN(argv[1],"?")
  encodeEPOCH (epoch, epString);
  strRETURN(argv[1],epString);
}

/******************************************************************************
* idl_encodepoch1.
******************************************************************************/

void idl_encodepoch1 (argc, argv)
int argc;
IDL_VPTR argv[];
{
  double epoch; char epString[EPOCH1_STRING_LEN+1];
  if (!CastToDouble(argv[0],&epoch)) strRETURN(argv[1],"?")
  encodeEPOCH1 (epoch, epString);
  strRETURN(argv[1],epString)
}

/******************************************************************************
* idl_encodepoch2.
******************************************************************************/

void idl_encodepoch2 (argc, argv)
int argc;
IDL_VPTR argv[];
{
  double epoch; char epString[EPOCH2_STRING_LEN+1];
  if (!CastToDouble(argv[0],&epoch)) strRETURN(argv[1],"?")
  encodeEPOCH2 (epoch, epString);
  strRETURN(argv[1],epString)
}

/******************************************************************************
* idl_encodepoch3.
******************************************************************************/

void idl_encodepoch3 (argc, argv)
int argc;
IDL_VPTR argv[];
{
  double epoch; char epString[EPOCH3_STRING_LEN+1];
  if (!CastToDouble(argv[0],&epoch)) strRETURN(argv[1],"?")
  encodeEPOCH3 (epoch, epString);
  strRETURN(argv[1],epString)
}

/******************************************************************************
* idl_encodepochx.
******************************************************************************/

void idl_encodepochx (argc, argv)
int argc;
IDL_VPTR argv[];
{
  double epoch; char epString[EPOCHx_STRING_MAX+1], *format;
  if (!CastToDouble(argv[0],&epoch)) strRETURN(argv[2],"?")
  if (!StringPtr(argv[1],&format)) strRETURN(argv[2],"?")
  encodeEPOCHx (epoch, format, epString);
  strRETURN(argv[2],epString)
}


/******************************************************************************
* row_2_col.
******************************************************************************/

void row_2_col (argc, argv)
int argc;
IDL_VPTR argv[];
{
  void *iBuffer, *oBuffer; long i, offset, bytes_per_record, record_num;
  long numDims, dimSizes[CDF_MAX_DIMS], nValueBytes, num_records, nvalues;
  if (!DataPtr(argv[0],&iBuffer)) sRETURN(argv[6],BAD_ARGUMENT)
  if (!DataPtr(argv[1],&oBuffer)) sRETURN(argv[6],BAD_ARGUMENT)
  if (!CastToLong(argv[2],&numDims)) sRETURN(argv[6],BAD_ARGUMENT)
  if (!BuildLongArray(argv[3],dimSizes,
		      CDF_MAX_DIMS)) sRETURN(argv[6],BAD_ARGUMENT)
  if (!CastToLong(argv[4],&nValueBytes)) sRETURN(argv[6],BAD_ARGUMENT)
  if (!CastToLong(argv[5],&num_records)) sRETURN(argv[6],BAD_ARGUMENT)
  nvalues = 1;
  for (i = 0; i < numDims; i++) nvalues = nvalues * dimSizes[i];
  bytes_per_record = nvalues * nValueBytes;
  offset = 0;
  for (record_num = 0; record_num < num_records; record_num++){
     ROWtoCOL ((Byte *)iBuffer+offset, (Byte *)oBuffer+offset, numDims, 
	       dimSizes, nValueBytes);
     offset += bytes_per_record;
  }
  sRETURN(argv[6],CDF_OK)
}

/******************************************************************************
* col_2_row.
******************************************************************************/

void col_2_row (argc, argv)
int argc;
IDL_VPTR argv[];
{
  void *iBuffer, *oBuffer; long i, offset, bytes_per_record, record_num;
  long numDims, dimSizes[CDF_MAX_DIMS], nValueBytes, num_records, nvalues;
  if (!DataPtr(argv[0],&iBuffer)) sRETURN(argv[6],BAD_ARGUMENT)
  if (!DataPtr(argv[1],&oBuffer)) sRETURN(argv[6],BAD_ARGUMENT)
  if (!CastToLong(argv[2],&numDims)) sRETURN(argv[6],BAD_ARGUMENT)
  if (!BuildLongArray(argv[3],dimSizes,
		      CDF_MAX_DIMS)) sRETURN(argv[6],BAD_ARGUMENT)
  if (!CastToLong(argv[4],&nValueBytes)) sRETURN(argv[6],BAD_ARGUMENT)
  if (!CastToLong(argv[5],&num_records)) sRETURN(argv[6],BAD_ARGUMENT)
  nvalues = 1;
  for (i = 0; i < numDims; i++) nvalues = nvalues * dimSizes[i];
  bytes_per_record = nvalues * nValueBytes;
  offset = 0;
  for (record_num = 0; record_num < num_records; record_num++){
     COLtoROW ((Byte *)iBuffer+offset, (Byte *)oBuffer+offset, numDims, 
	       dimSizes, nValueBytes);
     offset += bytes_per_record;
  }
  sRETURN(argv[6],CDF_OK)
}

/******************************************************************************
* Include the CDF library source files.
******************************************************************************/

#include "cdflib.c"
#include "cdfcre.c"
#include "cdfope.c"
#include "cdfclo.c"
#include "cdfdel.c"
#include "cdfget.c"
#include "cdfput1.c"
#include "cdfput2.c"
#include "cdfsel.c"
#include "cdfcon.c"
#include "cdfread.c"
#include "cdfwrite.c"
#include "cdftext.c"
#include "cdfed.c"
#include "cdfstr.c"
#include "cdfvalid.c"
#include "cdfhyper.c"
#include "cdfmisc1.c"
#include "cdfmisc2.c"
#include "cdfmisc3.c"
#include "cdfmem.c"
#include "cdfalloc.c"
#include "cdfhuff.c"
#include "cdfrle.c"
#include "cdfgzip.c"
#include "vstream.c"
#include "epochu.c"
#include "dirutils.c"

