Logo Search packages:      
Sourcecode: netcdf version File versions  Download package

test_get.c

/* Do not edit this file. It is produced from the corresponding .m4 source */
/*********************************************************************
 *   Copyright 1996, UCAR/Unidata
 *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
 *   $Id: test_get.m4,v 1.14 1997/05/06 18:00:41 davis Exp $
 *********************************************************************/


#include "tests.h"


void
test_nc_get_var1_text(void)
{
    int ncid;
    int i;
    int j;
    int err;
    int nok = 0;      /* count of valid comparisons */
    size_t index[MAX_RANK];
    double expect;
    int canConvert;     /* Both text or both numeric */
    text value;

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_TEXT == NCT_TEXT);
      for (j = 0; j < var_rank[i]; j++)
          index[j] = 0;
        err = nc_get_var1_text(BAD_ID, i, index, &value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_var1_text(ncid, BAD_VARID, index, &value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);
      for (j = 0; j < var_rank[i]; j++) {
          index[j] = var_shape[i][j];
          err = nc_get_var1_text(ncid, i, index, &value);
          if(!canConvert) {
            IF(err != NC_ECHAR)
                  error("conversion: status = %d", err);
          } else IF (err != NC_EINVALCOORDS)
            error("bad index: status = %d", err);
          index[j] = 0;
      }
      for (j = 0; j < var_nels[i]; j++) {
          err = toMixedBase(j, var_rank[i], var_shape[i], index);
          IF (err)
            error("error in toMixedBase 1");
          expect = hash4( var_type[i], var_rank[i], index, NCT_TEXT );
          if (var_rank[i] == 0 && i%2 )
            err = nc_get_var1_text(ncid, i, NULL, &value);
          else
            err = nc_get_var1_text(ncid, i, index, &value);
            if (canConvert) {
            if (inRange3(expect,var_type[i], NCT_TEXT)) {
                if (expect >= text_min && expect <= text_max) {
                  IF (err) {
                      error("%s", nc_strerror(err));
                  } else {
                      IF (!equal(value,expect,var_type[i],NCT_TEXT)) {
                        error("expected: %G, got: %G", expect,
                            (double) value);
                      } else {
                        nok++;
                      }
                  }
                } else {
                  IF (err != NC_ERANGE)
                      error("Range error: status = %d", err);
                }
                } else {
                    IF (err != 0 && err != NC_ERANGE)
                        error("OK or Range error: status = %d", err);
            }
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
      }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_var1_uchar(void)
{
    int ncid;
    int i;
    int j;
    int err;
    int nok = 0;      /* count of valid comparisons */
    size_t index[MAX_RANK];
    double expect;
    int canConvert;     /* Both text or both numeric */
    uchar value;

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_UCHAR == NCT_TEXT);
      for (j = 0; j < var_rank[i]; j++)
          index[j] = 0;
        err = nc_get_var1_uchar(BAD_ID, i, index, &value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_var1_uchar(ncid, BAD_VARID, index, &value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);
      for (j = 0; j < var_rank[i]; j++) {
          index[j] = var_shape[i][j];
          err = nc_get_var1_uchar(ncid, i, index, &value);
          if(!canConvert) {
            IF(err != NC_ECHAR)
                  error("conversion: status = %d", err);
          } else IF (err != NC_EINVALCOORDS)
            error("bad index: status = %d", err);
          index[j] = 0;
      }
      for (j = 0; j < var_nels[i]; j++) {
          err = toMixedBase(j, var_rank[i], var_shape[i], index);
          IF (err)
            error("error in toMixedBase 1");
          expect = hash4( var_type[i], var_rank[i], index, NCT_UCHAR );
          if (var_rank[i] == 0 && i%2 )
            err = nc_get_var1_uchar(ncid, i, NULL, &value);
          else
            err = nc_get_var1_uchar(ncid, i, index, &value);
            if (canConvert) {
            if (inRange3(expect,var_type[i], NCT_UCHAR)) {
                if (expect >= uchar_min && expect <= uchar_max) {
                  IF (err) {
                      error("%s", nc_strerror(err));
                  } else {
                      IF (!equal(value,expect,var_type[i],NCT_UCHAR)) {
                        error("expected: %G, got: %G", expect,
                            (double) value);
                      } else {
                        nok++;
                      }
                  }
                } else {
                  IF (err != NC_ERANGE)
                      error("Range error: status = %d", err);
                }
                } else {
                    IF (err != 0 && err != NC_ERANGE)
                        error("OK or Range error: status = %d", err);
            }
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
      }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_var1_schar(void)
{
    int ncid;
    int i;
    int j;
    int err;
    int nok = 0;      /* count of valid comparisons */
    size_t index[MAX_RANK];
    double expect;
    int canConvert;     /* Both text or both numeric */
    schar value;

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_SCHAR == NCT_TEXT);
      for (j = 0; j < var_rank[i]; j++)
          index[j] = 0;
        err = nc_get_var1_schar(BAD_ID, i, index, &value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_var1_schar(ncid, BAD_VARID, index, &value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);
      for (j = 0; j < var_rank[i]; j++) {
          index[j] = var_shape[i][j];
          err = nc_get_var1_schar(ncid, i, index, &value);
          if(!canConvert) {
            IF(err != NC_ECHAR)
                  error("conversion: status = %d", err);
          } else IF (err != NC_EINVALCOORDS)
            error("bad index: status = %d", err);
          index[j] = 0;
      }
      for (j = 0; j < var_nels[i]; j++) {
          err = toMixedBase(j, var_rank[i], var_shape[i], index);
          IF (err)
            error("error in toMixedBase 1");
          expect = hash4( var_type[i], var_rank[i], index, NCT_SCHAR );
          if (var_rank[i] == 0 && i%2 )
            err = nc_get_var1_schar(ncid, i, NULL, &value);
          else
            err = nc_get_var1_schar(ncid, i, index, &value);
            if (canConvert) {
            if (inRange3(expect,var_type[i], NCT_SCHAR)) {
                if (expect >= schar_min && expect <= schar_max) {
                  IF (err) {
                      error("%s", nc_strerror(err));
                  } else {
                      IF (!equal(value,expect,var_type[i],NCT_SCHAR)) {
                        error("expected: %G, got: %G", expect,
                            (double) value);
                      } else {
                        nok++;
                      }
                  }
                } else {
                  IF (err != NC_ERANGE)
                      error("Range error: status = %d", err);
                }
                } else {
                    IF (err != 0 && err != NC_ERANGE)
                        error("OK or Range error: status = %d", err);
            }
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
      }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_var1_short(void)
{
    int ncid;
    int i;
    int j;
    int err;
    int nok = 0;      /* count of valid comparisons */
    size_t index[MAX_RANK];
    double expect;
    int canConvert;     /* Both text or both numeric */
    short value;

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_SHORT == NCT_TEXT);
      for (j = 0; j < var_rank[i]; j++)
          index[j] = 0;
        err = nc_get_var1_short(BAD_ID, i, index, &value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_var1_short(ncid, BAD_VARID, index, &value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);
      for (j = 0; j < var_rank[i]; j++) {
          index[j] = var_shape[i][j];
          err = nc_get_var1_short(ncid, i, index, &value);
          if(!canConvert) {
            IF(err != NC_ECHAR)
                  error("conversion: status = %d", err);
          } else IF (err != NC_EINVALCOORDS)
            error("bad index: status = %d", err);
          index[j] = 0;
      }
      for (j = 0; j < var_nels[i]; j++) {
          err = toMixedBase(j, var_rank[i], var_shape[i], index);
          IF (err)
            error("error in toMixedBase 1");
          expect = hash4( var_type[i], var_rank[i], index, NCT_SHORT );
          if (var_rank[i] == 0 && i%2 )
            err = nc_get_var1_short(ncid, i, NULL, &value);
          else
            err = nc_get_var1_short(ncid, i, index, &value);
            if (canConvert) {
            if (inRange3(expect,var_type[i], NCT_SHORT)) {
                if (expect >= short_min && expect <= short_max) {
                  IF (err) {
                      error("%s", nc_strerror(err));
                  } else {
                      IF (!equal(value,expect,var_type[i],NCT_SHORT)) {
                        error("expected: %G, got: %G", expect,
                            (double) value);
                      } else {
                        nok++;
                      }
                  }
                } else {
                  IF (err != NC_ERANGE)
                      error("Range error: status = %d", err);
                }
                } else {
                    IF (err != 0 && err != NC_ERANGE)
                        error("OK or Range error: status = %d", err);
            }
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
      }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_var1_int(void)
{
    int ncid;
    int i;
    int j;
    int err;
    int nok = 0;      /* count of valid comparisons */
    size_t index[MAX_RANK];
    double expect;
    int canConvert;     /* Both text or both numeric */
    int value;

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_INT == NCT_TEXT);
      for (j = 0; j < var_rank[i]; j++)
          index[j] = 0;
        err = nc_get_var1_int(BAD_ID, i, index, &value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_var1_int(ncid, BAD_VARID, index, &value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);
      for (j = 0; j < var_rank[i]; j++) {
          index[j] = var_shape[i][j];
          err = nc_get_var1_int(ncid, i, index, &value);
          if(!canConvert) {
            IF(err != NC_ECHAR)
                  error("conversion: status = %d", err);
          } else IF (err != NC_EINVALCOORDS)
            error("bad index: status = %d", err);
          index[j] = 0;
      }
      for (j = 0; j < var_nels[i]; j++) {
          err = toMixedBase(j, var_rank[i], var_shape[i], index);
          IF (err)
            error("error in toMixedBase 1");
          expect = hash4( var_type[i], var_rank[i], index, NCT_INT );
          if (var_rank[i] == 0 && i%2 )
            err = nc_get_var1_int(ncid, i, NULL, &value);
          else
            err = nc_get_var1_int(ncid, i, index, &value);
            if (canConvert) {
            if (inRange3(expect,var_type[i], NCT_INT)) {
                if (expect >= int_min && expect <= int_max) {
                  IF (err) {
                      error("%s", nc_strerror(err));
                  } else {
                      IF (!equal(value,expect,var_type[i],NCT_INT)) {
                        error("expected: %G, got: %G", expect,
                            (double) value);
                      } else {
                        nok++;
                      }
                  }
                } else {
                  IF (err != NC_ERANGE)
                      error("Range error: status = %d", err);
                }
                } else {
                    IF (err != 0 && err != NC_ERANGE)
                        error("OK or Range error: status = %d", err);
            }
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
      }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_var1_long(void)
{
    int ncid;
    int i;
    int j;
    int err;
    int nok = 0;      /* count of valid comparisons */
    size_t index[MAX_RANK];
    double expect;
    int canConvert;     /* Both text or both numeric */
    long value;

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_LONG == NCT_TEXT);
      for (j = 0; j < var_rank[i]; j++)
          index[j] = 0;
        err = nc_get_var1_long(BAD_ID, i, index, &value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_var1_long(ncid, BAD_VARID, index, &value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);
      for (j = 0; j < var_rank[i]; j++) {
          index[j] = var_shape[i][j];
          err = nc_get_var1_long(ncid, i, index, &value);
          if(!canConvert) {
            IF(err != NC_ECHAR)
                  error("conversion: status = %d", err);
          } else IF (err != NC_EINVALCOORDS)
            error("bad index: status = %d", err);
          index[j] = 0;
      }
      for (j = 0; j < var_nels[i]; j++) {
          err = toMixedBase(j, var_rank[i], var_shape[i], index);
          IF (err)
            error("error in toMixedBase 1");
          expect = hash4( var_type[i], var_rank[i], index, NCT_LONG );
          if (var_rank[i] == 0 && i%2 )
            err = nc_get_var1_long(ncid, i, NULL, &value);
          else
            err = nc_get_var1_long(ncid, i, index, &value);
            if (canConvert) {
            if (inRange3(expect,var_type[i], NCT_LONG)) {
                if (expect >= long_min && expect <= long_max) {
                  IF (err) {
                      error("%s", nc_strerror(err));
                  } else {
                      IF (!equal(value,expect,var_type[i],NCT_LONG)) {
                        error("expected: %G, got: %G", expect,
                            (double) value);
                      } else {
                        nok++;
                      }
                  }
                } else {
                  IF (err != NC_ERANGE)
                      error("Range error: status = %d", err);
                }
                } else {
                    IF (err != 0 && err != NC_ERANGE)
                        error("OK or Range error: status = %d", err);
            }
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
      }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_var1_float(void)
{
    int ncid;
    int i;
    int j;
    int err;
    int nok = 0;      /* count of valid comparisons */
    size_t index[MAX_RANK];
    double expect;
    int canConvert;     /* Both text or both numeric */
    float value;

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_FLOAT == NCT_TEXT);
      for (j = 0; j < var_rank[i]; j++)
          index[j] = 0;
        err = nc_get_var1_float(BAD_ID, i, index, &value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_var1_float(ncid, BAD_VARID, index, &value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);
      for (j = 0; j < var_rank[i]; j++) {
          index[j] = var_shape[i][j];
          err = nc_get_var1_float(ncid, i, index, &value);
          if(!canConvert) {
            IF(err != NC_ECHAR)
                  error("conversion: status = %d", err);
          } else IF (err != NC_EINVALCOORDS)
            error("bad index: status = %d", err);
          index[j] = 0;
      }
      for (j = 0; j < var_nels[i]; j++) {
          err = toMixedBase(j, var_rank[i], var_shape[i], index);
          IF (err)
            error("error in toMixedBase 1");
          expect = hash4( var_type[i], var_rank[i], index, NCT_FLOAT );
          if (var_rank[i] == 0 && i%2 )
            err = nc_get_var1_float(ncid, i, NULL, &value);
          else
            err = nc_get_var1_float(ncid, i, index, &value);
            if (canConvert) {
            if (inRange3(expect,var_type[i], NCT_FLOAT)) {
                if (expect >= float_min && expect <= float_max) {
                  IF (err) {
                      error("%s", nc_strerror(err));
                  } else {
                      IF (!equal(value,expect,var_type[i],NCT_FLOAT)) {
                        error("expected: %G, got: %G", expect,
                            (double) value);
                      } else {
                        nok++;
                      }
                  }
                } else {
                  IF (err != NC_ERANGE)
                      error("Range error: status = %d", err);
                }
                } else {
                    IF (err != 0 && err != NC_ERANGE)
                        error("OK or Range error: status = %d", err);
            }
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
      }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_var1_double(void)
{
    int ncid;
    int i;
    int j;
    int err;
    int nok = 0;      /* count of valid comparisons */
    size_t index[MAX_RANK];
    double expect;
    int canConvert;     /* Both text or both numeric */
    double value;

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_DOUBLE == NCT_TEXT);
      for (j = 0; j < var_rank[i]; j++)
          index[j] = 0;
        err = nc_get_var1_double(BAD_ID, i, index, &value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_var1_double(ncid, BAD_VARID, index, &value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);
      for (j = 0; j < var_rank[i]; j++) {
          index[j] = var_shape[i][j];
          err = nc_get_var1_double(ncid, i, index, &value);
          if(!canConvert) {
            IF(err != NC_ECHAR)
                  error("conversion: status = %d", err);
          } else IF (err != NC_EINVALCOORDS)
            error("bad index: status = %d", err);
          index[j] = 0;
      }
      for (j = 0; j < var_nels[i]; j++) {
          err = toMixedBase(j, var_rank[i], var_shape[i], index);
          IF (err)
            error("error in toMixedBase 1");
          expect = hash4( var_type[i], var_rank[i], index, NCT_DOUBLE );
          if (var_rank[i] == 0 && i%2 )
            err = nc_get_var1_double(ncid, i, NULL, &value);
          else
            err = nc_get_var1_double(ncid, i, index, &value);
            if (canConvert) {
            if (inRange3(expect,var_type[i], NCT_DOUBLE)) {
                if (expect >= double_min && expect <= double_max) {
                  IF (err) {
                      error("%s", nc_strerror(err));
                  } else {
                      IF (!equal(value,expect,var_type[i],NCT_DOUBLE)) {
                        error("expected: %G, got: %G", expect,
                            (double) value);
                      } else {
                        nok++;
                      }
                  }
                } else {
                  IF (err != NC_ERANGE)
                      error("Range error: status = %d", err);
                }
                } else {
                    IF (err != 0 && err != NC_ERANGE)
                        error("OK or Range error: status = %d", err);
            }
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
      }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}




void
test_nc_get_var_text(void)
{
    int ncid;
    int i;
    int j;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nok = 0;      /* count of valid comparisons */
    size_t index[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    text value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_TEXT == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        err = nc_get_var_text(BAD_ID, i, value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_var_text(ncid, BAD_VARID, value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);

      nels = 1;
      for (j = 0; j < var_rank[i]; j++) {
          nels *= var_shape[i][j];
      }
      allInExtRange = allInIntRange = 1;
      for (j = 0; j < nels; j++) {
          err = toMixedBase(j, var_rank[i], var_shape[i], index);
          IF (err)
            error("error in toMixedBase 1");
          expect[j] = hash4(var_type[i], var_rank[i], index, NCT_TEXT);
          if (inRange3(expect[j],var_type[i], NCT_TEXT)) {
            allInIntRange = allInIntRange && expect[j] >= text_min
                      && expect[j] <= text_max;
          } else {
            allInExtRange = 0;
          }
      }
      err = nc_get_var_text(ncid, i, value);
      if (canConvert) {
          if (allInExtRange) {
            if (allInIntRange) {
                IF (err)
                  error("%s", nc_strerror(err));
            } else {
                IF (err != NC_ERANGE)
                  error("Range error: status = %d", err);
            }
          } else {
            IF (err != 0 && err != NC_ERANGE)
                error("OK or Range error: status = %d", err);
          }
          for (j = 0; j < nels; j++) {
            if (inRange3(expect[j],var_type[i],NCT_TEXT)
                  && expect[j] >= text_min && expect[j] <= text_max) {
                IF (!equal(value[j],expect[j],var_type[i],NCT_TEXT)){
                  error("value read not that expected");
                  if (verbose) {
                      error("\n");
                      error("varid: %d, ", i);
                      error("var_name: %s, ", var_name[i]);
                      error("element number: %d ", j);
                      error("expect: %g", expect[j]);
                      error("got: %g", (double) value[j]);
                  }
                } else {
                  nok++;
                }
            }
          }
      } else {
          IF (nels > 0 && err != NC_ECHAR)
            error("wrong type: status = %d", err);
      }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_var_uchar(void)
{
    int ncid;
    int i;
    int j;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nok = 0;      /* count of valid comparisons */
    size_t index[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    uchar value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_UCHAR == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        err = nc_get_var_uchar(BAD_ID, i, value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_var_uchar(ncid, BAD_VARID, value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);

      nels = 1;
      for (j = 0; j < var_rank[i]; j++) {
          nels *= var_shape[i][j];
      }
      allInExtRange = allInIntRange = 1;
      for (j = 0; j < nels; j++) {
          err = toMixedBase(j, var_rank[i], var_shape[i], index);
          IF (err)
            error("error in toMixedBase 1");
          expect[j] = hash4(var_type[i], var_rank[i], index, NCT_UCHAR);
          if (inRange3(expect[j],var_type[i], NCT_UCHAR)) {
            allInIntRange = allInIntRange && expect[j] >= uchar_min
                      && expect[j] <= uchar_max;
          } else {
            allInExtRange = 0;
          }
      }
      err = nc_get_var_uchar(ncid, i, value);
      if (canConvert) {
          if (allInExtRange) {
            if (allInIntRange) {
                IF (err)
                  error("%s", nc_strerror(err));
            } else {
                IF (err != NC_ERANGE)
                  error("Range error: status = %d", err);
            }
          } else {
            IF (err != 0 && err != NC_ERANGE)
                error("OK or Range error: status = %d", err);
          }
          for (j = 0; j < nels; j++) {
            if (inRange3(expect[j],var_type[i],NCT_UCHAR)
                  && expect[j] >= uchar_min && expect[j] <= uchar_max) {
                IF (!equal(value[j],expect[j],var_type[i],NCT_UCHAR)){
                  error("value read not that expected");
                  if (verbose) {
                      error("\n");
                      error("varid: %d, ", i);
                      error("var_name: %s, ", var_name[i]);
                      error("element number: %d ", j);
                      error("expect: %g", expect[j]);
                      error("got: %g", (double) value[j]);
                  }
                } else {
                  nok++;
                }
            }
          }
      } else {
          IF (nels > 0 && err != NC_ECHAR)
            error("wrong type: status = %d", err);
      }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_var_schar(void)
{
    int ncid;
    int i;
    int j;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nok = 0;      /* count of valid comparisons */
    size_t index[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    schar value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_SCHAR == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        err = nc_get_var_schar(BAD_ID, i, value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_var_schar(ncid, BAD_VARID, value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);

      nels = 1;
      for (j = 0; j < var_rank[i]; j++) {
          nels *= var_shape[i][j];
      }
      allInExtRange = allInIntRange = 1;
      for (j = 0; j < nels; j++) {
          err = toMixedBase(j, var_rank[i], var_shape[i], index);
          IF (err)
            error("error in toMixedBase 1");
          expect[j] = hash4(var_type[i], var_rank[i], index, NCT_SCHAR);
          if (inRange3(expect[j],var_type[i], NCT_SCHAR)) {
            allInIntRange = allInIntRange && expect[j] >= schar_min
                      && expect[j] <= schar_max;
          } else {
            allInExtRange = 0;
          }
      }
      err = nc_get_var_schar(ncid, i, value);
      if (canConvert) {
          if (allInExtRange) {
            if (allInIntRange) {
                IF (err)
                  error("%s", nc_strerror(err));
            } else {
                IF (err != NC_ERANGE)
                  error("Range error: status = %d", err);
            }
          } else {
            IF (err != 0 && err != NC_ERANGE)
                error("OK or Range error: status = %d", err);
          }
          for (j = 0; j < nels; j++) {
            if (inRange3(expect[j],var_type[i],NCT_SCHAR)
                  && expect[j] >= schar_min && expect[j] <= schar_max) {
                IF (!equal(value[j],expect[j],var_type[i],NCT_SCHAR)){
                  error("value read not that expected");
                  if (verbose) {
                      error("\n");
                      error("varid: %d, ", i);
                      error("var_name: %s, ", var_name[i]);
                      error("element number: %d ", j);
                      error("expect: %g", expect[j]);
                      error("got: %g", (double) value[j]);
                  }
                } else {
                  nok++;
                }
            }
          }
      } else {
          IF (nels > 0 && err != NC_ECHAR)
            error("wrong type: status = %d", err);
      }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_var_short(void)
{
    int ncid;
    int i;
    int j;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nok = 0;      /* count of valid comparisons */
    size_t index[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    short value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_SHORT == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        err = nc_get_var_short(BAD_ID, i, value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_var_short(ncid, BAD_VARID, value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);

      nels = 1;
      for (j = 0; j < var_rank[i]; j++) {
          nels *= var_shape[i][j];
      }
      allInExtRange = allInIntRange = 1;
      for (j = 0; j < nels; j++) {
          err = toMixedBase(j, var_rank[i], var_shape[i], index);
          IF (err)
            error("error in toMixedBase 1");
          expect[j] = hash4(var_type[i], var_rank[i], index, NCT_SHORT);
          if (inRange3(expect[j],var_type[i], NCT_SHORT)) {
            allInIntRange = allInIntRange && expect[j] >= short_min
                      && expect[j] <= short_max;
          } else {
            allInExtRange = 0;
          }
      }
      err = nc_get_var_short(ncid, i, value);
      if (canConvert) {
          if (allInExtRange) {
            if (allInIntRange) {
                IF (err)
                  error("%s", nc_strerror(err));
            } else {
                IF (err != NC_ERANGE)
                  error("Range error: status = %d", err);
            }
          } else {
            IF (err != 0 && err != NC_ERANGE)
                error("OK or Range error: status = %d", err);
          }
          for (j = 0; j < nels; j++) {
            if (inRange3(expect[j],var_type[i],NCT_SHORT)
                  && expect[j] >= short_min && expect[j] <= short_max) {
                IF (!equal(value[j],expect[j],var_type[i],NCT_SHORT)){
                  error("value read not that expected");
                  if (verbose) {
                      error("\n");
                      error("varid: %d, ", i);
                      error("var_name: %s, ", var_name[i]);
                      error("element number: %d ", j);
                      error("expect: %g", expect[j]);
                      error("got: %g", (double) value[j]);
                  }
                } else {
                  nok++;
                }
            }
          }
      } else {
          IF (nels > 0 && err != NC_ECHAR)
            error("wrong type: status = %d", err);
      }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_var_int(void)
{
    int ncid;
    int i;
    int j;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nok = 0;      /* count of valid comparisons */
    size_t index[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    int value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_INT == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        err = nc_get_var_int(BAD_ID, i, value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_var_int(ncid, BAD_VARID, value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);

      nels = 1;
      for (j = 0; j < var_rank[i]; j++) {
          nels *= var_shape[i][j];
      }
      allInExtRange = allInIntRange = 1;
      for (j = 0; j < nels; j++) {
          err = toMixedBase(j, var_rank[i], var_shape[i], index);
          IF (err)
            error("error in toMixedBase 1");
          expect[j] = hash4(var_type[i], var_rank[i], index, NCT_INT);
          if (inRange3(expect[j],var_type[i], NCT_INT)) {
            allInIntRange = allInIntRange && expect[j] >= int_min
                      && expect[j] <= int_max;
          } else {
            allInExtRange = 0;
          }
      }
      err = nc_get_var_int(ncid, i, value);
      if (canConvert) {
          if (allInExtRange) {
            if (allInIntRange) {
                IF (err)
                  error("%s", nc_strerror(err));
            } else {
                IF (err != NC_ERANGE)
                  error("Range error: status = %d", err);
            }
          } else {
            IF (err != 0 && err != NC_ERANGE)
                error("OK or Range error: status = %d", err);
          }
          for (j = 0; j < nels; j++) {
            if (inRange3(expect[j],var_type[i],NCT_INT)
                  && expect[j] >= int_min && expect[j] <= int_max) {
                IF (!equal(value[j],expect[j],var_type[i],NCT_INT)){
                  error("value read not that expected");
                  if (verbose) {
                      error("\n");
                      error("varid: %d, ", i);
                      error("var_name: %s, ", var_name[i]);
                      error("element number: %d ", j);
                      error("expect: %g", expect[j]);
                      error("got: %g", (double) value[j]);
                  }
                } else {
                  nok++;
                }
            }
          }
      } else {
          IF (nels > 0 && err != NC_ECHAR)
            error("wrong type: status = %d", err);
      }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_var_long(void)
{
    int ncid;
    int i;
    int j;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nok = 0;      /* count of valid comparisons */
    size_t index[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    long value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_LONG == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        err = nc_get_var_long(BAD_ID, i, value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_var_long(ncid, BAD_VARID, value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);

      nels = 1;
      for (j = 0; j < var_rank[i]; j++) {
          nels *= var_shape[i][j];
      }
      allInExtRange = allInIntRange = 1;
      for (j = 0; j < nels; j++) {
          err = toMixedBase(j, var_rank[i], var_shape[i], index);
          IF (err)
            error("error in toMixedBase 1");
          expect[j] = hash4(var_type[i], var_rank[i], index, NCT_LONG);
          if (inRange3(expect[j],var_type[i], NCT_LONG)) {
            allInIntRange = allInIntRange && expect[j] >= long_min
                      && expect[j] <= long_max;
          } else {
            allInExtRange = 0;
          }
      }
      err = nc_get_var_long(ncid, i, value);
      if (canConvert) {
          if (allInExtRange) {
            if (allInIntRange) {
                IF (err)
                  error("%s", nc_strerror(err));
            } else {
                IF (err != NC_ERANGE)
                  error("Range error: status = %d", err);
            }
          } else {
            IF (err != 0 && err != NC_ERANGE)
                error("OK or Range error: status = %d", err);
          }
          for (j = 0; j < nels; j++) {
            if (inRange3(expect[j],var_type[i],NCT_LONG)
                  && expect[j] >= long_min && expect[j] <= long_max) {
                IF (!equal(value[j],expect[j],var_type[i],NCT_LONG)){
                  error("value read not that expected");
                  if (verbose) {
                      error("\n");
                      error("varid: %d, ", i);
                      error("var_name: %s, ", var_name[i]);
                      error("element number: %d ", j);
                      error("expect: %g", expect[j]);
                      error("got: %g", (double) value[j]);
                  }
                } else {
                  nok++;
                }
            }
          }
      } else {
          IF (nels > 0 && err != NC_ECHAR)
            error("wrong type: status = %d", err);
      }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_var_float(void)
{
    int ncid;
    int i;
    int j;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nok = 0;      /* count of valid comparisons */
    size_t index[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    float value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_FLOAT == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        err = nc_get_var_float(BAD_ID, i, value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_var_float(ncid, BAD_VARID, value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);

      nels = 1;
      for (j = 0; j < var_rank[i]; j++) {
          nels *= var_shape[i][j];
      }
      allInExtRange = allInIntRange = 1;
      for (j = 0; j < nels; j++) {
          err = toMixedBase(j, var_rank[i], var_shape[i], index);
          IF (err)
            error("error in toMixedBase 1");
          expect[j] = hash4(var_type[i], var_rank[i], index, NCT_FLOAT);
          if (inRange3(expect[j],var_type[i], NCT_FLOAT)) {
            allInIntRange = allInIntRange && expect[j] >= float_min
                      && expect[j] <= float_max;
          } else {
            allInExtRange = 0;
          }
      }
      err = nc_get_var_float(ncid, i, value);
      if (canConvert) {
          if (allInExtRange) {
            if (allInIntRange) {
                IF (err)
                  error("%s", nc_strerror(err));
            } else {
                IF (err != NC_ERANGE)
                  error("Range error: status = %d", err);
            }
          } else {
            IF (err != 0 && err != NC_ERANGE)
                error("OK or Range error: status = %d", err);
          }
          for (j = 0; j < nels; j++) {
            if (inRange3(expect[j],var_type[i],NCT_FLOAT)
                  && expect[j] >= float_min && expect[j] <= float_max) {
                IF (!equal(value[j],expect[j],var_type[i],NCT_FLOAT)){
                  error("value read not that expected");
                  if (verbose) {
                      error("\n");
                      error("varid: %d, ", i);
                      error("var_name: %s, ", var_name[i]);
                      error("element number: %d ", j);
                      error("expect: %g", expect[j]);
                      error("got: %g", (double) value[j]);
                  }
                } else {
                  nok++;
                }
            }
          }
      } else {
          IF (nels > 0 && err != NC_ECHAR)
            error("wrong type: status = %d", err);
      }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_var_double(void)
{
    int ncid;
    int i;
    int j;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nok = 0;      /* count of valid comparisons */
    size_t index[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    double value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_DOUBLE == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        err = nc_get_var_double(BAD_ID, i, value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_var_double(ncid, BAD_VARID, value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);

      nels = 1;
      for (j = 0; j < var_rank[i]; j++) {
          nels *= var_shape[i][j];
      }
      allInExtRange = allInIntRange = 1;
      for (j = 0; j < nels; j++) {
          err = toMixedBase(j, var_rank[i], var_shape[i], index);
          IF (err)
            error("error in toMixedBase 1");
          expect[j] = hash4(var_type[i], var_rank[i], index, NCT_DOUBLE);
          if (inRange3(expect[j],var_type[i], NCT_DOUBLE)) {
            allInIntRange = allInIntRange && expect[j] >= double_min
                      && expect[j] <= double_max;
          } else {
            allInExtRange = 0;
          }
      }
      err = nc_get_var_double(ncid, i, value);
      if (canConvert) {
          if (allInExtRange) {
            if (allInIntRange) {
                IF (err)
                  error("%s", nc_strerror(err));
            } else {
                IF (err != NC_ERANGE)
                  error("Range error: status = %d", err);
            }
          } else {
            IF (err != 0 && err != NC_ERANGE)
                error("OK or Range error: status = %d", err);
          }
          for (j = 0; j < nels; j++) {
            if (inRange3(expect[j],var_type[i],NCT_DOUBLE)
                  && expect[j] >= double_min && expect[j] <= double_max) {
                IF (!equal(value[j],expect[j],var_type[i],NCT_DOUBLE)){
                  error("value read not that expected");
                  if (verbose) {
                      error("\n");
                      error("varid: %d, ", i);
                      error("var_name: %s, ", var_name[i]);
                      error("element number: %d ", j);
                      error("expect: %g", expect[j]);
                      error("got: %g", (double) value[j]);
                  }
                } else {
                  nok++;
                }
            }
          }
      } else {
          IF (nels > 0 && err != NC_ECHAR)
            error("wrong type: status = %d", err);
      }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}




void
test_nc_get_vara_text(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t mid[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    text value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_TEXT == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
      for (j = 0; j < var_rank[i]; j++) {
          start[j] = 0;
          edge[j] = 1;
      }
        err = nc_get_vara_text(BAD_ID, i, start, edge, value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_vara_text(ncid, BAD_VARID, start, edge, value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);
      for (j = 0; j < var_rank[i]; j++) {
          start[j] = var_shape[i][j];
          err = nc_get_vara_text(ncid, i, start, edge, value);
            IF (canConvert && err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
          start[j] = 0;
          edge[j] = var_shape[i][j] + 1;
          err = nc_get_vara_text(ncid, i, start, edge, value);
            IF (canConvert && err != NC_EEDGE)
            error("bad edge: status = %d", err);
          edge[j] = 1;
      }
            /* Check non-scalars for correct error returned even when */
            /* there is nothing to get (edge[j]==0) */
      if(var_rank[i] > 0) {
          for (j = 0; j < var_rank[i]; j++) {
            edge[j] = 0;
          }
          err = nc_get_vara_text(BAD_ID, i, start, edge, value);
          IF (err != NC_EBADID) 
            error("bad ncid: status = %d", err);
          err = nc_get_vara_text(ncid, BAD_VARID, start, edge, value);
          IF (err != NC_ENOTVAR) 
            error("bad var id: status = %d", err);
          for (j = 0; j < var_rank[i]; j++) {
            if (var_dimid[i][j] > 0) {          /* skip record dim */
                start[j] = var_shape[i][j];
                err = nc_get_vara_text(ncid, i, start, edge, value);
                IF (canConvert && err != NC_EINVALCOORDS)
                  error("bad start: status = %d", err);
                start[j] = 0;
            }
          }
          err = nc_get_vara_text(ncid, i, start, edge, value);
          if (canConvert) {
            IF (err) 
                error("%s", nc_strerror(err));
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
          for (j = 0; j < var_rank[i]; j++) {
            edge[j] = 1;
          }
      }            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
        for (k = 0; k < nslabs; k++) {
            nels = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                nels *= edge[j];
            }
          allInExtRange = allInIntRange = 1;
            for (j = 0; j < nels; j++) {
                err = toMixedBase(j, var_rank[i], edge, index);
                IF (err)
                    error("error in toMixedBase 1");
                for (d = 0; d < var_rank[i]; d++)
                    index[d] += start[d];
                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_TEXT);
            if (inRange3(expect[j],var_type[i], NCT_TEXT)) {
                allInIntRange = allInIntRange && expect[j] >= text_min
                        && expect[j] <= text_max;
            } else {
                allInExtRange = 0;
            }
          }
            if (var_rank[i] == 0 && i%2)
            err = nc_get_vara_text(ncid, i, NULL, NULL, value);
          else
            err = nc_get_vara_text(ncid, i, start, edge, value);
            if (canConvert) {
            if (allInExtRange) {
                if (allInIntRange) {
                  IF (err)
                      error("%s", nc_strerror(err));
                } else {
                  IF (err != NC_ERANGE)
                      error("Range error: status = %d", err);
                }
            } else {
                IF (err != 0 && err != NC_ERANGE)
                  error("OK or Range error: status = %d", err);
            }
            for (j = 0; j < nels; j++) {
                if (inRange3(expect[j],var_type[i],NCT_TEXT)
                      && expect[j] >= text_min && expect[j] <= text_max) {
                  IF (!equal(value[j],expect[j],var_type[i],NCT_TEXT)){
                      error("value read not that expected");
                      if (verbose) {
                        error("\n");
                        error("varid: %d, ", i);
                        error("var_name: %s, ", var_name[i]);
                        error("element number: %d ", j);
                        error("expect: %g", expect[j]);
                        error("got: %g", (double) value[j]);
                      }
                  } else {
                      nok++;
                  }
                }
            }
            } else {
                IF (nels > 0 && err != NC_ECHAR)
                    error("wrong type: status = %d", err);
            }
        }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_vara_uchar(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t mid[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    uchar value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_UCHAR == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
      for (j = 0; j < var_rank[i]; j++) {
          start[j] = 0;
          edge[j] = 1;
      }
        err = nc_get_vara_uchar(BAD_ID, i, start, edge, value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_vara_uchar(ncid, BAD_VARID, start, edge, value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);
      for (j = 0; j < var_rank[i]; j++) {
          start[j] = var_shape[i][j];
          err = nc_get_vara_uchar(ncid, i, start, edge, value);
            IF (canConvert && err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
          start[j] = 0;
          edge[j] = var_shape[i][j] + 1;
          err = nc_get_vara_uchar(ncid, i, start, edge, value);
            IF (canConvert && err != NC_EEDGE)
            error("bad edge: status = %d", err);
          edge[j] = 1;
      }
            /* Check non-scalars for correct error returned even when */
            /* there is nothing to get (edge[j]==0) */
      if(var_rank[i] > 0) {
          for (j = 0; j < var_rank[i]; j++) {
            edge[j] = 0;
          }
          err = nc_get_vara_uchar(BAD_ID, i, start, edge, value);
          IF (err != NC_EBADID) 
            error("bad ncid: status = %d", err);
          err = nc_get_vara_uchar(ncid, BAD_VARID, start, edge, value);
          IF (err != NC_ENOTVAR) 
            error("bad var id: status = %d", err);
          for (j = 0; j < var_rank[i]; j++) {
            if (var_dimid[i][j] > 0) {          /* skip record dim */
                start[j] = var_shape[i][j];
                err = nc_get_vara_uchar(ncid, i, start, edge, value);
                IF (canConvert && err != NC_EINVALCOORDS)
                  error("bad start: status = %d", err);
                start[j] = 0;
            }
          }
          err = nc_get_vara_uchar(ncid, i, start, edge, value);
          if (canConvert) {
            IF (err) 
                error("%s", nc_strerror(err));
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
          for (j = 0; j < var_rank[i]; j++) {
            edge[j] = 1;
          }
      }            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
        for (k = 0; k < nslabs; k++) {
            nels = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                nels *= edge[j];
            }
          allInExtRange = allInIntRange = 1;
            for (j = 0; j < nels; j++) {
                err = toMixedBase(j, var_rank[i], edge, index);
                IF (err)
                    error("error in toMixedBase 1");
                for (d = 0; d < var_rank[i]; d++)
                    index[d] += start[d];
                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_UCHAR);
            if (inRange3(expect[j],var_type[i], NCT_UCHAR)) {
                allInIntRange = allInIntRange && expect[j] >= uchar_min
                        && expect[j] <= uchar_max;
            } else {
                allInExtRange = 0;
            }
          }
            if (var_rank[i] == 0 && i%2)
            err = nc_get_vara_uchar(ncid, i, NULL, NULL, value);
          else
            err = nc_get_vara_uchar(ncid, i, start, edge, value);
            if (canConvert) {
            if (allInExtRange) {
                if (allInIntRange) {
                  IF (err)
                      error("%s", nc_strerror(err));
                } else {
                  IF (err != NC_ERANGE)
                      error("Range error: status = %d", err);
                }
            } else {
                IF (err != 0 && err != NC_ERANGE)
                  error("OK or Range error: status = %d", err);
            }
            for (j = 0; j < nels; j++) {
                if (inRange3(expect[j],var_type[i],NCT_UCHAR)
                      && expect[j] >= uchar_min && expect[j] <= uchar_max) {
                  IF (!equal(value[j],expect[j],var_type[i],NCT_UCHAR)){
                      error("value read not that expected");
                      if (verbose) {
                        error("\n");
                        error("varid: %d, ", i);
                        error("var_name: %s, ", var_name[i]);
                        error("element number: %d ", j);
                        error("expect: %g", expect[j]);
                        error("got: %g", (double) value[j]);
                      }
                  } else {
                      nok++;
                  }
                }
            }
            } else {
                IF (nels > 0 && err != NC_ECHAR)
                    error("wrong type: status = %d", err);
            }
        }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_vara_schar(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t mid[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    schar value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_SCHAR == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
      for (j = 0; j < var_rank[i]; j++) {
          start[j] = 0;
          edge[j] = 1;
      }
        err = nc_get_vara_schar(BAD_ID, i, start, edge, value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_vara_schar(ncid, BAD_VARID, start, edge, value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);
      for (j = 0; j < var_rank[i]; j++) {
          start[j] = var_shape[i][j];
          err = nc_get_vara_schar(ncid, i, start, edge, value);
            IF (canConvert && err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
          start[j] = 0;
          edge[j] = var_shape[i][j] + 1;
          err = nc_get_vara_schar(ncid, i, start, edge, value);
            IF (canConvert && err != NC_EEDGE)
            error("bad edge: status = %d", err);
          edge[j] = 1;
      }
            /* Check non-scalars for correct error returned even when */
            /* there is nothing to get (edge[j]==0) */
      if(var_rank[i] > 0) {
          for (j = 0; j < var_rank[i]; j++) {
            edge[j] = 0;
          }
          err = nc_get_vara_schar(BAD_ID, i, start, edge, value);
          IF (err != NC_EBADID) 
            error("bad ncid: status = %d", err);
          err = nc_get_vara_schar(ncid, BAD_VARID, start, edge, value);
          IF (err != NC_ENOTVAR) 
            error("bad var id: status = %d", err);
          for (j = 0; j < var_rank[i]; j++) {
            if (var_dimid[i][j] > 0) {          /* skip record dim */
                start[j] = var_shape[i][j];
                err = nc_get_vara_schar(ncid, i, start, edge, value);
                IF (canConvert && err != NC_EINVALCOORDS)
                  error("bad start: status = %d", err);
                start[j] = 0;
            }
          }
          err = nc_get_vara_schar(ncid, i, start, edge, value);
          if (canConvert) {
            IF (err) 
                error("%s", nc_strerror(err));
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
          for (j = 0; j < var_rank[i]; j++) {
            edge[j] = 1;
          }
      }            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
        for (k = 0; k < nslabs; k++) {
            nels = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                nels *= edge[j];
            }
          allInExtRange = allInIntRange = 1;
            for (j = 0; j < nels; j++) {
                err = toMixedBase(j, var_rank[i], edge, index);
                IF (err)
                    error("error in toMixedBase 1");
                for (d = 0; d < var_rank[i]; d++)
                    index[d] += start[d];
                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_SCHAR);
            if (inRange3(expect[j],var_type[i], NCT_SCHAR)) {
                allInIntRange = allInIntRange && expect[j] >= schar_min
                        && expect[j] <= schar_max;
            } else {
                allInExtRange = 0;
            }
          }
            if (var_rank[i] == 0 && i%2)
            err = nc_get_vara_schar(ncid, i, NULL, NULL, value);
          else
            err = nc_get_vara_schar(ncid, i, start, edge, value);
            if (canConvert) {
            if (allInExtRange) {
                if (allInIntRange) {
                  IF (err)
                      error("%s", nc_strerror(err));
                } else {
                  IF (err != NC_ERANGE)
                      error("Range error: status = %d", err);
                }
            } else {
                IF (err != 0 && err != NC_ERANGE)
                  error("OK or Range error: status = %d", err);
            }
            for (j = 0; j < nels; j++) {
                if (inRange3(expect[j],var_type[i],NCT_SCHAR)
                      && expect[j] >= schar_min && expect[j] <= schar_max) {
                  IF (!equal(value[j],expect[j],var_type[i],NCT_SCHAR)){
                      error("value read not that expected");
                      if (verbose) {
                        error("\n");
                        error("varid: %d, ", i);
                        error("var_name: %s, ", var_name[i]);
                        error("element number: %d ", j);
                        error("expect: %g", expect[j]);
                        error("got: %g", (double) value[j]);
                      }
                  } else {
                      nok++;
                  }
                }
            }
            } else {
                IF (nels > 0 && err != NC_ECHAR)
                    error("wrong type: status = %d", err);
            }
        }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_vara_short(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t mid[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    short value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_SHORT == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
      for (j = 0; j < var_rank[i]; j++) {
          start[j] = 0;
          edge[j] = 1;
      }
        err = nc_get_vara_short(BAD_ID, i, start, edge, value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_vara_short(ncid, BAD_VARID, start, edge, value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);
      for (j = 0; j < var_rank[i]; j++) {
          start[j] = var_shape[i][j];
          err = nc_get_vara_short(ncid, i, start, edge, value);
            IF (canConvert && err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
          start[j] = 0;
          edge[j] = var_shape[i][j] + 1;
          err = nc_get_vara_short(ncid, i, start, edge, value);
            IF (canConvert && err != NC_EEDGE)
            error("bad edge: status = %d", err);
          edge[j] = 1;
      }
            /* Check non-scalars for correct error returned even when */
            /* there is nothing to get (edge[j]==0) */
      if(var_rank[i] > 0) {
          for (j = 0; j < var_rank[i]; j++) {
            edge[j] = 0;
          }
          err = nc_get_vara_short(BAD_ID, i, start, edge, value);
          IF (err != NC_EBADID) 
            error("bad ncid: status = %d", err);
          err = nc_get_vara_short(ncid, BAD_VARID, start, edge, value);
          IF (err != NC_ENOTVAR) 
            error("bad var id: status = %d", err);
          for (j = 0; j < var_rank[i]; j++) {
            if (var_dimid[i][j] > 0) {          /* skip record dim */
                start[j] = var_shape[i][j];
                err = nc_get_vara_short(ncid, i, start, edge, value);
                IF (canConvert && err != NC_EINVALCOORDS)
                  error("bad start: status = %d", err);
                start[j] = 0;
            }
          }
          err = nc_get_vara_short(ncid, i, start, edge, value);
          if (canConvert) {
            IF (err) 
                error("%s", nc_strerror(err));
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
          for (j = 0; j < var_rank[i]; j++) {
            edge[j] = 1;
          }
      }            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
        for (k = 0; k < nslabs; k++) {
            nels = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                nels *= edge[j];
            }
          allInExtRange = allInIntRange = 1;
            for (j = 0; j < nels; j++) {
                err = toMixedBase(j, var_rank[i], edge, index);
                IF (err)
                    error("error in toMixedBase 1");
                for (d = 0; d < var_rank[i]; d++)
                    index[d] += start[d];
                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_SHORT);
            if (inRange3(expect[j],var_type[i], NCT_SHORT)) {
                allInIntRange = allInIntRange && expect[j] >= short_min
                        && expect[j] <= short_max;
            } else {
                allInExtRange = 0;
            }
          }
            if (var_rank[i] == 0 && i%2)
            err = nc_get_vara_short(ncid, i, NULL, NULL, value);
          else
            err = nc_get_vara_short(ncid, i, start, edge, value);
            if (canConvert) {
            if (allInExtRange) {
                if (allInIntRange) {
                  IF (err)
                      error("%s", nc_strerror(err));
                } else {
                  IF (err != NC_ERANGE)
                      error("Range error: status = %d", err);
                }
            } else {
                IF (err != 0 && err != NC_ERANGE)
                  error("OK or Range error: status = %d", err);
            }
            for (j = 0; j < nels; j++) {
                if (inRange3(expect[j],var_type[i],NCT_SHORT)
                      && expect[j] >= short_min && expect[j] <= short_max) {
                  IF (!equal(value[j],expect[j],var_type[i],NCT_SHORT)){
                      error("value read not that expected");
                      if (verbose) {
                        error("\n");
                        error("varid: %d, ", i);
                        error("var_name: %s, ", var_name[i]);
                        error("element number: %d ", j);
                        error("expect: %g", expect[j]);
                        error("got: %g", (double) value[j]);
                      }
                  } else {
                      nok++;
                  }
                }
            }
            } else {
                IF (nels > 0 && err != NC_ECHAR)
                    error("wrong type: status = %d", err);
            }
        }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_vara_int(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t mid[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    int value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_INT == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
      for (j = 0; j < var_rank[i]; j++) {
          start[j] = 0;
          edge[j] = 1;
      }
        err = nc_get_vara_int(BAD_ID, i, start, edge, value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_vara_int(ncid, BAD_VARID, start, edge, value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);
      for (j = 0; j < var_rank[i]; j++) {
          start[j] = var_shape[i][j];
          err = nc_get_vara_int(ncid, i, start, edge, value);
            IF (canConvert && err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
          start[j] = 0;
          edge[j] = var_shape[i][j] + 1;
          err = nc_get_vara_int(ncid, i, start, edge, value);
            IF (canConvert && err != NC_EEDGE)
            error("bad edge: status = %d", err);
          edge[j] = 1;
      }
            /* Check non-scalars for correct error returned even when */
            /* there is nothing to get (edge[j]==0) */
      if(var_rank[i] > 0) {
          for (j = 0; j < var_rank[i]; j++) {
            edge[j] = 0;
          }
          err = nc_get_vara_int(BAD_ID, i, start, edge, value);
          IF (err != NC_EBADID) 
            error("bad ncid: status = %d", err);
          err = nc_get_vara_int(ncid, BAD_VARID, start, edge, value);
          IF (err != NC_ENOTVAR) 
            error("bad var id: status = %d", err);
          for (j = 0; j < var_rank[i]; j++) {
            if (var_dimid[i][j] > 0) {          /* skip record dim */
                start[j] = var_shape[i][j];
                err = nc_get_vara_int(ncid, i, start, edge, value);
                IF (canConvert && err != NC_EINVALCOORDS)
                  error("bad start: status = %d", err);
                start[j] = 0;
            }
          }
          err = nc_get_vara_int(ncid, i, start, edge, value);
          if (canConvert) {
            IF (err) 
                error("%s", nc_strerror(err));
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
          for (j = 0; j < var_rank[i]; j++) {
            edge[j] = 1;
          }
      }            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
        for (k = 0; k < nslabs; k++) {
            nels = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                nels *= edge[j];
            }
          allInExtRange = allInIntRange = 1;
            for (j = 0; j < nels; j++) {
                err = toMixedBase(j, var_rank[i], edge, index);
                IF (err)
                    error("error in toMixedBase 1");
                for (d = 0; d < var_rank[i]; d++)
                    index[d] += start[d];
                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_INT);
            if (inRange3(expect[j],var_type[i], NCT_INT)) {
                allInIntRange = allInIntRange && expect[j] >= int_min
                        && expect[j] <= int_max;
            } else {
                allInExtRange = 0;
            }
          }
            if (var_rank[i] == 0 && i%2)
            err = nc_get_vara_int(ncid, i, NULL, NULL, value);
          else
            err = nc_get_vara_int(ncid, i, start, edge, value);
            if (canConvert) {
            if (allInExtRange) {
                if (allInIntRange) {
                  IF (err)
                      error("%s", nc_strerror(err));
                } else {
                  IF (err != NC_ERANGE)
                      error("Range error: status = %d", err);
                }
            } else {
                IF (err != 0 && err != NC_ERANGE)
                  error("OK or Range error: status = %d", err);
            }
            for (j = 0; j < nels; j++) {
                if (inRange3(expect[j],var_type[i],NCT_INT)
                      && expect[j] >= int_min && expect[j] <= int_max) {
                  IF (!equal(value[j],expect[j],var_type[i],NCT_INT)){
                      error("value read not that expected");
                      if (verbose) {
                        error("\n");
                        error("varid: %d, ", i);
                        error("var_name: %s, ", var_name[i]);
                        error("element number: %d ", j);
                        error("expect: %g", expect[j]);
                        error("got: %g", (double) value[j]);
                      }
                  } else {
                      nok++;
                  }
                }
            }
            } else {
                IF (nels > 0 && err != NC_ECHAR)
                    error("wrong type: status = %d", err);
            }
        }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_vara_long(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t mid[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    long value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_LONG == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
      for (j = 0; j < var_rank[i]; j++) {
          start[j] = 0;
          edge[j] = 1;
      }
        err = nc_get_vara_long(BAD_ID, i, start, edge, value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_vara_long(ncid, BAD_VARID, start, edge, value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);
      for (j = 0; j < var_rank[i]; j++) {
          start[j] = var_shape[i][j];
          err = nc_get_vara_long(ncid, i, start, edge, value);
            IF (canConvert && err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
          start[j] = 0;
          edge[j] = var_shape[i][j] + 1;
          err = nc_get_vara_long(ncid, i, start, edge, value);
            IF (canConvert && err != NC_EEDGE)
            error("bad edge: status = %d", err);
          edge[j] = 1;
      }
            /* Check non-scalars for correct error returned even when */
            /* there is nothing to get (edge[j]==0) */
      if(var_rank[i] > 0) {
          for (j = 0; j < var_rank[i]; j++) {
            edge[j] = 0;
          }
          err = nc_get_vara_long(BAD_ID, i, start, edge, value);
          IF (err != NC_EBADID) 
            error("bad ncid: status = %d", err);
          err = nc_get_vara_long(ncid, BAD_VARID, start, edge, value);
          IF (err != NC_ENOTVAR) 
            error("bad var id: status = %d", err);
          for (j = 0; j < var_rank[i]; j++) {
            if (var_dimid[i][j] > 0) {          /* skip record dim */
                start[j] = var_shape[i][j];
                err = nc_get_vara_long(ncid, i, start, edge, value);
                IF (canConvert && err != NC_EINVALCOORDS)
                  error("bad start: status = %d", err);
                start[j] = 0;
            }
          }
          err = nc_get_vara_long(ncid, i, start, edge, value);
          if (canConvert) {
            IF (err) 
                error("%s", nc_strerror(err));
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
          for (j = 0; j < var_rank[i]; j++) {
            edge[j] = 1;
          }
      }            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
        for (k = 0; k < nslabs; k++) {
            nels = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                nels *= edge[j];
            }
          allInExtRange = allInIntRange = 1;
            for (j = 0; j < nels; j++) {
                err = toMixedBase(j, var_rank[i], edge, index);
                IF (err)
                    error("error in toMixedBase 1");
                for (d = 0; d < var_rank[i]; d++)
                    index[d] += start[d];
                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_LONG);
            if (inRange3(expect[j],var_type[i], NCT_LONG)) {
                allInIntRange = allInIntRange && expect[j] >= long_min
                        && expect[j] <= long_max;
            } else {
                allInExtRange = 0;
            }
          }
            if (var_rank[i] == 0 && i%2)
            err = nc_get_vara_long(ncid, i, NULL, NULL, value);
          else
            err = nc_get_vara_long(ncid, i, start, edge, value);
            if (canConvert) {
            if (allInExtRange) {
                if (allInIntRange) {
                  IF (err)
                      error("%s", nc_strerror(err));
                } else {
                  IF (err != NC_ERANGE)
                      error("Range error: status = %d", err);
                }
            } else {
                IF (err != 0 && err != NC_ERANGE)
                  error("OK or Range error: status = %d", err);
            }
            for (j = 0; j < nels; j++) {
                if (inRange3(expect[j],var_type[i],NCT_LONG)
                      && expect[j] >= long_min && expect[j] <= long_max) {
                  IF (!equal(value[j],expect[j],var_type[i],NCT_LONG)){
                      error("value read not that expected");
                      if (verbose) {
                        error("\n");
                        error("varid: %d, ", i);
                        error("var_name: %s, ", var_name[i]);
                        error("element number: %d ", j);
                        error("expect: %g", expect[j]);
                        error("got: %g", (double) value[j]);
                      }
                  } else {
                      nok++;
                  }
                }
            }
            } else {
                IF (nels > 0 && err != NC_ECHAR)
                    error("wrong type: status = %d", err);
            }
        }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_vara_float(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t mid[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    float value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_FLOAT == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
      for (j = 0; j < var_rank[i]; j++) {
          start[j] = 0;
          edge[j] = 1;
      }
        err = nc_get_vara_float(BAD_ID, i, start, edge, value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_vara_float(ncid, BAD_VARID, start, edge, value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);
      for (j = 0; j < var_rank[i]; j++) {
          start[j] = var_shape[i][j];
          err = nc_get_vara_float(ncid, i, start, edge, value);
            IF (canConvert && err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
          start[j] = 0;
          edge[j] = var_shape[i][j] + 1;
          err = nc_get_vara_float(ncid, i, start, edge, value);
            IF (canConvert && err != NC_EEDGE)
            error("bad edge: status = %d", err);
          edge[j] = 1;
      }
            /* Check non-scalars for correct error returned even when */
            /* there is nothing to get (edge[j]==0) */
      if(var_rank[i] > 0) {
          for (j = 0; j < var_rank[i]; j++) {
            edge[j] = 0;
          }
          err = nc_get_vara_float(BAD_ID, i, start, edge, value);
          IF (err != NC_EBADID) 
            error("bad ncid: status = %d", err);
          err = nc_get_vara_float(ncid, BAD_VARID, start, edge, value);
          IF (err != NC_ENOTVAR) 
            error("bad var id: status = %d", err);
          for (j = 0; j < var_rank[i]; j++) {
            if (var_dimid[i][j] > 0) {          /* skip record dim */
                start[j] = var_shape[i][j];
                err = nc_get_vara_float(ncid, i, start, edge, value);
                IF (canConvert && err != NC_EINVALCOORDS)
                  error("bad start: status = %d", err);
                start[j] = 0;
            }
          }
          err = nc_get_vara_float(ncid, i, start, edge, value);
          if (canConvert) {
            IF (err) 
                error("%s", nc_strerror(err));
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
          for (j = 0; j < var_rank[i]; j++) {
            edge[j] = 1;
          }
      }            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
        for (k = 0; k < nslabs; k++) {
            nels = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                nels *= edge[j];
            }
          allInExtRange = allInIntRange = 1;
            for (j = 0; j < nels; j++) {
                err = toMixedBase(j, var_rank[i], edge, index);
                IF (err)
                    error("error in toMixedBase 1");
                for (d = 0; d < var_rank[i]; d++)
                    index[d] += start[d];
                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_FLOAT);
            if (inRange3(expect[j],var_type[i], NCT_FLOAT)) {
                allInIntRange = allInIntRange && expect[j] >= float_min
                        && expect[j] <= float_max;
            } else {
                allInExtRange = 0;
            }
          }
            if (var_rank[i] == 0 && i%2)
            err = nc_get_vara_float(ncid, i, NULL, NULL, value);
          else
            err = nc_get_vara_float(ncid, i, start, edge, value);
            if (canConvert) {
            if (allInExtRange) {
                if (allInIntRange) {
                  IF (err)
                      error("%s", nc_strerror(err));
                } else {
                  IF (err != NC_ERANGE)
                      error("Range error: status = %d", err);
                }
            } else {
                IF (err != 0 && err != NC_ERANGE)
                  error("OK or Range error: status = %d", err);
            }
            for (j = 0; j < nels; j++) {
                if (inRange3(expect[j],var_type[i],NCT_FLOAT)
                      && expect[j] >= float_min && expect[j] <= float_max) {
                  IF (!equal(value[j],expect[j],var_type[i],NCT_FLOAT)){
                      error("value read not that expected");
                      if (verbose) {
                        error("\n");
                        error("varid: %d, ", i);
                        error("var_name: %s, ", var_name[i]);
                        error("element number: %d ", j);
                        error("expect: %g", expect[j]);
                        error("got: %g", (double) value[j]);
                      }
                  } else {
                      nok++;
                  }
                }
            }
            } else {
                IF (nels > 0 && err != NC_ECHAR)
                    error("wrong type: status = %d", err);
            }
        }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_vara_double(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t mid[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    double value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
      error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_DOUBLE == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
      for (j = 0; j < var_rank[i]; j++) {
          start[j] = 0;
          edge[j] = 1;
      }
        err = nc_get_vara_double(BAD_ID, i, start, edge, value);
        IF (err != NC_EBADID)
          error("bad ncid: status = %d", err);
        err = nc_get_vara_double(ncid, BAD_VARID, start, edge, value);
        IF (err != NC_ENOTVAR)
          error("bad var id: status = %d", err);
      for (j = 0; j < var_rank[i]; j++) {
          start[j] = var_shape[i][j];
          err = nc_get_vara_double(ncid, i, start, edge, value);
            IF (canConvert && err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
          start[j] = 0;
          edge[j] = var_shape[i][j] + 1;
          err = nc_get_vara_double(ncid, i, start, edge, value);
            IF (canConvert && err != NC_EEDGE)
            error("bad edge: status = %d", err);
          edge[j] = 1;
      }
            /* Check non-scalars for correct error returned even when */
            /* there is nothing to get (edge[j]==0) */
      if(var_rank[i] > 0) {
          for (j = 0; j < var_rank[i]; j++) {
            edge[j] = 0;
          }
          err = nc_get_vara_double(BAD_ID, i, start, edge, value);
          IF (err != NC_EBADID) 
            error("bad ncid: status = %d", err);
          err = nc_get_vara_double(ncid, BAD_VARID, start, edge, value);
          IF (err != NC_ENOTVAR) 
            error("bad var id: status = %d", err);
          for (j = 0; j < var_rank[i]; j++) {
            if (var_dimid[i][j] > 0) {          /* skip record dim */
                start[j] = var_shape[i][j];
                err = nc_get_vara_double(ncid, i, start, edge, value);
                IF (canConvert && err != NC_EINVALCOORDS)
                  error("bad start: status = %d", err);
                start[j] = 0;
            }
          }
          err = nc_get_vara_double(ncid, i, start, edge, value);
          if (canConvert) {
            IF (err) 
                error("%s", nc_strerror(err));
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
          for (j = 0; j < var_rank[i]; j++) {
            edge[j] = 1;
          }
      }            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
        for (k = 0; k < nslabs; k++) {
            nels = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                nels *= edge[j];
            }
          allInExtRange = allInIntRange = 1;
            for (j = 0; j < nels; j++) {
                err = toMixedBase(j, var_rank[i], edge, index);
                IF (err)
                    error("error in toMixedBase 1");
                for (d = 0; d < var_rank[i]; d++)
                    index[d] += start[d];
                expect[j] = hash4(var_type[i], var_rank[i], index, NCT_DOUBLE);
            if (inRange3(expect[j],var_type[i], NCT_DOUBLE)) {
                allInIntRange = allInIntRange && expect[j] >= double_min
                        && expect[j] <= double_max;
            } else {
                allInExtRange = 0;
            }
          }
            if (var_rank[i] == 0 && i%2)
            err = nc_get_vara_double(ncid, i, NULL, NULL, value);
          else
            err = nc_get_vara_double(ncid, i, start, edge, value);
            if (canConvert) {
            if (allInExtRange) {
                if (allInIntRange) {
                  IF (err)
                      error("%s", nc_strerror(err));
                } else {
                  IF (err != NC_ERANGE)
                      error("Range error: status = %d", err);
                }
            } else {
                IF (err != 0 && err != NC_ERANGE)
                  error("OK or Range error: status = %d", err);
            }
            for (j = 0; j < nels; j++) {
                if (inRange3(expect[j],var_type[i],NCT_DOUBLE)
                      && expect[j] >= double_min && expect[j] <= double_max) {
                  IF (!equal(value[j],expect[j],var_type[i],NCT_DOUBLE)){
                      error("value read not that expected");
                      if (verbose) {
                        error("\n");
                        error("varid: %d, ", i);
                        error("var_name: %s, ", var_name[i]);
                        error("element number: %d ", j);
                        error("expect: %g", expect[j]);
                        error("got: %g", (double) value[j]);
                      }
                  } else {
                      nok++;
                  }
                }
            }
            } else {
                IF (nels > 0 && err != NC_ECHAR)
                    error("wrong type: status = %d", err);
            }
        }
    }
    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}




void
test_nc_get_vars_text(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int m;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nstarts;        /* number of different starts */
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t index2[MAX_RANK];
    size_t mid[MAX_RANK];
    size_t count[MAX_RANK];
    size_t sstride[MAX_RANK];
    ptrdiff_t stride[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    text value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
        error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_TEXT == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = 0;
            edge[j] = 1;
            stride[j] = 1;
        }
        err = nc_get_vars_text(BAD_ID, i, start, edge, stride, value);
        IF (err != NC_EBADID)
            error("bad ncid: status = %d", err);
        err = nc_get_vars_text(ncid, BAD_VARID, start, edge, stride, value);
        IF (err != NC_ENOTVAR)
            error("bad var id: status = %d", err);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = var_shape[i][j];
            err = nc_get_vars_text(ncid, i, start, edge, stride, value);
        if(!canConvert) {
            IF (err != NC_ECHAR)
                      error("conversion: status = %d", err);
        } else {
            IF (err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
            start[j] = 0;
            edge[j] = var_shape[i][j] + 1;
            err = nc_get_vars_text(ncid, i, start, edge, stride, value);
            IF (err != NC_EEDGE)
                error("bad edge: status = %d", err);
            edge[j] = 1;
            stride[j] = 0;
            err = nc_get_vars_text(ncid, i, start, edge, stride, value);
            IF (err != NC_ESTRIDE)
                error("bad stride: status = %d", err);
            stride[j] = 1;
        }
        }
            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
            /* choose random stride from 1 to edge */
        for (k = 0; k < nslabs; k++) {
            nstarts = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
                nstarts *= stride[j];
            }
            for (m = 0; m < nstarts; m++) {
                err = toMixedBase(m, var_rank[i], sstride, index);
                IF (err)
                    error("error in toMixedBase");
                nels = 1;
                for (j = 0; j < var_rank[i]; j++) {
                    count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
                    nels *= count[j];
                    index[j] += start[j];
                }
                        /* Random choice of forward or backward */
/* TODO
                if ( roll(2) ) {
                    for (j = 0; j < var_rank[i]; j++) {
                        index[j] += (count[j] - 1) * stride[j];
                        stride[j] = -stride[j];
                    }
                }
*/
            allInExtRange = allInIntRange = 1;
            for (j = 0; j < nels; j++) {
                err = toMixedBase(j, var_rank[i], count, index2);
                IF (err)
                  error("error in toMixedBase 1");
                for (d = 0; d < var_rank[i]; d++)
                  index2[d] = index[d] + index2[d] * stride[d];
                expect[j] = hash4(var_type[i], var_rank[i], index2, 
                  NCT_TEXT);
                if (inRange3(expect[j],var_type[i],NCT_TEXT)) {
                  allInIntRange = allInIntRange && expect[j] >= text_min
                      && expect[j] <= text_max;
                } else {
                  allInExtRange = 0;
                }
            }
                if (var_rank[i] == 0 && i%2 )
                    err = nc_get_vars_text(ncid, i, NULL, NULL, NULL, value);
                else
                    err = nc_get_vars_text(ncid, i, index, count, stride, value);
            if (canConvert) {
                if (allInExtRange) {
                  if (allInIntRange) {
                      IF (err)
                        error("%s", nc_strerror(err));
                  } else {
                      IF (err != NC_ERANGE)
                        error("Range error: status = %d", err);
                  }
                } else {
                  IF (err != 0 && err != NC_ERANGE)
                      error("OK or Range error: status = %d", err);
                }
                for (j = 0; j < nels; j++) {
                  if (inRange3(expect[j],var_type[i],NCT_TEXT)
                        && expect[j] >= text_min && expect[j] <= text_max) {
                      IF (!equal(value[j],expect[j],var_type[i],
                            NCT_TEXT)){
                        error("value read not that expected");
                        if (verbose) {
                            error("\n");
                            error("varid: %d, ", i);
                            error("var_name: %s, ", var_name[i]);
                            error("element number: %d ", j);
                                    error("expect: %g, ", expect[j]);
                            error("got: %g", (double) value[j]);
                        }
                      } else {
                        nok++;
                      }
                  }
                }
            } else {
                IF (nels > 0 && err != NC_ECHAR)
                  error("wrong type: status = %d", err);
            }
          }
      }

    }
    err = nc_close(ncid);
    IF (err)
        error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_vars_uchar(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int m;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nstarts;        /* number of different starts */
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t index2[MAX_RANK];
    size_t mid[MAX_RANK];
    size_t count[MAX_RANK];
    size_t sstride[MAX_RANK];
    ptrdiff_t stride[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    uchar value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
        error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_UCHAR == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = 0;
            edge[j] = 1;
            stride[j] = 1;
        }
        err = nc_get_vars_uchar(BAD_ID, i, start, edge, stride, value);
        IF (err != NC_EBADID)
            error("bad ncid: status = %d", err);
        err = nc_get_vars_uchar(ncid, BAD_VARID, start, edge, stride, value);
        IF (err != NC_ENOTVAR)
            error("bad var id: status = %d", err);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = var_shape[i][j];
            err = nc_get_vars_uchar(ncid, i, start, edge, stride, value);
        if(!canConvert) {
            IF (err != NC_ECHAR)
                      error("conversion: status = %d", err);
        } else {
            IF (err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
            start[j] = 0;
            edge[j] = var_shape[i][j] + 1;
            err = nc_get_vars_uchar(ncid, i, start, edge, stride, value);
            IF (err != NC_EEDGE)
                error("bad edge: status = %d", err);
            edge[j] = 1;
            stride[j] = 0;
            err = nc_get_vars_uchar(ncid, i, start, edge, stride, value);
            IF (err != NC_ESTRIDE)
                error("bad stride: status = %d", err);
            stride[j] = 1;
        }
        }
            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
            /* choose random stride from 1 to edge */
        for (k = 0; k < nslabs; k++) {
            nstarts = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
                nstarts *= stride[j];
            }
            for (m = 0; m < nstarts; m++) {
                err = toMixedBase(m, var_rank[i], sstride, index);
                IF (err)
                    error("error in toMixedBase");
                nels = 1;
                for (j = 0; j < var_rank[i]; j++) {
                    count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
                    nels *= count[j];
                    index[j] += start[j];
                }
                        /* Random choice of forward or backward */
/* TODO
                if ( roll(2) ) {
                    for (j = 0; j < var_rank[i]; j++) {
                        index[j] += (count[j] - 1) * stride[j];
                        stride[j] = -stride[j];
                    }
                }
*/
            allInExtRange = allInIntRange = 1;
            for (j = 0; j < nels; j++) {
                err = toMixedBase(j, var_rank[i], count, index2);
                IF (err)
                  error("error in toMixedBase 1");
                for (d = 0; d < var_rank[i]; d++)
                  index2[d] = index[d] + index2[d] * stride[d];
                expect[j] = hash4(var_type[i], var_rank[i], index2, 
                  NCT_UCHAR);
                if (inRange3(expect[j],var_type[i],NCT_UCHAR)) {
                  allInIntRange = allInIntRange && expect[j] >= uchar_min
                      && expect[j] <= uchar_max;
                } else {
                  allInExtRange = 0;
                }
            }
                if (var_rank[i] == 0 && i%2 )
                    err = nc_get_vars_uchar(ncid, i, NULL, NULL, NULL, value);
                else
                    err = nc_get_vars_uchar(ncid, i, index, count, stride, value);
            if (canConvert) {
                if (allInExtRange) {
                  if (allInIntRange) {
                      IF (err)
                        error("%s", nc_strerror(err));
                  } else {
                      IF (err != NC_ERANGE)
                        error("Range error: status = %d", err);
                  }
                } else {
                  IF (err != 0 && err != NC_ERANGE)
                      error("OK or Range error: status = %d", err);
                }
                for (j = 0; j < nels; j++) {
                  if (inRange3(expect[j],var_type[i],NCT_UCHAR)
                        && expect[j] >= uchar_min && expect[j] <= uchar_max) {
                      IF (!equal(value[j],expect[j],var_type[i],
                            NCT_UCHAR)){
                        error("value read not that expected");
                        if (verbose) {
                            error("\n");
                            error("varid: %d, ", i);
                            error("var_name: %s, ", var_name[i]);
                            error("element number: %d ", j);
                                    error("expect: %g, ", expect[j]);
                            error("got: %g", (double) value[j]);
                        }
                      } else {
                        nok++;
                      }
                  }
                }
            } else {
                IF (nels > 0 && err != NC_ECHAR)
                  error("wrong type: status = %d", err);
            }
          }
      }

    }
    err = nc_close(ncid);
    IF (err)
        error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_vars_schar(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int m;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nstarts;        /* number of different starts */
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t index2[MAX_RANK];
    size_t mid[MAX_RANK];
    size_t count[MAX_RANK];
    size_t sstride[MAX_RANK];
    ptrdiff_t stride[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    schar value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
        error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_SCHAR == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = 0;
            edge[j] = 1;
            stride[j] = 1;
        }
        err = nc_get_vars_schar(BAD_ID, i, start, edge, stride, value);
        IF (err != NC_EBADID)
            error("bad ncid: status = %d", err);
        err = nc_get_vars_schar(ncid, BAD_VARID, start, edge, stride, value);
        IF (err != NC_ENOTVAR)
            error("bad var id: status = %d", err);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = var_shape[i][j];
            err = nc_get_vars_schar(ncid, i, start, edge, stride, value);
        if(!canConvert) {
            IF (err != NC_ECHAR)
                      error("conversion: status = %d", err);
        } else {
            IF (err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
            start[j] = 0;
            edge[j] = var_shape[i][j] + 1;
            err = nc_get_vars_schar(ncid, i, start, edge, stride, value);
            IF (err != NC_EEDGE)
                error("bad edge: status = %d", err);
            edge[j] = 1;
            stride[j] = 0;
            err = nc_get_vars_schar(ncid, i, start, edge, stride, value);
            IF (err != NC_ESTRIDE)
                error("bad stride: status = %d", err);
            stride[j] = 1;
        }
        }
            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
            /* choose random stride from 1 to edge */
        for (k = 0; k < nslabs; k++) {
            nstarts = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
                nstarts *= stride[j];
            }
            for (m = 0; m < nstarts; m++) {
                err = toMixedBase(m, var_rank[i], sstride, index);
                IF (err)
                    error("error in toMixedBase");
                nels = 1;
                for (j = 0; j < var_rank[i]; j++) {
                    count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
                    nels *= count[j];
                    index[j] += start[j];
                }
                        /* Random choice of forward or backward */
/* TODO
                if ( roll(2) ) {
                    for (j = 0; j < var_rank[i]; j++) {
                        index[j] += (count[j] - 1) * stride[j];
                        stride[j] = -stride[j];
                    }
                }
*/
            allInExtRange = allInIntRange = 1;
            for (j = 0; j < nels; j++) {
                err = toMixedBase(j, var_rank[i], count, index2);
                IF (err)
                  error("error in toMixedBase 1");
                for (d = 0; d < var_rank[i]; d++)
                  index2[d] = index[d] + index2[d] * stride[d];
                expect[j] = hash4(var_type[i], var_rank[i], index2, 
                  NCT_SCHAR);
                if (inRange3(expect[j],var_type[i],NCT_SCHAR)) {
                  allInIntRange = allInIntRange && expect[j] >= schar_min
                      && expect[j] <= schar_max;
                } else {
                  allInExtRange = 0;
                }
            }
                if (var_rank[i] == 0 && i%2 )
                    err = nc_get_vars_schar(ncid, i, NULL, NULL, NULL, value);
                else
                    err = nc_get_vars_schar(ncid, i, index, count, stride, value);
            if (canConvert) {
                if (allInExtRange) {
                  if (allInIntRange) {
                      IF (err)
                        error("%s", nc_strerror(err));
                  } else {
                      IF (err != NC_ERANGE)
                        error("Range error: status = %d", err);
                  }
                } else {
                  IF (err != 0 && err != NC_ERANGE)
                      error("OK or Range error: status = %d", err);
                }
                for (j = 0; j < nels; j++) {
                  if (inRange3(expect[j],var_type[i],NCT_SCHAR)
                        && expect[j] >= schar_min && expect[j] <= schar_max) {
                      IF (!equal(value[j],expect[j],var_type[i],
                            NCT_SCHAR)){
                        error("value read not that expected");
                        if (verbose) {
                            error("\n");
                            error("varid: %d, ", i);
                            error("var_name: %s, ", var_name[i]);
                            error("element number: %d ", j);
                                    error("expect: %g, ", expect[j]);
                            error("got: %g", (double) value[j]);
                        }
                      } else {
                        nok++;
                      }
                  }
                }
            } else {
                IF (nels > 0 && err != NC_ECHAR)
                  error("wrong type: status = %d", err);
            }
          }
      }

    }
    err = nc_close(ncid);
    IF (err)
        error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_vars_short(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int m;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nstarts;        /* number of different starts */
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t index2[MAX_RANK];
    size_t mid[MAX_RANK];
    size_t count[MAX_RANK];
    size_t sstride[MAX_RANK];
    ptrdiff_t stride[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    short value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
        error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_SHORT == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = 0;
            edge[j] = 1;
            stride[j] = 1;
        }
        err = nc_get_vars_short(BAD_ID, i, start, edge, stride, value);
        IF (err != NC_EBADID)
            error("bad ncid: status = %d", err);
        err = nc_get_vars_short(ncid, BAD_VARID, start, edge, stride, value);
        IF (err != NC_ENOTVAR)
            error("bad var id: status = %d", err);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = var_shape[i][j];
            err = nc_get_vars_short(ncid, i, start, edge, stride, value);
        if(!canConvert) {
            IF (err != NC_ECHAR)
                      error("conversion: status = %d", err);
        } else {
            IF (err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
            start[j] = 0;
            edge[j] = var_shape[i][j] + 1;
            err = nc_get_vars_short(ncid, i, start, edge, stride, value);
            IF (err != NC_EEDGE)
                error("bad edge: status = %d", err);
            edge[j] = 1;
            stride[j] = 0;
            err = nc_get_vars_short(ncid, i, start, edge, stride, value);
            IF (err != NC_ESTRIDE)
                error("bad stride: status = %d", err);
            stride[j] = 1;
        }
        }
            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
            /* choose random stride from 1 to edge */
        for (k = 0; k < nslabs; k++) {
            nstarts = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
                nstarts *= stride[j];
            }
            for (m = 0; m < nstarts; m++) {
                err = toMixedBase(m, var_rank[i], sstride, index);
                IF (err)
                    error("error in toMixedBase");
                nels = 1;
                for (j = 0; j < var_rank[i]; j++) {
                    count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
                    nels *= count[j];
                    index[j] += start[j];
                }
                        /* Random choice of forward or backward */
/* TODO
                if ( roll(2) ) {
                    for (j = 0; j < var_rank[i]; j++) {
                        index[j] += (count[j] - 1) * stride[j];
                        stride[j] = -stride[j];
                    }
                }
*/
            allInExtRange = allInIntRange = 1;
            for (j = 0; j < nels; j++) {
                err = toMixedBase(j, var_rank[i], count, index2);
                IF (err)
                  error("error in toMixedBase 1");
                for (d = 0; d < var_rank[i]; d++)
                  index2[d] = index[d] + index2[d] * stride[d];
                expect[j] = hash4(var_type[i], var_rank[i], index2, 
                  NCT_SHORT);
                if (inRange3(expect[j],var_type[i],NCT_SHORT)) {
                  allInIntRange = allInIntRange && expect[j] >= short_min
                      && expect[j] <= short_max;
                } else {
                  allInExtRange = 0;
                }
            }
                if (var_rank[i] == 0 && i%2 )
                    err = nc_get_vars_short(ncid, i, NULL, NULL, NULL, value);
                else
                    err = nc_get_vars_short(ncid, i, index, count, stride, value);
            if (canConvert) {
                if (allInExtRange) {
                  if (allInIntRange) {
                      IF (err)
                        error("%s", nc_strerror(err));
                  } else {
                      IF (err != NC_ERANGE)
                        error("Range error: status = %d", err);
                  }
                } else {
                  IF (err != 0 && err != NC_ERANGE)
                      error("OK or Range error: status = %d", err);
                }
                for (j = 0; j < nels; j++) {
                  if (inRange3(expect[j],var_type[i],NCT_SHORT)
                        && expect[j] >= short_min && expect[j] <= short_max) {
                      IF (!equal(value[j],expect[j],var_type[i],
                            NCT_SHORT)){
                        error("value read not that expected");
                        if (verbose) {
                            error("\n");
                            error("varid: %d, ", i);
                            error("var_name: %s, ", var_name[i]);
                            error("element number: %d ", j);
                                    error("expect: %g, ", expect[j]);
                            error("got: %g", (double) value[j]);
                        }
                      } else {
                        nok++;
                      }
                  }
                }
            } else {
                IF (nels > 0 && err != NC_ECHAR)
                  error("wrong type: status = %d", err);
            }
          }
      }

    }
    err = nc_close(ncid);
    IF (err)
        error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_vars_int(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int m;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nstarts;        /* number of different starts */
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t index2[MAX_RANK];
    size_t mid[MAX_RANK];
    size_t count[MAX_RANK];
    size_t sstride[MAX_RANK];
    ptrdiff_t stride[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    int value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
        error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_INT == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = 0;
            edge[j] = 1;
            stride[j] = 1;
        }
        err = nc_get_vars_int(BAD_ID, i, start, edge, stride, value);
        IF (err != NC_EBADID)
            error("bad ncid: status = %d", err);
        err = nc_get_vars_int(ncid, BAD_VARID, start, edge, stride, value);
        IF (err != NC_ENOTVAR)
            error("bad var id: status = %d", err);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = var_shape[i][j];
            err = nc_get_vars_int(ncid, i, start, edge, stride, value);
        if(!canConvert) {
            IF (err != NC_ECHAR)
                      error("conversion: status = %d", err);
        } else {
            IF (err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
            start[j] = 0;
            edge[j] = var_shape[i][j] + 1;
            err = nc_get_vars_int(ncid, i, start, edge, stride, value);
            IF (err != NC_EEDGE)
                error("bad edge: status = %d", err);
            edge[j] = 1;
            stride[j] = 0;
            err = nc_get_vars_int(ncid, i, start, edge, stride, value);
            IF (err != NC_ESTRIDE)
                error("bad stride: status = %d", err);
            stride[j] = 1;
        }
        }
            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
            /* choose random stride from 1 to edge */
        for (k = 0; k < nslabs; k++) {
            nstarts = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
                nstarts *= stride[j];
            }
            for (m = 0; m < nstarts; m++) {
                err = toMixedBase(m, var_rank[i], sstride, index);
                IF (err)
                    error("error in toMixedBase");
                nels = 1;
                for (j = 0; j < var_rank[i]; j++) {
                    count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
                    nels *= count[j];
                    index[j] += start[j];
                }
                        /* Random choice of forward or backward */
/* TODO
                if ( roll(2) ) {
                    for (j = 0; j < var_rank[i]; j++) {
                        index[j] += (count[j] - 1) * stride[j];
                        stride[j] = -stride[j];
                    }
                }
*/
            allInExtRange = allInIntRange = 1;
            for (j = 0; j < nels; j++) {
                err = toMixedBase(j, var_rank[i], count, index2);
                IF (err)
                  error("error in toMixedBase 1");
                for (d = 0; d < var_rank[i]; d++)
                  index2[d] = index[d] + index2[d] * stride[d];
                expect[j] = hash4(var_type[i], var_rank[i], index2, 
                  NCT_INT);
                if (inRange3(expect[j],var_type[i],NCT_INT)) {
                  allInIntRange = allInIntRange && expect[j] >= int_min
                      && expect[j] <= int_max;
                } else {
                  allInExtRange = 0;
                }
            }
                if (var_rank[i] == 0 && i%2 )
                    err = nc_get_vars_int(ncid, i, NULL, NULL, NULL, value);
                else
                    err = nc_get_vars_int(ncid, i, index, count, stride, value);
            if (canConvert) {
                if (allInExtRange) {
                  if (allInIntRange) {
                      IF (err)
                        error("%s", nc_strerror(err));
                  } else {
                      IF (err != NC_ERANGE)
                        error("Range error: status = %d", err);
                  }
                } else {
                  IF (err != 0 && err != NC_ERANGE)
                      error("OK or Range error: status = %d", err);
                }
                for (j = 0; j < nels; j++) {
                  if (inRange3(expect[j],var_type[i],NCT_INT)
                        && expect[j] >= int_min && expect[j] <= int_max) {
                      IF (!equal(value[j],expect[j],var_type[i],
                            NCT_INT)){
                        error("value read not that expected");
                        if (verbose) {
                            error("\n");
                            error("varid: %d, ", i);
                            error("var_name: %s, ", var_name[i]);
                            error("element number: %d ", j);
                                    error("expect: %g, ", expect[j]);
                            error("got: %g", (double) value[j]);
                        }
                      } else {
                        nok++;
                      }
                  }
                }
            } else {
                IF (nels > 0 && err != NC_ECHAR)
                  error("wrong type: status = %d", err);
            }
          }
      }

    }
    err = nc_close(ncid);
    IF (err)
        error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_vars_long(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int m;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nstarts;        /* number of different starts */
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t index2[MAX_RANK];
    size_t mid[MAX_RANK];
    size_t count[MAX_RANK];
    size_t sstride[MAX_RANK];
    ptrdiff_t stride[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    long value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
        error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_LONG == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = 0;
            edge[j] = 1;
            stride[j] = 1;
        }
        err = nc_get_vars_long(BAD_ID, i, start, edge, stride, value);
        IF (err != NC_EBADID)
            error("bad ncid: status = %d", err);
        err = nc_get_vars_long(ncid, BAD_VARID, start, edge, stride, value);
        IF (err != NC_ENOTVAR)
            error("bad var id: status = %d", err);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = var_shape[i][j];
            err = nc_get_vars_long(ncid, i, start, edge, stride, value);
        if(!canConvert) {
            IF (err != NC_ECHAR)
                      error("conversion: status = %d", err);
        } else {
            IF (err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
            start[j] = 0;
            edge[j] = var_shape[i][j] + 1;
            err = nc_get_vars_long(ncid, i, start, edge, stride, value);
            IF (err != NC_EEDGE)
                error("bad edge: status = %d", err);
            edge[j] = 1;
            stride[j] = 0;
            err = nc_get_vars_long(ncid, i, start, edge, stride, value);
            IF (err != NC_ESTRIDE)
                error("bad stride: status = %d", err);
            stride[j] = 1;
        }
        }
            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
            /* choose random stride from 1 to edge */
        for (k = 0; k < nslabs; k++) {
            nstarts = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
                nstarts *= stride[j];
            }
            for (m = 0; m < nstarts; m++) {
                err = toMixedBase(m, var_rank[i], sstride, index);
                IF (err)
                    error("error in toMixedBase");
                nels = 1;
                for (j = 0; j < var_rank[i]; j++) {
                    count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
                    nels *= count[j];
                    index[j] += start[j];
                }
                        /* Random choice of forward or backward */
/* TODO
                if ( roll(2) ) {
                    for (j = 0; j < var_rank[i]; j++) {
                        index[j] += (count[j] - 1) * stride[j];
                        stride[j] = -stride[j];
                    }
                }
*/
            allInExtRange = allInIntRange = 1;
            for (j = 0; j < nels; j++) {
                err = toMixedBase(j, var_rank[i], count, index2);
                IF (err)
                  error("error in toMixedBase 1");
                for (d = 0; d < var_rank[i]; d++)
                  index2[d] = index[d] + index2[d] * stride[d];
                expect[j] = hash4(var_type[i], var_rank[i], index2, 
                  NCT_LONG);
                if (inRange3(expect[j],var_type[i],NCT_LONG)) {
                  allInIntRange = allInIntRange && expect[j] >= long_min
                      && expect[j] <= long_max;
                } else {
                  allInExtRange = 0;
                }
            }
                if (var_rank[i] == 0 && i%2 )
                    err = nc_get_vars_long(ncid, i, NULL, NULL, NULL, value);
                else
                    err = nc_get_vars_long(ncid, i, index, count, stride, value);
            if (canConvert) {
                if (allInExtRange) {
                  if (allInIntRange) {
                      IF (err)
                        error("%s", nc_strerror(err));
                  } else {
                      IF (err != NC_ERANGE)
                        error("Range error: status = %d", err);
                  }
                } else {
                  IF (err != 0 && err != NC_ERANGE)
                      error("OK or Range error: status = %d", err);
                }
                for (j = 0; j < nels; j++) {
                  if (inRange3(expect[j],var_type[i],NCT_LONG)
                        && expect[j] >= long_min && expect[j] <= long_max) {
                      IF (!equal(value[j],expect[j],var_type[i],
                            NCT_LONG)){
                        error("value read not that expected");
                        if (verbose) {
                            error("\n");
                            error("varid: %d, ", i);
                            error("var_name: %s, ", var_name[i]);
                            error("element number: %d ", j);
                                    error("expect: %g, ", expect[j]);
                            error("got: %g", (double) value[j]);
                        }
                      } else {
                        nok++;
                      }
                  }
                }
            } else {
                IF (nels > 0 && err != NC_ECHAR)
                  error("wrong type: status = %d", err);
            }
          }
      }

    }
    err = nc_close(ncid);
    IF (err)
        error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_vars_float(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int m;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nstarts;        /* number of different starts */
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t index2[MAX_RANK];
    size_t mid[MAX_RANK];
    size_t count[MAX_RANK];
    size_t sstride[MAX_RANK];
    ptrdiff_t stride[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    float value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
        error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_FLOAT == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = 0;
            edge[j] = 1;
            stride[j] = 1;
        }
        err = nc_get_vars_float(BAD_ID, i, start, edge, stride, value);
        IF (err != NC_EBADID)
            error("bad ncid: status = %d", err);
        err = nc_get_vars_float(ncid, BAD_VARID, start, edge, stride, value);
        IF (err != NC_ENOTVAR)
            error("bad var id: status = %d", err);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = var_shape[i][j];
            err = nc_get_vars_float(ncid, i, start, edge, stride, value);
        if(!canConvert) {
            IF (err != NC_ECHAR)
                      error("conversion: status = %d", err);
        } else {
            IF (err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
            start[j] = 0;
            edge[j] = var_shape[i][j] + 1;
            err = nc_get_vars_float(ncid, i, start, edge, stride, value);
            IF (err != NC_EEDGE)
                error("bad edge: status = %d", err);
            edge[j] = 1;
            stride[j] = 0;
            err = nc_get_vars_float(ncid, i, start, edge, stride, value);
            IF (err != NC_ESTRIDE)
                error("bad stride: status = %d", err);
            stride[j] = 1;
        }
        }
            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
            /* choose random stride from 1 to edge */
        for (k = 0; k < nslabs; k++) {
            nstarts = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
                nstarts *= stride[j];
            }
            for (m = 0; m < nstarts; m++) {
                err = toMixedBase(m, var_rank[i], sstride, index);
                IF (err)
                    error("error in toMixedBase");
                nels = 1;
                for (j = 0; j < var_rank[i]; j++) {
                    count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
                    nels *= count[j];
                    index[j] += start[j];
                }
                        /* Random choice of forward or backward */
/* TODO
                if ( roll(2) ) {
                    for (j = 0; j < var_rank[i]; j++) {
                        index[j] += (count[j] - 1) * stride[j];
                        stride[j] = -stride[j];
                    }
                }
*/
            allInExtRange = allInIntRange = 1;
            for (j = 0; j < nels; j++) {
                err = toMixedBase(j, var_rank[i], count, index2);
                IF (err)
                  error("error in toMixedBase 1");
                for (d = 0; d < var_rank[i]; d++)
                  index2[d] = index[d] + index2[d] * stride[d];
                expect[j] = hash4(var_type[i], var_rank[i], index2, 
                  NCT_FLOAT);
                if (inRange3(expect[j],var_type[i],NCT_FLOAT)) {
                  allInIntRange = allInIntRange && expect[j] >= float_min
                      && expect[j] <= float_max;
                } else {
                  allInExtRange = 0;
                }
            }
                if (var_rank[i] == 0 && i%2 )
                    err = nc_get_vars_float(ncid, i, NULL, NULL, NULL, value);
                else
                    err = nc_get_vars_float(ncid, i, index, count, stride, value);
            if (canConvert) {
                if (allInExtRange) {
                  if (allInIntRange) {
                      IF (err)
                        error("%s", nc_strerror(err));
                  } else {
                      IF (err != NC_ERANGE)
                        error("Range error: status = %d", err);
                  }
                } else {
                  IF (err != 0 && err != NC_ERANGE)
                      error("OK or Range error: status = %d", err);
                }
                for (j = 0; j < nels; j++) {
                  if (inRange3(expect[j],var_type[i],NCT_FLOAT)
                        && expect[j] >= float_min && expect[j] <= float_max) {
                      IF (!equal(value[j],expect[j],var_type[i],
                            NCT_FLOAT)){
                        error("value read not that expected");
                        if (verbose) {
                            error("\n");
                            error("varid: %d, ", i);
                            error("var_name: %s, ", var_name[i]);
                            error("element number: %d ", j);
                                    error("expect: %g, ", expect[j]);
                            error("got: %g", (double) value[j]);
                        }
                      } else {
                        nok++;
                      }
                  }
                }
            } else {
                IF (nels > 0 && err != NC_ECHAR)
                  error("wrong type: status = %d", err);
            }
          }
      }

    }
    err = nc_close(ncid);
    IF (err)
        error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_vars_double(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int m;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nstarts;        /* number of different starts */
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t index2[MAX_RANK];
    size_t mid[MAX_RANK];
    size_t count[MAX_RANK];
    size_t sstride[MAX_RANK];
    ptrdiff_t stride[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    double value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
        error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_DOUBLE == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = 0;
            edge[j] = 1;
            stride[j] = 1;
        }
        err = nc_get_vars_double(BAD_ID, i, start, edge, stride, value);
        IF (err != NC_EBADID)
            error("bad ncid: status = %d", err);
        err = nc_get_vars_double(ncid, BAD_VARID, start, edge, stride, value);
        IF (err != NC_ENOTVAR)
            error("bad var id: status = %d", err);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = var_shape[i][j];
            err = nc_get_vars_double(ncid, i, start, edge, stride, value);
        if(!canConvert) {
            IF (err != NC_ECHAR)
                      error("conversion: status = %d", err);
        } else {
            IF (err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
            start[j] = 0;
            edge[j] = var_shape[i][j] + 1;
            err = nc_get_vars_double(ncid, i, start, edge, stride, value);
            IF (err != NC_EEDGE)
                error("bad edge: status = %d", err);
            edge[j] = 1;
            stride[j] = 0;
            err = nc_get_vars_double(ncid, i, start, edge, stride, value);
            IF (err != NC_ESTRIDE)
                error("bad stride: status = %d", err);
            stride[j] = 1;
        }
        }
            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
            /* choose random stride from 1 to edge */
        for (k = 0; k < nslabs; k++) {
            nstarts = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
                nstarts *= stride[j];
            }
            for (m = 0; m < nstarts; m++) {
                err = toMixedBase(m, var_rank[i], sstride, index);
                IF (err)
                    error("error in toMixedBase");
                nels = 1;
                for (j = 0; j < var_rank[i]; j++) {
                    count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
                    nels *= count[j];
                    index[j] += start[j];
                }
                        /* Random choice of forward or backward */
/* TODO
                if ( roll(2) ) {
                    for (j = 0; j < var_rank[i]; j++) {
                        index[j] += (count[j] - 1) * stride[j];
                        stride[j] = -stride[j];
                    }
                }
*/
            allInExtRange = allInIntRange = 1;
            for (j = 0; j < nels; j++) {
                err = toMixedBase(j, var_rank[i], count, index2);
                IF (err)
                  error("error in toMixedBase 1");
                for (d = 0; d < var_rank[i]; d++)
                  index2[d] = index[d] + index2[d] * stride[d];
                expect[j] = hash4(var_type[i], var_rank[i], index2, 
                  NCT_DOUBLE);
                if (inRange3(expect[j],var_type[i],NCT_DOUBLE)) {
                  allInIntRange = allInIntRange && expect[j] >= double_min
                      && expect[j] <= double_max;
                } else {
                  allInExtRange = 0;
                }
            }
                if (var_rank[i] == 0 && i%2 )
                    err = nc_get_vars_double(ncid, i, NULL, NULL, NULL, value);
                else
                    err = nc_get_vars_double(ncid, i, index, count, stride, value);
            if (canConvert) {
                if (allInExtRange) {
                  if (allInIntRange) {
                      IF (err)
                        error("%s", nc_strerror(err));
                  } else {
                      IF (err != NC_ERANGE)
                        error("Range error: status = %d", err);
                  }
                } else {
                  IF (err != 0 && err != NC_ERANGE)
                      error("OK or Range error: status = %d", err);
                }
                for (j = 0; j < nels; j++) {
                  if (inRange3(expect[j],var_type[i],NCT_DOUBLE)
                        && expect[j] >= double_min && expect[j] <= double_max) {
                      IF (!equal(value[j],expect[j],var_type[i],
                            NCT_DOUBLE)){
                        error("value read not that expected");
                        if (verbose) {
                            error("\n");
                            error("varid: %d, ", i);
                            error("var_name: %s, ", var_name[i]);
                            error("element number: %d ", j);
                                    error("expect: %g, ", expect[j]);
                            error("got: %g", (double) value[j]);
                        }
                      } else {
                        nok++;
                      }
                  }
                }
            } else {
                IF (nels > 0 && err != NC_ECHAR)
                  error("wrong type: status = %d", err);
            }
          }
      }

    }
    err = nc_close(ncid);
    IF (err)
        error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}




void
test_nc_get_varm_text(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int m;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nstarts;        /* number of different starts */
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t index2[MAX_RANK];
    size_t mid[MAX_RANK];
    size_t count[MAX_RANK];
    size_t sstride[MAX_RANK];
    ptrdiff_t stride[MAX_RANK];
    ptrdiff_t imap[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    text value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
        error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_TEXT == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = 0;
            edge[j] = 1;
            stride[j] = 1;
            imap[j] = 1;
        }
        err = nc_get_varm_text(BAD_ID, i, start, edge, stride, imap, value);
        IF (err != NC_EBADID)
            error("bad ncid: status = %d", err);
        err = nc_get_varm_text(ncid, BAD_VARID, start, edge, stride, imap, value);
        IF (err != NC_ENOTVAR)
            error("bad var id: status = %d", err);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = var_shape[i][j];
            err = nc_get_varm_text(ncid, i, start, edge, stride, imap, value);
        if(!canConvert) {
            IF (err != NC_ECHAR)
                      error("conversion: status = %d", err);
        } else {
          IF (err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
            start[j] = 0;
            edge[j] = var_shape[i][j] + 1;
            err = nc_get_varm_text(ncid, i, start, edge, stride, imap, value);
            IF (err != NC_EEDGE)
                error("bad edge: status = %d", err);
            edge[j] = 1;
            stride[j] = 0;
            err = nc_get_varm_text(ncid, i, start, edge, stride, imap, value);
            IF (err != NC_ESTRIDE)
                error("bad stride: status = %d", err);
            stride[j] = 1;
           }
        }
            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
            /* choose random stride from 1 to edge */
        for (k = 0; k < nslabs; k++) {
            nstarts = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
                nstarts *= stride[j];
            }
            for (m = 0; m < nstarts; m++) {
                err = toMixedBase(m, var_rank[i], sstride, index);
                IF (err)
                    error("error in toMixedBase");
                nels = 1;
                for (j = 0; j < var_rank[i]; j++) {
                    count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
                    nels *= count[j];
                    index[j] += start[j];
                }
                /* Random choice of forward or backward */
/* TODO
            if ( roll(2) ) {
                for (j = 0; j < var_rank[i]; j++) {
                  index[j] += (count[j] - 1) * stride[j];
                  stride[j] = -stride[j];
                }
            }
 */
            if (var_rank[i] > 0) {
                j = var_rank[i] - 1;
                imap[j] = 1;
                for (; j > 0; j--)
                  imap[j-1] = imap[j] * count[j];
            }
                allInExtRange = allInIntRange = 1;
                for (j = 0; j < nels; j++) {
                    err = toMixedBase(j, var_rank[i], count, index2);
                    IF (err)
                        error("error in toMixedBase 1");
                    for (d = 0; d < var_rank[i]; d++)
                        index2[d] = index[d] + index2[d] * stride[d];
                    expect[j] = hash4(var_type[i], var_rank[i], index2,
                        NCT_TEXT);
                    if (inRange3(expect[j],var_type[i],NCT_TEXT)) {
                        allInIntRange = allInIntRange && expect[j] >= text_min
                            && expect[j] <= text_max;
                    } else {
                        allInExtRange = 0;
                    }
                }
                if (var_rank[i] == 0 && i%2 )
                    err = nc_get_varm_text(ncid,i,NULL,NULL,NULL,NULL,value);
                else
                    err = nc_get_varm_text(ncid,i,index,count,stride,imap,value);
                if (canConvert) {
                    if (allInExtRange) {
                        if (allInIntRange) {
                            IF (err)
                                error("%s", nc_strerror(err));
                        } else {
                            IF (err != NC_ERANGE)
                                error("Range error: status = %d", err);
                        }
                    } else {
                        IF (err != 0 && err != NC_ERANGE)
                            error("OK or Range error: status = %d", err);
                    }
                    for (j = 0; j < nels; j++) {
                        if (inRange3(expect[j],var_type[i],NCT_TEXT)
                                && expect[j] >= text_min 
                        && expect[j] <= text_max) {
                      IF (!equal(value[j],expect[j],var_type[i],
                            NCT_TEXT)){
                                error("value read not that expected");
                                if (verbose) {
                                    error("\n");
                                    error("varid: %d, ", i);
                                    error("var_name: %s, ", var_name[i]);
                                    error("element number: %d ", j);
                                    error("expect: %g, ", expect[j]);
                                    error("got: %g", (double) value[j]);
                                }
                            } else {
                                nok++;
                            }
                        }
                    }
                } else {
                    IF (nels > 0 && err != NC_ECHAR)
                        error("wrong type: status = %d", err);
                }
            }
        }
    }
    err = nc_close(ncid);
    IF (err)
        error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_varm_uchar(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int m;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nstarts;        /* number of different starts */
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t index2[MAX_RANK];
    size_t mid[MAX_RANK];
    size_t count[MAX_RANK];
    size_t sstride[MAX_RANK];
    ptrdiff_t stride[MAX_RANK];
    ptrdiff_t imap[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    uchar value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
        error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_UCHAR == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = 0;
            edge[j] = 1;
            stride[j] = 1;
            imap[j] = 1;
        }
        err = nc_get_varm_uchar(BAD_ID, i, start, edge, stride, imap, value);
        IF (err != NC_EBADID)
            error("bad ncid: status = %d", err);
        err = nc_get_varm_uchar(ncid, BAD_VARID, start, edge, stride, imap, value);
        IF (err != NC_ENOTVAR)
            error("bad var id: status = %d", err);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = var_shape[i][j];
            err = nc_get_varm_uchar(ncid, i, start, edge, stride, imap, value);
        if(!canConvert) {
            IF (err != NC_ECHAR)
                      error("conversion: status = %d", err);
        } else {
          IF (err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
            start[j] = 0;
            edge[j] = var_shape[i][j] + 1;
            err = nc_get_varm_uchar(ncid, i, start, edge, stride, imap, value);
            IF (err != NC_EEDGE)
                error("bad edge: status = %d", err);
            edge[j] = 1;
            stride[j] = 0;
            err = nc_get_varm_uchar(ncid, i, start, edge, stride, imap, value);
            IF (err != NC_ESTRIDE)
                error("bad stride: status = %d", err);
            stride[j] = 1;
           }
        }
            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
            /* choose random stride from 1 to edge */
        for (k = 0; k < nslabs; k++) {
            nstarts = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
                nstarts *= stride[j];
            }
            for (m = 0; m < nstarts; m++) {
                err = toMixedBase(m, var_rank[i], sstride, index);
                IF (err)
                    error("error in toMixedBase");
                nels = 1;
                for (j = 0; j < var_rank[i]; j++) {
                    count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
                    nels *= count[j];
                    index[j] += start[j];
                }
                /* Random choice of forward or backward */
/* TODO
            if ( roll(2) ) {
                for (j = 0; j < var_rank[i]; j++) {
                  index[j] += (count[j] - 1) * stride[j];
                  stride[j] = -stride[j];
                }
            }
 */
            if (var_rank[i] > 0) {
                j = var_rank[i] - 1;
                imap[j] = 1;
                for (; j > 0; j--)
                  imap[j-1] = imap[j] * count[j];
            }
                allInExtRange = allInIntRange = 1;
                for (j = 0; j < nels; j++) {
                    err = toMixedBase(j, var_rank[i], count, index2);
                    IF (err)
                        error("error in toMixedBase 1");
                    for (d = 0; d < var_rank[i]; d++)
                        index2[d] = index[d] + index2[d] * stride[d];
                    expect[j] = hash4(var_type[i], var_rank[i], index2,
                        NCT_UCHAR);
                    if (inRange3(expect[j],var_type[i],NCT_UCHAR)) {
                        allInIntRange = allInIntRange && expect[j] >= uchar_min
                            && expect[j] <= uchar_max;
                    } else {
                        allInExtRange = 0;
                    }
                }
                if (var_rank[i] == 0 && i%2 )
                    err = nc_get_varm_uchar(ncid,i,NULL,NULL,NULL,NULL,value);
                else
                    err = nc_get_varm_uchar(ncid,i,index,count,stride,imap,value);
                if (canConvert) {
                    if (allInExtRange) {
                        if (allInIntRange) {
                            IF (err)
                                error("%s", nc_strerror(err));
                        } else {
                            IF (err != NC_ERANGE)
                                error("Range error: status = %d", err);
                        }
                    } else {
                        IF (err != 0 && err != NC_ERANGE)
                            error("OK or Range error: status = %d", err);
                    }
                    for (j = 0; j < nels; j++) {
                        if (inRange3(expect[j],var_type[i],NCT_UCHAR)
                                && expect[j] >= uchar_min 
                        && expect[j] <= uchar_max) {
                      IF (!equal(value[j],expect[j],var_type[i],
                            NCT_UCHAR)){
                                error("value read not that expected");
                                if (verbose) {
                                    error("\n");
                                    error("varid: %d, ", i);
                                    error("var_name: %s, ", var_name[i]);
                                    error("element number: %d ", j);
                                    error("expect: %g, ", expect[j]);
                                    error("got: %g", (double) value[j]);
                                }
                            } else {
                                nok++;
                            }
                        }
                    }
                } else {
                    IF (nels > 0 && err != NC_ECHAR)
                        error("wrong type: status = %d", err);
                }
            }
        }
    }
    err = nc_close(ncid);
    IF (err)
        error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_varm_schar(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int m;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nstarts;        /* number of different starts */
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t index2[MAX_RANK];
    size_t mid[MAX_RANK];
    size_t count[MAX_RANK];
    size_t sstride[MAX_RANK];
    ptrdiff_t stride[MAX_RANK];
    ptrdiff_t imap[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    schar value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
        error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_SCHAR == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = 0;
            edge[j] = 1;
            stride[j] = 1;
            imap[j] = 1;
        }
        err = nc_get_varm_schar(BAD_ID, i, start, edge, stride, imap, value);
        IF (err != NC_EBADID)
            error("bad ncid: status = %d", err);
        err = nc_get_varm_schar(ncid, BAD_VARID, start, edge, stride, imap, value);
        IF (err != NC_ENOTVAR)
            error("bad var id: status = %d", err);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = var_shape[i][j];
            err = nc_get_varm_schar(ncid, i, start, edge, stride, imap, value);
        if(!canConvert) {
            IF (err != NC_ECHAR)
                      error("conversion: status = %d", err);
        } else {
          IF (err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
            start[j] = 0;
            edge[j] = var_shape[i][j] + 1;
            err = nc_get_varm_schar(ncid, i, start, edge, stride, imap, value);
            IF (err != NC_EEDGE)
                error("bad edge: status = %d", err);
            edge[j] = 1;
            stride[j] = 0;
            err = nc_get_varm_schar(ncid, i, start, edge, stride, imap, value);
            IF (err != NC_ESTRIDE)
                error("bad stride: status = %d", err);
            stride[j] = 1;
           }
        }
            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
            /* choose random stride from 1 to edge */
        for (k = 0; k < nslabs; k++) {
            nstarts = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
                nstarts *= stride[j];
            }
            for (m = 0; m < nstarts; m++) {
                err = toMixedBase(m, var_rank[i], sstride, index);
                IF (err)
                    error("error in toMixedBase");
                nels = 1;
                for (j = 0; j < var_rank[i]; j++) {
                    count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
                    nels *= count[j];
                    index[j] += start[j];
                }
                /* Random choice of forward or backward */
/* TODO
            if ( roll(2) ) {
                for (j = 0; j < var_rank[i]; j++) {
                  index[j] += (count[j] - 1) * stride[j];
                  stride[j] = -stride[j];
                }
            }
 */
            if (var_rank[i] > 0) {
                j = var_rank[i] - 1;
                imap[j] = 1;
                for (; j > 0; j--)
                  imap[j-1] = imap[j] * count[j];
            }
                allInExtRange = allInIntRange = 1;
                for (j = 0; j < nels; j++) {
                    err = toMixedBase(j, var_rank[i], count, index2);
                    IF (err)
                        error("error in toMixedBase 1");
                    for (d = 0; d < var_rank[i]; d++)
                        index2[d] = index[d] + index2[d] * stride[d];
                    expect[j] = hash4(var_type[i], var_rank[i], index2,
                        NCT_SCHAR);
                    if (inRange3(expect[j],var_type[i],NCT_SCHAR)) {
                        allInIntRange = allInIntRange && expect[j] >= schar_min
                            && expect[j] <= schar_max;
                    } else {
                        allInExtRange = 0;
                    }
                }
                if (var_rank[i] == 0 && i%2 )
                    err = nc_get_varm_schar(ncid,i,NULL,NULL,NULL,NULL,value);
                else
                    err = nc_get_varm_schar(ncid,i,index,count,stride,imap,value);
                if (canConvert) {
                    if (allInExtRange) {
                        if (allInIntRange) {
                            IF (err)
                                error("%s", nc_strerror(err));
                        } else {
                            IF (err != NC_ERANGE)
                                error("Range error: status = %d", err);
                        }
                    } else {
                        IF (err != 0 && err != NC_ERANGE)
                            error("OK or Range error: status = %d", err);
                    }
                    for (j = 0; j < nels; j++) {
                        if (inRange3(expect[j],var_type[i],NCT_SCHAR)
                                && expect[j] >= schar_min 
                        && expect[j] <= schar_max) {
                      IF (!equal(value[j],expect[j],var_type[i],
                            NCT_SCHAR)){
                                error("value read not that expected");
                                if (verbose) {
                                    error("\n");
                                    error("varid: %d, ", i);
                                    error("var_name: %s, ", var_name[i]);
                                    error("element number: %d ", j);
                                    error("expect: %g, ", expect[j]);
                                    error("got: %g", (double) value[j]);
                                }
                            } else {
                                nok++;
                            }
                        }
                    }
                } else {
                    IF (nels > 0 && err != NC_ECHAR)
                        error("wrong type: status = %d", err);
                }
            }
        }
    }
    err = nc_close(ncid);
    IF (err)
        error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_varm_short(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int m;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nstarts;        /* number of different starts */
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t index2[MAX_RANK];
    size_t mid[MAX_RANK];
    size_t count[MAX_RANK];
    size_t sstride[MAX_RANK];
    ptrdiff_t stride[MAX_RANK];
    ptrdiff_t imap[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    short value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
        error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_SHORT == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = 0;
            edge[j] = 1;
            stride[j] = 1;
            imap[j] = 1;
        }
        err = nc_get_varm_short(BAD_ID, i, start, edge, stride, imap, value);
        IF (err != NC_EBADID)
            error("bad ncid: status = %d", err);
        err = nc_get_varm_short(ncid, BAD_VARID, start, edge, stride, imap, value);
        IF (err != NC_ENOTVAR)
            error("bad var id: status = %d", err);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = var_shape[i][j];
            err = nc_get_varm_short(ncid, i, start, edge, stride, imap, value);
        if(!canConvert) {
            IF (err != NC_ECHAR)
                      error("conversion: status = %d", err);
        } else {
          IF (err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
            start[j] = 0;
            edge[j] = var_shape[i][j] + 1;
            err = nc_get_varm_short(ncid, i, start, edge, stride, imap, value);
            IF (err != NC_EEDGE)
                error("bad edge: status = %d", err);
            edge[j] = 1;
            stride[j] = 0;
            err = nc_get_varm_short(ncid, i, start, edge, stride, imap, value);
            IF (err != NC_ESTRIDE)
                error("bad stride: status = %d", err);
            stride[j] = 1;
           }
        }
            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
            /* choose random stride from 1 to edge */
        for (k = 0; k < nslabs; k++) {
            nstarts = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
                nstarts *= stride[j];
            }
            for (m = 0; m < nstarts; m++) {
                err = toMixedBase(m, var_rank[i], sstride, index);
                IF (err)
                    error("error in toMixedBase");
                nels = 1;
                for (j = 0; j < var_rank[i]; j++) {
                    count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
                    nels *= count[j];
                    index[j] += start[j];
                }
                /* Random choice of forward or backward */
/* TODO
            if ( roll(2) ) {
                for (j = 0; j < var_rank[i]; j++) {
                  index[j] += (count[j] - 1) * stride[j];
                  stride[j] = -stride[j];
                }
            }
 */
            if (var_rank[i] > 0) {
                j = var_rank[i] - 1;
                imap[j] = 1;
                for (; j > 0; j--)
                  imap[j-1] = imap[j] * count[j];
            }
                allInExtRange = allInIntRange = 1;
                for (j = 0; j < nels; j++) {
                    err = toMixedBase(j, var_rank[i], count, index2);
                    IF (err)
                        error("error in toMixedBase 1");
                    for (d = 0; d < var_rank[i]; d++)
                        index2[d] = index[d] + index2[d] * stride[d];
                    expect[j] = hash4(var_type[i], var_rank[i], index2,
                        NCT_SHORT);
                    if (inRange3(expect[j],var_type[i],NCT_SHORT)) {
                        allInIntRange = allInIntRange && expect[j] >= short_min
                            && expect[j] <= short_max;
                    } else {
                        allInExtRange = 0;
                    }
                }
                if (var_rank[i] == 0 && i%2 )
                    err = nc_get_varm_short(ncid,i,NULL,NULL,NULL,NULL,value);
                else
                    err = nc_get_varm_short(ncid,i,index,count,stride,imap,value);
                if (canConvert) {
                    if (allInExtRange) {
                        if (allInIntRange) {
                            IF (err)
                                error("%s", nc_strerror(err));
                        } else {
                            IF (err != NC_ERANGE)
                                error("Range error: status = %d", err);
                        }
                    } else {
                        IF (err != 0 && err != NC_ERANGE)
                            error("OK or Range error: status = %d", err);
                    }
                    for (j = 0; j < nels; j++) {
                        if (inRange3(expect[j],var_type[i],NCT_SHORT)
                                && expect[j] >= short_min 
                        && expect[j] <= short_max) {
                      IF (!equal(value[j],expect[j],var_type[i],
                            NCT_SHORT)){
                                error("value read not that expected");
                                if (verbose) {
                                    error("\n");
                                    error("varid: %d, ", i);
                                    error("var_name: %s, ", var_name[i]);
                                    error("element number: %d ", j);
                                    error("expect: %g, ", expect[j]);
                                    error("got: %g", (double) value[j]);
                                }
                            } else {
                                nok++;
                            }
                        }
                    }
                } else {
                    IF (nels > 0 && err != NC_ECHAR)
                        error("wrong type: status = %d", err);
                }
            }
        }
    }
    err = nc_close(ncid);
    IF (err)
        error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_varm_int(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int m;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nstarts;        /* number of different starts */
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t index2[MAX_RANK];
    size_t mid[MAX_RANK];
    size_t count[MAX_RANK];
    size_t sstride[MAX_RANK];
    ptrdiff_t stride[MAX_RANK];
    ptrdiff_t imap[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    int value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
        error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_INT == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = 0;
            edge[j] = 1;
            stride[j] = 1;
            imap[j] = 1;
        }
        err = nc_get_varm_int(BAD_ID, i, start, edge, stride, imap, value);
        IF (err != NC_EBADID)
            error("bad ncid: status = %d", err);
        err = nc_get_varm_int(ncid, BAD_VARID, start, edge, stride, imap, value);
        IF (err != NC_ENOTVAR)
            error("bad var id: status = %d", err);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = var_shape[i][j];
            err = nc_get_varm_int(ncid, i, start, edge, stride, imap, value);
        if(!canConvert) {
            IF (err != NC_ECHAR)
                      error("conversion: status = %d", err);
        } else {
          IF (err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
            start[j] = 0;
            edge[j] = var_shape[i][j] + 1;
            err = nc_get_varm_int(ncid, i, start, edge, stride, imap, value);
            IF (err != NC_EEDGE)
                error("bad edge: status = %d", err);
            edge[j] = 1;
            stride[j] = 0;
            err = nc_get_varm_int(ncid, i, start, edge, stride, imap, value);
            IF (err != NC_ESTRIDE)
                error("bad stride: status = %d", err);
            stride[j] = 1;
           }
        }
            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
            /* choose random stride from 1 to edge */
        for (k = 0; k < nslabs; k++) {
            nstarts = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
                nstarts *= stride[j];
            }
            for (m = 0; m < nstarts; m++) {
                err = toMixedBase(m, var_rank[i], sstride, index);
                IF (err)
                    error("error in toMixedBase");
                nels = 1;
                for (j = 0; j < var_rank[i]; j++) {
                    count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
                    nels *= count[j];
                    index[j] += start[j];
                }
                /* Random choice of forward or backward */
/* TODO
            if ( roll(2) ) {
                for (j = 0; j < var_rank[i]; j++) {
                  index[j] += (count[j] - 1) * stride[j];
                  stride[j] = -stride[j];
                }
            }
 */
            if (var_rank[i] > 0) {
                j = var_rank[i] - 1;
                imap[j] = 1;
                for (; j > 0; j--)
                  imap[j-1] = imap[j] * count[j];
            }
                allInExtRange = allInIntRange = 1;
                for (j = 0; j < nels; j++) {
                    err = toMixedBase(j, var_rank[i], count, index2);
                    IF (err)
                        error("error in toMixedBase 1");
                    for (d = 0; d < var_rank[i]; d++)
                        index2[d] = index[d] + index2[d] * stride[d];
                    expect[j] = hash4(var_type[i], var_rank[i], index2,
                        NCT_INT);
                    if (inRange3(expect[j],var_type[i],NCT_INT)) {
                        allInIntRange = allInIntRange && expect[j] >= int_min
                            && expect[j] <= int_max;
                    } else {
                        allInExtRange = 0;
                    }
                }
                if (var_rank[i] == 0 && i%2 )
                    err = nc_get_varm_int(ncid,i,NULL,NULL,NULL,NULL,value);
                else
                    err = nc_get_varm_int(ncid,i,index,count,stride,imap,value);
                if (canConvert) {
                    if (allInExtRange) {
                        if (allInIntRange) {
                            IF (err)
                                error("%s", nc_strerror(err));
                        } else {
                            IF (err != NC_ERANGE)
                                error("Range error: status = %d", err);
                        }
                    } else {
                        IF (err != 0 && err != NC_ERANGE)
                            error("OK or Range error: status = %d", err);
                    }
                    for (j = 0; j < nels; j++) {
                        if (inRange3(expect[j],var_type[i],NCT_INT)
                                && expect[j] >= int_min 
                        && expect[j] <= int_max) {
                      IF (!equal(value[j],expect[j],var_type[i],
                            NCT_INT)){
                                error("value read not that expected");
                                if (verbose) {
                                    error("\n");
                                    error("varid: %d, ", i);
                                    error("var_name: %s, ", var_name[i]);
                                    error("element number: %d ", j);
                                    error("expect: %g, ", expect[j]);
                                    error("got: %g", (double) value[j]);
                                }
                            } else {
                                nok++;
                            }
                        }
                    }
                } else {
                    IF (nels > 0 && err != NC_ECHAR)
                        error("wrong type: status = %d", err);
                }
            }
        }
    }
    err = nc_close(ncid);
    IF (err)
        error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_varm_long(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int m;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nstarts;        /* number of different starts */
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t index2[MAX_RANK];
    size_t mid[MAX_RANK];
    size_t count[MAX_RANK];
    size_t sstride[MAX_RANK];
    ptrdiff_t stride[MAX_RANK];
    ptrdiff_t imap[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    long value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
        error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_LONG == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = 0;
            edge[j] = 1;
            stride[j] = 1;
            imap[j] = 1;
        }
        err = nc_get_varm_long(BAD_ID, i, start, edge, stride, imap, value);
        IF (err != NC_EBADID)
            error("bad ncid: status = %d", err);
        err = nc_get_varm_long(ncid, BAD_VARID, start, edge, stride, imap, value);
        IF (err != NC_ENOTVAR)
            error("bad var id: status = %d", err);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = var_shape[i][j];
            err = nc_get_varm_long(ncid, i, start, edge, stride, imap, value);
        if(!canConvert) {
            IF (err != NC_ECHAR)
                      error("conversion: status = %d", err);
        } else {
          IF (err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
            start[j] = 0;
            edge[j] = var_shape[i][j] + 1;
            err = nc_get_varm_long(ncid, i, start, edge, stride, imap, value);
            IF (err != NC_EEDGE)
                error("bad edge: status = %d", err);
            edge[j] = 1;
            stride[j] = 0;
            err = nc_get_varm_long(ncid, i, start, edge, stride, imap, value);
            IF (err != NC_ESTRIDE)
                error("bad stride: status = %d", err);
            stride[j] = 1;
           }
        }
            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
            /* choose random stride from 1 to edge */
        for (k = 0; k < nslabs; k++) {
            nstarts = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
                nstarts *= stride[j];
            }
            for (m = 0; m < nstarts; m++) {
                err = toMixedBase(m, var_rank[i], sstride, index);
                IF (err)
                    error("error in toMixedBase");
                nels = 1;
                for (j = 0; j < var_rank[i]; j++) {
                    count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
                    nels *= count[j];
                    index[j] += start[j];
                }
                /* Random choice of forward or backward */
/* TODO
            if ( roll(2) ) {
                for (j = 0; j < var_rank[i]; j++) {
                  index[j] += (count[j] - 1) * stride[j];
                  stride[j] = -stride[j];
                }
            }
 */
            if (var_rank[i] > 0) {
                j = var_rank[i] - 1;
                imap[j] = 1;
                for (; j > 0; j--)
                  imap[j-1] = imap[j] * count[j];
            }
                allInExtRange = allInIntRange = 1;
                for (j = 0; j < nels; j++) {
                    err = toMixedBase(j, var_rank[i], count, index2);
                    IF (err)
                        error("error in toMixedBase 1");
                    for (d = 0; d < var_rank[i]; d++)
                        index2[d] = index[d] + index2[d] * stride[d];
                    expect[j] = hash4(var_type[i], var_rank[i], index2,
                        NCT_LONG);
                    if (inRange3(expect[j],var_type[i],NCT_LONG)) {
                        allInIntRange = allInIntRange && expect[j] >= long_min
                            && expect[j] <= long_max;
                    } else {
                        allInExtRange = 0;
                    }
                }
                if (var_rank[i] == 0 && i%2 )
                    err = nc_get_varm_long(ncid,i,NULL,NULL,NULL,NULL,value);
                else
                    err = nc_get_varm_long(ncid,i,index,count,stride,imap,value);
                if (canConvert) {
                    if (allInExtRange) {
                        if (allInIntRange) {
                            IF (err)
                                error("%s", nc_strerror(err));
                        } else {
                            IF (err != NC_ERANGE)
                                error("Range error: status = %d", err);
                        }
                    } else {
                        IF (err != 0 && err != NC_ERANGE)
                            error("OK or Range error: status = %d", err);
                    }
                    for (j = 0; j < nels; j++) {
                        if (inRange3(expect[j],var_type[i],NCT_LONG)
                                && expect[j] >= long_min 
                        && expect[j] <= long_max) {
                      IF (!equal(value[j],expect[j],var_type[i],
                            NCT_LONG)){
                                error("value read not that expected");
                                if (verbose) {
                                    error("\n");
                                    error("varid: %d, ", i);
                                    error("var_name: %s, ", var_name[i]);
                                    error("element number: %d ", j);
                                    error("expect: %g, ", expect[j]);
                                    error("got: %g", (double) value[j]);
                                }
                            } else {
                                nok++;
                            }
                        }
                    }
                } else {
                    IF (nels > 0 && err != NC_ECHAR)
                        error("wrong type: status = %d", err);
                }
            }
        }
    }
    err = nc_close(ncid);
    IF (err)
        error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_varm_float(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int m;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nstarts;        /* number of different starts */
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t index2[MAX_RANK];
    size_t mid[MAX_RANK];
    size_t count[MAX_RANK];
    size_t sstride[MAX_RANK];
    ptrdiff_t stride[MAX_RANK];
    ptrdiff_t imap[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    float value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
        error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_FLOAT == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = 0;
            edge[j] = 1;
            stride[j] = 1;
            imap[j] = 1;
        }
        err = nc_get_varm_float(BAD_ID, i, start, edge, stride, imap, value);
        IF (err != NC_EBADID)
            error("bad ncid: status = %d", err);
        err = nc_get_varm_float(ncid, BAD_VARID, start, edge, stride, imap, value);
        IF (err != NC_ENOTVAR)
            error("bad var id: status = %d", err);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = var_shape[i][j];
            err = nc_get_varm_float(ncid, i, start, edge, stride, imap, value);
        if(!canConvert) {
            IF (err != NC_ECHAR)
                      error("conversion: status = %d", err);
        } else {
          IF (err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
            start[j] = 0;
            edge[j] = var_shape[i][j] + 1;
            err = nc_get_varm_float(ncid, i, start, edge, stride, imap, value);
            IF (err != NC_EEDGE)
                error("bad edge: status = %d", err);
            edge[j] = 1;
            stride[j] = 0;
            err = nc_get_varm_float(ncid, i, start, edge, stride, imap, value);
            IF (err != NC_ESTRIDE)
                error("bad stride: status = %d", err);
            stride[j] = 1;
           }
        }
            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
            /* choose random stride from 1 to edge */
        for (k = 0; k < nslabs; k++) {
            nstarts = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
                nstarts *= stride[j];
            }
            for (m = 0; m < nstarts; m++) {
                err = toMixedBase(m, var_rank[i], sstride, index);
                IF (err)
                    error("error in toMixedBase");
                nels = 1;
                for (j = 0; j < var_rank[i]; j++) {
                    count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
                    nels *= count[j];
                    index[j] += start[j];
                }
                /* Random choice of forward or backward */
/* TODO
            if ( roll(2) ) {
                for (j = 0; j < var_rank[i]; j++) {
                  index[j] += (count[j] - 1) * stride[j];
                  stride[j] = -stride[j];
                }
            }
 */
            if (var_rank[i] > 0) {
                j = var_rank[i] - 1;
                imap[j] = 1;
                for (; j > 0; j--)
                  imap[j-1] = imap[j] * count[j];
            }
                allInExtRange = allInIntRange = 1;
                for (j = 0; j < nels; j++) {
                    err = toMixedBase(j, var_rank[i], count, index2);
                    IF (err)
                        error("error in toMixedBase 1");
                    for (d = 0; d < var_rank[i]; d++)
                        index2[d] = index[d] + index2[d] * stride[d];
                    expect[j] = hash4(var_type[i], var_rank[i], index2,
                        NCT_FLOAT);
                    if (inRange3(expect[j],var_type[i],NCT_FLOAT)) {
                        allInIntRange = allInIntRange && expect[j] >= float_min
                            && expect[j] <= float_max;
                    } else {
                        allInExtRange = 0;
                    }
                }
                if (var_rank[i] == 0 && i%2 )
                    err = nc_get_varm_float(ncid,i,NULL,NULL,NULL,NULL,value);
                else
                    err = nc_get_varm_float(ncid,i,index,count,stride,imap,value);
                if (canConvert) {
                    if (allInExtRange) {
                        if (allInIntRange) {
                            IF (err)
                                error("%s", nc_strerror(err));
                        } else {
                            IF (err != NC_ERANGE)
                                error("Range error: status = %d", err);
                        }
                    } else {
                        IF (err != 0 && err != NC_ERANGE)
                            error("OK or Range error: status = %d", err);
                    }
                    for (j = 0; j < nels; j++) {
                        if (inRange3(expect[j],var_type[i],NCT_FLOAT)
                                && expect[j] >= float_min 
                        && expect[j] <= float_max) {
                      IF (!equal(value[j],expect[j],var_type[i],
                            NCT_FLOAT)){
                                error("value read not that expected");
                                if (verbose) {
                                    error("\n");
                                    error("varid: %d, ", i);
                                    error("var_name: %s, ", var_name[i]);
                                    error("element number: %d ", j);
                                    error("expect: %g, ", expect[j]);
                                    error("got: %g", (double) value[j]);
                                }
                            } else {
                                nok++;
                            }
                        }
                    }
                } else {
                    IF (nels > 0 && err != NC_ECHAR)
                        error("wrong type: status = %d", err);
                }
            }
        }
    }
    err = nc_close(ncid);
    IF (err)
        error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_varm_double(void)
{
    int ncid;
    int d;
    int i;
    int j;
    int k;
    int m;
    int err;
    int allInExtRange;  /* all values within external range? */
    int allInIntRange;  /* all values within internal range? */
    int nels;
    int nslabs;
    int nstarts;        /* number of different starts */
    int nok = 0;      /* count of valid comparisons */
    size_t start[MAX_RANK];
    size_t edge[MAX_RANK];
    size_t index[MAX_RANK];
    size_t index2[MAX_RANK];
    size_t mid[MAX_RANK];
    size_t count[MAX_RANK];
    size_t sstride[MAX_RANK];
    ptrdiff_t stride[MAX_RANK];
    ptrdiff_t imap[MAX_RANK];
    int canConvert;     /* Both text or both numeric */
    double value[MAX_NELS];
    double expect[MAX_NELS];

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err)
        error("nc_open: %s", nc_strerror(err));
    for (i = 0; i < NVARS; i++) {
        canConvert = (var_type[i] == NC_CHAR) == (NCT_DOUBLE == NCT_TEXT);
        assert(var_rank[i] <= MAX_RANK);
        assert(var_nels[i] <= MAX_NELS);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = 0;
            edge[j] = 1;
            stride[j] = 1;
            imap[j] = 1;
        }
        err = nc_get_varm_double(BAD_ID, i, start, edge, stride, imap, value);
        IF (err != NC_EBADID)
            error("bad ncid: status = %d", err);
        err = nc_get_varm_double(ncid, BAD_VARID, start, edge, stride, imap, value);
        IF (err != NC_ENOTVAR)
            error("bad var id: status = %d", err);
        for (j = 0; j < var_rank[i]; j++) {
            start[j] = var_shape[i][j];
            err = nc_get_varm_double(ncid, i, start, edge, stride, imap, value);
        if(!canConvert) {
            IF (err != NC_ECHAR)
                      error("conversion: status = %d", err);
        } else {
          IF (err != NC_EINVALCOORDS)
                error("bad index: status = %d", err);
            start[j] = 0;
            edge[j] = var_shape[i][j] + 1;
            err = nc_get_varm_double(ncid, i, start, edge, stride, imap, value);
            IF (err != NC_EEDGE)
                error("bad edge: status = %d", err);
            edge[j] = 1;
            stride[j] = 0;
            err = nc_get_varm_double(ncid, i, start, edge, stride, imap, value);
            IF (err != NC_ESTRIDE)
                error("bad stride: status = %d", err);
            stride[j] = 1;
           }
        }
            /* Choose a random point dividing each dim into 2 parts */
            /* get 2^rank (nslabs) slabs so defined */
        nslabs = 1;
        for (j = 0; j < var_rank[i]; j++) {
            mid[j] = roll( var_shape[i][j] );
            nslabs *= 2;
        }
            /* bits of k determine whether to get lower or upper part of dim */
            /* choose random stride from 1 to edge */
        for (k = 0; k < nslabs; k++) {
            nstarts = 1;
            for (j = 0; j < var_rank[i]; j++) {
                if ((k >> j) & 1) {
                    start[j] = 0;
                    edge[j] = mid[j];
                }else{
                    start[j] = mid[j];
                    edge[j] = var_shape[i][j] - mid[j];
                }
                sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
                nstarts *= stride[j];
            }
            for (m = 0; m < nstarts; m++) {
                err = toMixedBase(m, var_rank[i], sstride, index);
                IF (err)
                    error("error in toMixedBase");
                nels = 1;
                for (j = 0; j < var_rank[i]; j++) {
                    count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
                    nels *= count[j];
                    index[j] += start[j];
                }
                /* Random choice of forward or backward */
/* TODO
            if ( roll(2) ) {
                for (j = 0; j < var_rank[i]; j++) {
                  index[j] += (count[j] - 1) * stride[j];
                  stride[j] = -stride[j];
                }
            }
 */
            if (var_rank[i] > 0) {
                j = var_rank[i] - 1;
                imap[j] = 1;
                for (; j > 0; j--)
                  imap[j-1] = imap[j] * count[j];
            }
                allInExtRange = allInIntRange = 1;
                for (j = 0; j < nels; j++) {
                    err = toMixedBase(j, var_rank[i], count, index2);
                    IF (err)
                        error("error in toMixedBase 1");
                    for (d = 0; d < var_rank[i]; d++)
                        index2[d] = index[d] + index2[d] * stride[d];
                    expect[j] = hash4(var_type[i], var_rank[i], index2,
                        NCT_DOUBLE);
                    if (inRange3(expect[j],var_type[i],NCT_DOUBLE)) {
                        allInIntRange = allInIntRange && expect[j] >= double_min
                            && expect[j] <= double_max;
                    } else {
                        allInExtRange = 0;
                    }
                }
                if (var_rank[i] == 0 && i%2 )
                    err = nc_get_varm_double(ncid,i,NULL,NULL,NULL,NULL,value);
                else
                    err = nc_get_varm_double(ncid,i,index,count,stride,imap,value);
                if (canConvert) {
                    if (allInExtRange) {
                        if (allInIntRange) {
                            IF (err)
                                error("%s", nc_strerror(err));
                        } else {
                            IF (err != NC_ERANGE)
                                error("Range error: status = %d", err);
                        }
                    } else {
                        IF (err != 0 && err != NC_ERANGE)
                            error("OK or Range error: status = %d", err);
                    }
                    for (j = 0; j < nels; j++) {
                        if (inRange3(expect[j],var_type[i],NCT_DOUBLE)
                                && expect[j] >= double_min 
                        && expect[j] <= double_max) {
                      IF (!equal(value[j],expect[j],var_type[i],
                            NCT_DOUBLE)){
                                error("value read not that expected");
                                if (verbose) {
                                    error("\n");
                                    error("varid: %d, ", i);
                                    error("var_name: %s, ", var_name[i]);
                                    error("element number: %d ", j);
                                    error("expect: %g, ", expect[j]);
                                    error("got: %g", (double) value[j]);
                                }
                            } else {
                                nok++;
                            }
                        }
                    }
                } else {
                    IF (nels > 0 && err != NC_ECHAR)
                        error("wrong type: status = %d", err);
                }
            }
        }
    }
    err = nc_close(ncid);
    IF (err)
        error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}




void
test_nc_get_att_text(void)
{
    int ncid;
    int i;
    int j;
    size_t k;
    int err;
    int allInExtRange;
    int allInIntRange;
    int canConvert;     /* Both text or both numeric */
    text value[MAX_NELS];
    double expect[MAX_NELS];
    int nok = 0;      /* count of valid comparisons */

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err) 
      error("nc_open: %s", nc_strerror(err));

    for (i = -1; i < NVARS; i++) {
        for (j = 0; j < NATTS(i); j++) {
          canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_TEXT == NCT_TEXT);
          err = nc_get_att_text(BAD_ID, i, ATT_NAME(i,j), value);
          IF (err != NC_EBADID) 
            error("bad ncid: status = %d", err);
          err = nc_get_att_text(ncid, BAD_VARID, ATT_NAME(i,j), value);
          IF (err != NC_ENOTVAR) 
            error("bad var id: status = %d", err);
          err = nc_get_att_text(ncid, i, "noSuch", value);
          IF (err != NC_ENOTATT) 
            error("Bad attribute name: status = %d", err);
          allInExtRange = allInIntRange = 1;
            for (k = 0; k < ATT_LEN(i,j); k++) {
            expect[k] = hash4(ATT_TYPE(i,j), -1, &k, NCT_TEXT);
                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_TEXT)) {
                    allInIntRange = allInIntRange && expect[k] >= text_min
                                && expect[k] <= text_max;
                } else {
                    allInExtRange = 0;
                }
          }
          err = nc_get_att_text(ncid, i, ATT_NAME(i,j), value);
            if (canConvert || ATT_LEN(i,j) == 0) {
                if (allInExtRange) {
                    if (allInIntRange) {
                        IF (err)
                            error("%s", nc_strerror(err));
                    } else {
                        IF (err != NC_ERANGE)
                            error("Range error: status = %d", err);
                    }
                } else {
                    IF (err != 0 && err != NC_ERANGE)
                        error("OK or Range error: status = %d", err);
                }
            for (k = 0; k < ATT_LEN(i,j); k++) {
                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_TEXT)
                            && expect[k] >= text_min && expect[k] <= text_max) {
                  IF (!equal(value[k],expect[k],ATT_TYPE(i,j),
                        NCT_TEXT)){
                      error("value read not that expected");
                            if (verbose) {
                                error("\n");
                                error("varid: %d, ", i);
                                error("att_name: %s, ", ATT_NAME(i,j));
                                error("element number: %d ", k);
                                error("expect: %g", expect[k]);
                                error("got: %g", (double) value[k]);
                            }
                  } else {
                      nok++;
                        }
                }
            }
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
      }
    }

    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_att_uchar(void)
{
    int ncid;
    int i;
    int j;
    size_t k;
    int err;
    int allInExtRange;
    int allInIntRange;
    int canConvert;     /* Both text or both numeric */
    uchar value[MAX_NELS];
    double expect[MAX_NELS];
    int nok = 0;      /* count of valid comparisons */

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err) 
      error("nc_open: %s", nc_strerror(err));

    for (i = -1; i < NVARS; i++) {
        for (j = 0; j < NATTS(i); j++) {
          canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_UCHAR == NCT_TEXT);
          err = nc_get_att_uchar(BAD_ID, i, ATT_NAME(i,j), value);
          IF (err != NC_EBADID) 
            error("bad ncid: status = %d", err);
          err = nc_get_att_uchar(ncid, BAD_VARID, ATT_NAME(i,j), value);
          IF (err != NC_ENOTVAR) 
            error("bad var id: status = %d", err);
          err = nc_get_att_uchar(ncid, i, "noSuch", value);
          IF (err != NC_ENOTATT) 
            error("Bad attribute name: status = %d", err);
          allInExtRange = allInIntRange = 1;
            for (k = 0; k < ATT_LEN(i,j); k++) {
            expect[k] = hash4(ATT_TYPE(i,j), -1, &k, NCT_UCHAR);
                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_UCHAR)) {
                    allInIntRange = allInIntRange && expect[k] >= uchar_min
                                && expect[k] <= uchar_max;
                } else {
                    allInExtRange = 0;
                }
          }
          err = nc_get_att_uchar(ncid, i, ATT_NAME(i,j), value);
            if (canConvert || ATT_LEN(i,j) == 0) {
                if (allInExtRange) {
                    if (allInIntRange) {
                        IF (err)
                            error("%s", nc_strerror(err));
                    } else {
                        IF (err != NC_ERANGE)
                            error("Range error: status = %d", err);
                    }
                } else {
                    IF (err != 0 && err != NC_ERANGE)
                        error("OK or Range error: status = %d", err);
                }
            for (k = 0; k < ATT_LEN(i,j); k++) {
                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_UCHAR)
                            && expect[k] >= uchar_min && expect[k] <= uchar_max) {
                  IF (!equal(value[k],expect[k],ATT_TYPE(i,j),
                        NCT_UCHAR)){
                      error("value read not that expected");
                            if (verbose) {
                                error("\n");
                                error("varid: %d, ", i);
                                error("att_name: %s, ", ATT_NAME(i,j));
                                error("element number: %d ", k);
                                error("expect: %g", expect[k]);
                                error("got: %g", (double) value[k]);
                            }
                  } else {
                      nok++;
                        }
                }
            }
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
      }
    }

    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_att_schar(void)
{
    int ncid;
    int i;
    int j;
    size_t k;
    int err;
    int allInExtRange;
    int allInIntRange;
    int canConvert;     /* Both text or both numeric */
    schar value[MAX_NELS];
    double expect[MAX_NELS];
    int nok = 0;      /* count of valid comparisons */

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err) 
      error("nc_open: %s", nc_strerror(err));

    for (i = -1; i < NVARS; i++) {
        for (j = 0; j < NATTS(i); j++) {
          canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_SCHAR == NCT_TEXT);
          err = nc_get_att_schar(BAD_ID, i, ATT_NAME(i,j), value);
          IF (err != NC_EBADID) 
            error("bad ncid: status = %d", err);
          err = nc_get_att_schar(ncid, BAD_VARID, ATT_NAME(i,j), value);
          IF (err != NC_ENOTVAR) 
            error("bad var id: status = %d", err);
          err = nc_get_att_schar(ncid, i, "noSuch", value);
          IF (err != NC_ENOTATT) 
            error("Bad attribute name: status = %d", err);
          allInExtRange = allInIntRange = 1;
            for (k = 0; k < ATT_LEN(i,j); k++) {
            expect[k] = hash4(ATT_TYPE(i,j), -1, &k, NCT_SCHAR);
                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_SCHAR)) {
                    allInIntRange = allInIntRange && expect[k] >= schar_min
                                && expect[k] <= schar_max;
                } else {
                    allInExtRange = 0;
                }
          }
          err = nc_get_att_schar(ncid, i, ATT_NAME(i,j), value);
            if (canConvert || ATT_LEN(i,j) == 0) {
                if (allInExtRange) {
                    if (allInIntRange) {
                        IF (err)
                            error("%s", nc_strerror(err));
                    } else {
                        IF (err != NC_ERANGE)
                            error("Range error: status = %d", err);
                    }
                } else {
                    IF (err != 0 && err != NC_ERANGE)
                        error("OK or Range error: status = %d", err);
                }
            for (k = 0; k < ATT_LEN(i,j); k++) {
                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_SCHAR)
                            && expect[k] >= schar_min && expect[k] <= schar_max) {
                  IF (!equal(value[k],expect[k],ATT_TYPE(i,j),
                        NCT_SCHAR)){
                      error("value read not that expected");
                            if (verbose) {
                                error("\n");
                                error("varid: %d, ", i);
                                error("att_name: %s, ", ATT_NAME(i,j));
                                error("element number: %d ", k);
                                error("expect: %g", expect[k]);
                                error("got: %g", (double) value[k]);
                            }
                  } else {
                      nok++;
                        }
                }
            }
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
      }
    }

    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_att_short(void)
{
    int ncid;
    int i;
    int j;
    size_t k;
    int err;
    int allInExtRange;
    int allInIntRange;
    int canConvert;     /* Both text or both numeric */
    short value[MAX_NELS];
    double expect[MAX_NELS];
    int nok = 0;      /* count of valid comparisons */

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err) 
      error("nc_open: %s", nc_strerror(err));

    for (i = -1; i < NVARS; i++) {
        for (j = 0; j < NATTS(i); j++) {
          canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_SHORT == NCT_TEXT);
          err = nc_get_att_short(BAD_ID, i, ATT_NAME(i,j), value);
          IF (err != NC_EBADID) 
            error("bad ncid: status = %d", err);
          err = nc_get_att_short(ncid, BAD_VARID, ATT_NAME(i,j), value);
          IF (err != NC_ENOTVAR) 
            error("bad var id: status = %d", err);
          err = nc_get_att_short(ncid, i, "noSuch", value);
          IF (err != NC_ENOTATT) 
            error("Bad attribute name: status = %d", err);
          allInExtRange = allInIntRange = 1;
            for (k = 0; k < ATT_LEN(i,j); k++) {
            expect[k] = hash4(ATT_TYPE(i,j), -1, &k, NCT_SHORT);
                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_SHORT)) {
                    allInIntRange = allInIntRange && expect[k] >= short_min
                                && expect[k] <= short_max;
                } else {
                    allInExtRange = 0;
                }
          }
          err = nc_get_att_short(ncid, i, ATT_NAME(i,j), value);
            if (canConvert || ATT_LEN(i,j) == 0) {
                if (allInExtRange) {
                    if (allInIntRange) {
                        IF (err)
                            error("%s", nc_strerror(err));
                    } else {
                        IF (err != NC_ERANGE)
                            error("Range error: status = %d", err);
                    }
                } else {
                    IF (err != 0 && err != NC_ERANGE)
                        error("OK or Range error: status = %d", err);
                }
            for (k = 0; k < ATT_LEN(i,j); k++) {
                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_SHORT)
                            && expect[k] >= short_min && expect[k] <= short_max) {
                  IF (!equal(value[k],expect[k],ATT_TYPE(i,j),
                        NCT_SHORT)){
                      error("value read not that expected");
                            if (verbose) {
                                error("\n");
                                error("varid: %d, ", i);
                                error("att_name: %s, ", ATT_NAME(i,j));
                                error("element number: %d ", k);
                                error("expect: %g", expect[k]);
                                error("got: %g", (double) value[k]);
                            }
                  } else {
                      nok++;
                        }
                }
            }
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
      }
    }

    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_att_int(void)
{
    int ncid;
    int i;
    int j;
    size_t k;
    int err;
    int allInExtRange;
    int allInIntRange;
    int canConvert;     /* Both text or both numeric */
    int value[MAX_NELS];
    double expect[MAX_NELS];
    int nok = 0;      /* count of valid comparisons */

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err) 
      error("nc_open: %s", nc_strerror(err));

    for (i = -1; i < NVARS; i++) {
        for (j = 0; j < NATTS(i); j++) {
          canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_INT == NCT_TEXT);
          err = nc_get_att_int(BAD_ID, i, ATT_NAME(i,j), value);
          IF (err != NC_EBADID) 
            error("bad ncid: status = %d", err);
          err = nc_get_att_int(ncid, BAD_VARID, ATT_NAME(i,j), value);
          IF (err != NC_ENOTVAR) 
            error("bad var id: status = %d", err);
          err = nc_get_att_int(ncid, i, "noSuch", value);
          IF (err != NC_ENOTATT) 
            error("Bad attribute name: status = %d", err);
          allInExtRange = allInIntRange = 1;
            for (k = 0; k < ATT_LEN(i,j); k++) {
            expect[k] = hash4(ATT_TYPE(i,j), -1, &k, NCT_INT);
                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_INT)) {
                    allInIntRange = allInIntRange && expect[k] >= int_min
                                && expect[k] <= int_max;
                } else {
                    allInExtRange = 0;
                }
          }
          err = nc_get_att_int(ncid, i, ATT_NAME(i,j), value);
            if (canConvert || ATT_LEN(i,j) == 0) {
                if (allInExtRange) {
                    if (allInIntRange) {
                        IF (err)
                            error("%s", nc_strerror(err));
                    } else {
                        IF (err != NC_ERANGE)
                            error("Range error: status = %d", err);
                    }
                } else {
                    IF (err != 0 && err != NC_ERANGE)
                        error("OK or Range error: status = %d", err);
                }
            for (k = 0; k < ATT_LEN(i,j); k++) {
                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_INT)
                            && expect[k] >= int_min && expect[k] <= int_max) {
                  IF (!equal(value[k],expect[k],ATT_TYPE(i,j),
                        NCT_INT)){
                      error("value read not that expected");
                            if (verbose) {
                                error("\n");
                                error("varid: %d, ", i);
                                error("att_name: %s, ", ATT_NAME(i,j));
                                error("element number: %d ", k);
                                error("expect: %g", expect[k]);
                                error("got: %g", (double) value[k]);
                            }
                  } else {
                      nok++;
                        }
                }
            }
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
      }
    }

    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_att_long(void)
{
    int ncid;
    int i;
    int j;
    size_t k;
    int err;
    int allInExtRange;
    int allInIntRange;
    int canConvert;     /* Both text or both numeric */
    long value[MAX_NELS];
    double expect[MAX_NELS];
    int nok = 0;      /* count of valid comparisons */

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err) 
      error("nc_open: %s", nc_strerror(err));

    for (i = -1; i < NVARS; i++) {
        for (j = 0; j < NATTS(i); j++) {
          canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_LONG == NCT_TEXT);
          err = nc_get_att_long(BAD_ID, i, ATT_NAME(i,j), value);
          IF (err != NC_EBADID) 
            error("bad ncid: status = %d", err);
          err = nc_get_att_long(ncid, BAD_VARID, ATT_NAME(i,j), value);
          IF (err != NC_ENOTVAR) 
            error("bad var id: status = %d", err);
          err = nc_get_att_long(ncid, i, "noSuch", value);
          IF (err != NC_ENOTATT) 
            error("Bad attribute name: status = %d", err);
          allInExtRange = allInIntRange = 1;
            for (k = 0; k < ATT_LEN(i,j); k++) {
            expect[k] = hash4(ATT_TYPE(i,j), -1, &k, NCT_LONG);
                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_LONG)) {
                    allInIntRange = allInIntRange && expect[k] >= long_min
                                && expect[k] <= long_max;
                } else {
                    allInExtRange = 0;
                }
          }
          err = nc_get_att_long(ncid, i, ATT_NAME(i,j), value);
            if (canConvert || ATT_LEN(i,j) == 0) {
                if (allInExtRange) {
                    if (allInIntRange) {
                        IF (err)
                            error("%s", nc_strerror(err));
                    } else {
                        IF (err != NC_ERANGE)
                            error("Range error: status = %d", err);
                    }
                } else {
                    IF (err != 0 && err != NC_ERANGE)
                        error("OK or Range error: status = %d", err);
                }
            for (k = 0; k < ATT_LEN(i,j); k++) {
                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_LONG)
                            && expect[k] >= long_min && expect[k] <= long_max) {
                  IF (!equal(value[k],expect[k],ATT_TYPE(i,j),
                        NCT_LONG)){
                      error("value read not that expected");
                            if (verbose) {
                                error("\n");
                                error("varid: %d, ", i);
                                error("att_name: %s, ", ATT_NAME(i,j));
                                error("element number: %d ", k);
                                error("expect: %g", expect[k]);
                                error("got: %g", (double) value[k]);
                            }
                  } else {
                      nok++;
                        }
                }
            }
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
      }
    }

    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_att_float(void)
{
    int ncid;
    int i;
    int j;
    size_t k;
    int err;
    int allInExtRange;
    int allInIntRange;
    int canConvert;     /* Both text or both numeric */
    float value[MAX_NELS];
    double expect[MAX_NELS];
    int nok = 0;      /* count of valid comparisons */

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err) 
      error("nc_open: %s", nc_strerror(err));

    for (i = -1; i < NVARS; i++) {
        for (j = 0; j < NATTS(i); j++) {
          canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_FLOAT == NCT_TEXT);
          err = nc_get_att_float(BAD_ID, i, ATT_NAME(i,j), value);
          IF (err != NC_EBADID) 
            error("bad ncid: status = %d", err);
          err = nc_get_att_float(ncid, BAD_VARID, ATT_NAME(i,j), value);
          IF (err != NC_ENOTVAR) 
            error("bad var id: status = %d", err);
          err = nc_get_att_float(ncid, i, "noSuch", value);
          IF (err != NC_ENOTATT) 
            error("Bad attribute name: status = %d", err);
          allInExtRange = allInIntRange = 1;
            for (k = 0; k < ATT_LEN(i,j); k++) {
            expect[k] = hash4(ATT_TYPE(i,j), -1, &k, NCT_FLOAT);
                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_FLOAT)) {
                    allInIntRange = allInIntRange && expect[k] >= float_min
                                && expect[k] <= float_max;
                } else {
                    allInExtRange = 0;
                }
          }
          err = nc_get_att_float(ncid, i, ATT_NAME(i,j), value);
            if (canConvert || ATT_LEN(i,j) == 0) {
                if (allInExtRange) {
                    if (allInIntRange) {
                        IF (err)
                            error("%s", nc_strerror(err));
                    } else {
                        IF (err != NC_ERANGE)
                            error("Range error: status = %d", err);
                    }
                } else {
                    IF (err != 0 && err != NC_ERANGE)
                        error("OK or Range error: status = %d", err);
                }
            for (k = 0; k < ATT_LEN(i,j); k++) {
                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_FLOAT)
                            && expect[k] >= float_min && expect[k] <= float_max) {
                  IF (!equal(value[k],expect[k],ATT_TYPE(i,j),
                        NCT_FLOAT)){
                      error("value read not that expected");
                            if (verbose) {
                                error("\n");
                                error("varid: %d, ", i);
                                error("att_name: %s, ", ATT_NAME(i,j));
                                error("element number: %d ", k);
                                error("expect: %g", expect[k]);
                                error("got: %g", (double) value[k]);
                            }
                  } else {
                      nok++;
                        }
                }
            }
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
      }
    }

    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}

void
test_nc_get_att_double(void)
{
    int ncid;
    int i;
    int j;
    size_t k;
    int err;
    int allInExtRange;
    int allInIntRange;
    int canConvert;     /* Both text or both numeric */
    double value[MAX_NELS];
    double expect[MAX_NELS];
    int nok = 0;      /* count of valid comparisons */

    err = nc_open(testfile, NC_NOWRITE, &ncid);
    IF (err) 
      error("nc_open: %s", nc_strerror(err));

    for (i = -1; i < NVARS; i++) {
        for (j = 0; j < NATTS(i); j++) {
          canConvert = (ATT_TYPE(i,j) == NC_CHAR) == (NCT_DOUBLE == NCT_TEXT);
          err = nc_get_att_double(BAD_ID, i, ATT_NAME(i,j), value);
          IF (err != NC_EBADID) 
            error("bad ncid: status = %d", err);
          err = nc_get_att_double(ncid, BAD_VARID, ATT_NAME(i,j), value);
          IF (err != NC_ENOTVAR) 
            error("bad var id: status = %d", err);
          err = nc_get_att_double(ncid, i, "noSuch", value);
          IF (err != NC_ENOTATT) 
            error("Bad attribute name: status = %d", err);
          allInExtRange = allInIntRange = 1;
            for (k = 0; k < ATT_LEN(i,j); k++) {
            expect[k] = hash4(ATT_TYPE(i,j), -1, &k, NCT_DOUBLE);
                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_DOUBLE)) {
                    allInIntRange = allInIntRange && expect[k] >= double_min
                                && expect[k] <= double_max;
                } else {
                    allInExtRange = 0;
                }
          }
          err = nc_get_att_double(ncid, i, ATT_NAME(i,j), value);
            if (canConvert || ATT_LEN(i,j) == 0) {
                if (allInExtRange) {
                    if (allInIntRange) {
                        IF (err)
                            error("%s", nc_strerror(err));
                    } else {
                        IF (err != NC_ERANGE)
                            error("Range error: status = %d", err);
                    }
                } else {
                    IF (err != 0 && err != NC_ERANGE)
                        error("OK or Range error: status = %d", err);
                }
            for (k = 0; k < ATT_LEN(i,j); k++) {
                if (inRange3(expect[k],ATT_TYPE(i,j),NCT_DOUBLE)
                            && expect[k] >= double_min && expect[k] <= double_max) {
                  IF (!equal(value[k],expect[k],ATT_TYPE(i,j),
                        NCT_DOUBLE)){
                      error("value read not that expected");
                            if (verbose) {
                                error("\n");
                                error("varid: %d, ", i);
                                error("att_name: %s, ", ATT_NAME(i,j));
                                error("element number: %d ", k);
                                error("expect: %g", expect[k]);
                                error("got: %g", (double) value[k]);
                            }
                  } else {
                      nok++;
                        }
                }
            }
          } else {
            IF (err != NC_ECHAR)
                error("wrong type: status = %d", err);
          }
      }
    }

    err = nc_close(ncid);
    IF (err)
      error("nc_close: %s", nc_strerror(err));
    print_nok(nok);
}



Generated by  Doxygen 1.6.0   Back to index