Esempio n. 1
0
static int read_variable(harp_product *product, int ncid, int varid, netcdf_dimensions *dimensions)
{
    harp_variable *variable;
    harp_data_type data_type;
    int num_dimensions;
    harp_dimension_type dimension_type[HARP_MAX_NUM_DIMS];
    long dimension[HARP_MAX_NUM_DIMS];
    char netcdf_name[NC_MAX_NAME + 1];
    nc_type netcdf_data_type;
    int netcdf_num_dimensions;
    int netcdf_dim_id[NC_MAX_VAR_DIMS];
    int result;
    long i;

    result = nc_inq_var(ncid, varid, netcdf_name, &netcdf_data_type, &netcdf_num_dimensions, netcdf_dim_id, NULL);
    if (result != NC_NOERR)
    {
        harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
        return -1;
    }

    if (get_harp_type(netcdf_data_type, &data_type) != 0)
    {
        harp_add_error_message(" (variable '%s')", netcdf_name);
        return -1;
    }

    num_dimensions = netcdf_num_dimensions;

    if (data_type == harp_type_string)
    {
        if (num_dimensions == 0)
        {
            harp_set_error(HARP_ERROR_IMPORT, "variable '%s' of type '%s' has 0 dimensions; expected >= 1",
                           netcdf_name, harp_get_data_type_name(harp_type_string));
        }

        if (dimensions->type[netcdf_dim_id[num_dimensions - 1]] != netcdf_dimension_string)
        {
            harp_set_error(HARP_ERROR_IMPORT, "inner-most dimension of variable '%s' is of type '%s'; expected '%s'",
                           netcdf_name, get_dimension_type_name(dimensions->type[netcdf_dim_id[num_dimensions - 1]]),
                           get_dimension_type_name(netcdf_dimension_string));
            return -1;
        }

        num_dimensions--;
    }

    if (num_dimensions > HARP_MAX_NUM_DIMS)
    {
        harp_set_error(HARP_ERROR_IMPORT, "variable '%s' has too many dimensions", netcdf_name);
        return -1;
    }

    for (i = 0; i < num_dimensions; i++)
    {
        if (get_harp_dimension_type(dimensions->type[netcdf_dim_id[i]], &dimension_type[i]) != 0)
        {
            harp_add_error_message(" (variable '%s')", netcdf_name);
            return -1;
        }
    }

    for (i = 0; i < num_dimensions; i++)
    {
        dimension[i] = dimensions->length[netcdf_dim_id[i]];
    }

    if (harp_variable_new(netcdf_name, data_type, num_dimensions, dimension_type, dimension, &variable) != 0)
    {
        return -1;
    }

    if (harp_product_add_variable(product, variable) != 0)
    {
        harp_variable_delete(variable);
        return -1;
    }

    /* Read data. */
    if (data_type == harp_type_string)
    {
        char *buffer;
        long length;

        assert(netcdf_num_dimensions > 0);
        length = dimensions->length[netcdf_dim_id[netcdf_num_dimensions - 1]];

        buffer = malloc(variable->num_elements * length * sizeof(char));
        if (buffer == NULL)
        {
            harp_set_error(HARP_ERROR_OUT_OF_MEMORY, "out of memory (could not allocate %lu bytes) (%s:%u)",
                           variable->num_elements * length * sizeof(char), __FILE__, __LINE__);
            return -1;
        }

        result = nc_get_var_text(ncid, varid, buffer);
        if (result != NC_NOERR)
        {
            harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
            free(buffer);
            return -1;
        }

        for (i = 0; i < variable->num_elements; i++)
        {
            char *str;

            str = malloc((length + 1) * sizeof(char));
            if (str == NULL)
            {
                harp_set_error(HARP_ERROR_OUT_OF_MEMORY, "out of memory (could not allocate %lu bytes) (%s:%u)",
                               (length + 1) * sizeof(char), __FILE__, __LINE__);
                free(buffer);
                return -1;
            }

            memcpy(str, &buffer[i * length], length);
            str[length] = '\0';
            variable->data.string_data[i] = str;
        }

        free(buffer);
    }
    else
    {
        switch (data_type)
        {
            case harp_type_int8:
                result = nc_get_var_schar(ncid, varid, variable->data.int8_data);
                break;
            case harp_type_int16:
                result = nc_get_var_short(ncid, varid, variable->data.int16_data);
                break;
            case harp_type_int32:
                result = nc_get_var_int(ncid, varid, variable->data.int32_data);
                break;
            case harp_type_float:
                result = nc_get_var_float(ncid, varid, variable->data.float_data);
                break;
            case harp_type_double:
                result = nc_get_var_double(ncid, varid, variable->data.double_data);
                break;
            default:
                assert(0);
                exit(1);
        }

        if (result != NC_NOERR)
        {
            harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
            return -1;
        }
    }

    /* Read attributes. */
    result = nc_inq_att(ncid, varid, "description", NULL, NULL);
    if (result == NC_NOERR)
    {
        if (read_string_attribute(ncid, varid, "description", &variable->description) != 0)
        {
            harp_add_error_message(" (variable '%s')", netcdf_name);
            return -1;
        }
    }
    else if (result != NC_ENOTATT)
    {
        harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
        return -1;
    }

    result = nc_inq_att(ncid, varid, "units", NULL, NULL);
    if (result == NC_NOERR)
    {
        if (read_string_attribute(ncid, varid, "units", &variable->unit) != 0)
        {
            harp_add_error_message(" (variable '%s')", netcdf_name);
            return -1;
        }
    }
    else if (result != NC_ENOTATT)
    {
        harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
        return -1;
    }

    result = nc_inq_att(ncid, varid, "valid_min", NULL, NULL);
    if (result == NC_NOERR)
    {
        harp_data_type attr_data_type;

        if (read_numeric_attribute(ncid, varid, "valid_min", &attr_data_type, &variable->valid_min) != 0)
        {
            harp_add_error_message(" (variable '%s')", netcdf_name);
            return -1;
        }

        if (attr_data_type != data_type)
        {
            harp_set_error(HARP_ERROR_IMPORT, "attribute 'valid_min' of variable '%s' has invalid type", netcdf_name);
            return -1;
        }
    }
    else if (result != NC_ENOTATT)
    {
        harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
        return -1;
    }

    result = nc_inq_att(ncid, varid, "valid_max", NULL, NULL);
    if (result == NC_NOERR)
    {
        harp_data_type attr_data_type;

        if (read_numeric_attribute(ncid, varid, "valid_max", &attr_data_type, &variable->valid_max) != 0)
        {
            harp_add_error_message(" (variable '%s')", netcdf_name);
            return -1;
        }

        if (attr_data_type != data_type)
        {
            harp_set_error(HARP_ERROR_IMPORT, "attribute 'valid_max' of variable '%s' has invalid type", netcdf_name);
            return -1;
        }
    }
    else if (result != NC_ENOTATT)
    {
        harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
        return -1;
    }

    return 0;
}
Esempio n. 2
0
int main()
{
    int ncid, varid;
    int ncstat = NC_NOERR;
    char* url;
    char* topsrcdir;
    size_t len;
#ifndef USE_NETCDF4
    int i,j;
#endif

    /* location of our target url: use file:// to avoid remote
	server downtime issues
     */

    /* Assume that TESTS_ENVIRONMENT was set */
    topsrcdir = getenv("TOPSRCDIR");
    if(topsrcdir == NULL) {
        fprintf(stderr,"*** FAIL: $abs_top_srcdir not defined: location= %s:%d\n",__FILE__,__LINE__);
        exit(1);
    }
    len = strlen("file://") + strlen(topsrcdir) + strlen("/ncdap_test/testdata3/test.02") + 1;
#ifdef DEBUG
    len += strlen("[log][show=fetch]");
#endif
    url = (char*)malloc(len);
    url[0] = '\0';

#ifdef DEBUG
    strcat(url,"[log][show=fetch]");
#endif

    strcat(url,"file://");
    strcat(url,topsrcdir);
    strcat(url,"/ncdap_test/testdata3/test.02");

    printf("*** Test: var conversions on URL: %s\n",url);

    /* open file, get varid */
    CHECK(nc_open(url, NC_NOWRITE, &ncid));
    /* extract the string case for netcdf-3*/
#ifndef USE_NETCDF4
    CHECK(nc_inq_varid(ncid, "s", &varid));
    CHECK(nc_get_var_text(ncid,varid,(char*)string3));
#ifdef GENERATE
    printf("static %s string3_data[DIMSIZE][STRLEN]={","char");
    for(i=0;i<DIMSIZE;i++) {
	int j;
	/* Do simple escape */
	for(j=0;j<STRLEN;j++) {
	    if(string3[i][j] > 0
	       && string3[i][j] != '\n'
	       && string3[i][j] != '\r'
	       && string3[i][j] != '\t'
	       &&(string3[i][j] < ' ' || string3[i][j] >= '\177'))
		string3[i][j] = '?';
	}
	printf("%s\"%s\"",COMMA,string3[i]);
    }
    printf("};\n");
#else
 	fprintf(stdout,"*** testing: %s\n","string3");
	for(i=0;i<DIMSIZE;i++) {
   	    for(j=0;j<STRLEN;j++) {
	        if(string3[i][j] != string3_data[i][j]) {report(i,"string3",__LINE__); break;}
	    }
	}
#endif
#endif

    CHECK(nc_inq_varid(ncid, "b", &varid));
    CHECK(nc_get_var_text(ncid,varid,ch));
#ifdef GENERATE
    printf("static %s ch_data[DIMSIZE]={","char");
    for(i=0;i<DIMSIZE;i++) printf("%s'\\%03hho'",COMMA,ch[i]);
    printf("};\n");
#else
    COMPARE(NC_CHAR,NC_CHAR,ch,ch_data);
#endif

    CHECK(nc_inq_varid(ncid, "b", &varid));
    CHECK(nc_get_var_schar(ncid,varid,int8v));
#ifdef GENERATE
    printf("static %s int8_data[DIMSIZE]={","signed char");
    for(i=0;i<DIMSIZE;i++) printf("%s%hhd",COMMA,int8v[i]);
    printf("};\n");
#else
    COMPARE(NC_BYTE,NC_BYTE,int8v,int8_data);
#endif

    CHECK(nc_inq_varid(ncid, "b", &varid));
    CHECK(nc_get_var_uchar(ncid,varid,uint8v));
#ifdef GENERATE
    printf("static %s uint8_data[DIMSIZE]={","unsigned char");
    for(i=0;i<DIMSIZE;i++) printf("%s%hhu",COMMA,uint8v[i]);
    printf("};\n");
#else
    COMPARE(NC_UBYTE,NC_UBYTE,uint8v,uint8_data);
#endif

    CHECK(nc_inq_varid(ncid, "b", &varid));
    CHECK(nc_get_var_int(ncid,varid,int32v));
#ifdef GENERATE
    printf("static %s int8toint32_data[DIMSIZE]={","int");
    for(i=0;i<DIMSIZE;i++) printf("%s%d",COMMA,int32v[i]);
    printf("};\n");
#else
    COMPARE(NC_BYTE,NC_INT,int32v,int8toint32_data);
#endif

    CHECK(nc_inq_varid(ncid, "b", &varid));
    CHECK(nc_get_var_float(ncid,varid,float32v));
#ifdef GENERATE
    printf("static %s int82float32_data[DIMSIZE]={","float");
    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32v[i]);
    printf("};\n");
#else
    COMPARE(NC_FLOAT,NC_FLOAT,float32v,int82float32_data);
#endif

    CHECK(nc_inq_varid(ncid, "i16", &varid));
    CHECK(nc_get_var_short(ncid,varid,int16v));
#ifdef GENERATE
    printf("static %s int16_data[DIMSIZE]={","short");
    for(i=0;i<DIMSIZE;i++) printf("%s%hd",COMMA,int16v[i]);
    printf("};\n");
#else
    COMPARE(NC_SHORT,NC_SHORT,int16v,int16_data);
#endif

    CHECK(nc_inq_varid(ncid, "i16", &varid));
    CHECK(nc_get_var_int(ncid,varid,int32v));
#ifdef GENERATE
    printf("static %s int16toint32_data[DIMSIZE]={","int");
    for(i=0;i<DIMSIZE;i++) printf("%s%d",COMMA,int32v[i]);
    printf("};\n");
#else
    COMPARE(NC_SHORT,NC_INT,int32v,int16toint32_data);
#endif

    CHECK(nc_inq_varid(ncid, "i16", &varid));
    CHECK(nc_get_var_float(ncid,varid,float32v));
#ifdef GENERATE
    printf("static %s int162float32_data[DIMSIZE]={","float");
    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32v[i]);
    printf("};\n");
#else
    COMPARE(NC_SHORT,NC_FLOAT,float32v,int162float32_data);
#endif

    CHECK(nc_inq_varid(ncid, "i32", &varid));
    CHECK(nc_get_var_int(ncid,varid,int32v));
#ifdef GENERATE
    printf("static %s int32_data[DIMSIZE]={","int");
    for(i=0;i<DIMSIZE;i++) printf("%s%d",COMMA,int32v[i]);
    printf("};\n");
#else
    COMPARE(NC_INT,NC_INT,int32v,int32_data);
#endif

    CHECK(nc_inq_varid(ncid, "i32", &varid));
    CHECK(nc_get_var_float(ncid,varid,float32v));
#ifdef GENERATE
    printf("static %s int32tofloat32_data[DIMSIZE]={","float");
    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32v[i]);
    printf("};\n");
#else
    COMPARE(NC_INT,NC_FLOAT,float32v,int32tofloat32_data);
#endif

    CHECK(nc_inq_varid(ncid, "i32", &varid));
    CHECK(nc_get_var_long(ncid,varid,ilong));
#ifdef GENERATE
    printf("static %s int32toilong_data[DIMSIZE]={","long");
    for(i=0;i<DIMSIZE;i++) printf("%s%ld",COMMA,ilong[i]);
    printf("};\n");
#else
    COMPARE(NC_INT,NC_NAT,ilong,int32toilong_data);
#endif

    CHECK(nc_inq_varid(ncid, "f32", &varid));
    CHECK(nc_get_var_float(ncid,varid,float32v));
#ifdef GENERATE
    printf("static %s float32_data[DIMSIZE]={","float");
    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32v[i]);
    printf("};\n");
#else
    COMPARE(NC_FLOAT,NC_FLOAT,float32v,float32_data);
#endif

    CHECK(nc_inq_varid(ncid, "f64", &varid));
    CHECK(nc_get_var_double(ncid,varid,float64v));
#ifdef GENERATE
    printf("static %s float64_data[DIMSIZE]={","double");
    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float64v[i]);
    printf("};\n");
#else
    COMPARE(NC_DOUBLE,NC_DOUBLE,float64v,float64_data);
#endif

    if(failure) {
        printf("ncstat=%d %s",ncstat,nc_strerror(ncstat));
        exit(1);
    }
    return 0;
}
Esempio n. 3
0
int
check_file(int format, unsigned char *uchar_out)
{
   int ncid;
   int ndims, natts;
   int dimids_var[1], var_type;
   char var_name[NC_MAX_NAME+1];
   unsigned char uchar_in[DIM1_LEN];
   signed char char_in[DIM1_LEN];
   unsigned short ushort_in[DIM1_LEN];
   short short_in[DIM1_LEN];
   unsigned int uint_in[DIM1_LEN];
   int int_in[DIM1_LEN];
   long long int64_in[DIM1_LEN];
   unsigned long long uint64_in[DIM1_LEN];
   int i, res;

   /* Read it back in, and check conversions. */
   if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
   if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
   if (strcmp(var_name, VAR1_NAME) || natts !=0 || ndims != 1 ||
       dimids_var[0] != 0 || var_type != NC_BYTE) ERR;

   /* This is actually an NC_BYTE, with some negatives, so this should
    * generate a range error for netcdf-4, but not for netcdf-3,
    * because range errors are not generated for byte type
    * conversions. */
   res = nc_get_var_uchar(ncid, 0, uchar_in);
   if (format == NC_FORMAT_NETCDF4 || format == NC_FORMAT_64BIT_DATA)
   {
      if (res != NC_ERANGE) ERR;
   }
   else if (res) ERR;

   for (i=0; i<DIM1_LEN; i++)
#ifdef ERANGE_FILL
      if (uchar_in[i] != uchar_out[i] && uchar_in[i] != NC_FILL_UBYTE) ERR;
#else
      if (uchar_in[i] != uchar_out[i]) ERR;
#endif

   if (nc_get_var_schar(ncid, 0, char_in)) ERR;
   for (i=0; i<DIM1_LEN; i++)
#ifdef ERANGE_FILL
      if (char_in[i] != (signed char)uchar_out[i] && char_in[i] != NC_FILL_BYTE) ERR;
#else
      if (char_in[i] != (signed char)uchar_out[i]) ERR;
#endif

   if (nc_get_var_short(ncid, 0, short_in)) ERR;
   for (i=0; i<DIM1_LEN; i++)
#ifdef ERANGE_FILL
      if (short_in[i] != (signed char)uchar_out[i] && short_in[i] != NC_FILL_BYTE) ERR;
#else
      if (short_in[i] != (signed char)uchar_out[i]) ERR;
#endif

   if (nc_get_var_int(ncid, 0, int_in)) ERR;
   for (i=0; i<DIM1_LEN; i++)
#ifdef ERANGE_FILL
      if (int_in[i] != (signed char)uchar_out[i] && int_in[i] != NC_FILL_BYTE) ERR;
#else
      if (int_in[i] != (signed char)uchar_out[i]) ERR;
#endif

   if (format == NC_FORMAT_NETCDF4 || format == NC_FORMAT_NETCDF4_CLASSIC)
   {
      /* Since we wrote them as NC_BYTE, some of these are negative
       * values, and will return a range error when reading into
       * unsigned type. To compare values, first cast uchar_out to
       * signed int, then cast again to the type we are reading it
       * as. */
      if (nc_get_var_ushort(ncid, 0, ushort_in) != NC_ERANGE) ERR;
      for (i=0; i<DIM1_LEN; i++)
	 if (ushort_in[i] != (unsigned short)(signed char)uchar_out[i]) ERR;

      if (nc_get_var_uint(ncid, 0, uint_in) != NC_ERANGE) ERR;
      for (i=0; i<DIM1_LEN; i++)
	 if (uint_in[i] != (unsigned int)(signed char)uchar_out[i]) ERR;

      if (nc_get_var_ulonglong(ncid, 0, uint64_in) != NC_ERANGE) ERR;
      for (i=0; i<DIM1_LEN; i++)
	 if (uint64_in[i] != (unsigned long long)(signed char)uchar_out[i]) ERR;

      if (nc_get_var_longlong(ncid, 0, int64_in)) ERR;
      for (i=0; i<DIM1_LEN; i++)
	 if (int64_in[i] != (signed char)uchar_out[i]) ERR;

   }

   if (nc_close(ncid)) ERR;
   return 0;
}
Esempio n. 4
0
int
main(int argc, char **argv)
{
#ifdef USE_PARALLEL
   MPI_Init(&argc, &argv);
#endif

   int ncid, dimids[3];
   int char_varid, byte_varid, ubyte_varid, short_varid, int_varid, float_varid, double_varid;
   int ushort_varid, uint_varid, int64_varid, uint64_varid;
   int i, j;

   unsigned char ubyte_out[DIM1_LEN][DIM2_LEN] = {{1, 128, 255},{1, 128, 255}};
   signed char byte_in[DIM1_LEN][DIM2_LEN], byte_out[DIM1_LEN][DIM2_LEN] = {{-127, 1, 127},{-127, 1, 127}};
   unsigned short ushort_out[DIM1_LEN][DIM2_LEN] = {{110, 128, 255},{110, 128, 255}};
   short short_in[DIM1_LEN][DIM2_LEN], short_out[DIM1_LEN][DIM2_LEN] = {{-110, -128, 255},{-110, -128, 255}};
   int int_in[DIM1_LEN][DIM2_LEN], int_out[DIM1_LEN][DIM2_LEN] = {{0, 128, 255},{0, 128, 255}};
   float float_in[DIM1_LEN][DIM2_LEN], float_out[DIM1_LEN][DIM2_LEN] = {{-.1, 9999.99, 100.001},{-.1, 9999.99, 100.001}};
   double double_in[DIM1_LEN][DIM2_LEN], double_out[DIM1_LEN][DIM2_LEN] = {{0.02, .1128, 1090.1},{0.02, .1128, 1090.1}};
   unsigned int uint_in[DIM1_LEN][DIM2_LEN], uint_out[DIM1_LEN][DIM2_LEN] = {{0, 128, 255},{0, 128, 255}};
   long long int64_in[DIM1_LEN][DIM2_LEN], int64_out[DIM1_LEN][DIM2_LEN] = {{-111, 777, 100},{-111, 777, 100}};
   unsigned long long uint64_in[DIM1_LEN][DIM2_LEN];
   unsigned long long uint64_out[DIM1_LEN][DIM2_LEN] = {{0, 10101, 9999999},{0, 10101, 9999999}};
   char char_out[DIM1_LEN][DIM2_LEN][DIM3_LEN] = {{"lalala", "lololo", "lelele"}, {"lalala", "lololo", "lelele"}};

   /*nc_set_log_level(4);*/

   printf("\n*** Testing netcdf-4 variable functions.\n");

   printf("*** testing netcdf-4 varids inq on netcdf-3 file...");
   {
      int nvars_in, varids_in[2];

      /* Create a netcdf-3 file with one dim and two vars. */
      if (nc_create(FILE_NAME, 0, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
      if (nc_def_dim(ncid, DIM3_NAME, DIM3_LEN, &dimids[2])) ERR;
      if (nc_def_var(ncid, VAR_BYTE_NAME, NC_BYTE, 2, dimids, &byte_varid)) ERR;
      if (nc_def_var(ncid, VAR_CHAR_NAME, NC_CHAR, 3, dimids, &char_varid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and make sure nc_inq_varids yeilds correct
       * result. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
      if (nvars_in != 2 || varids_in[0] != 0 || varids_in[1] != 1) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing simple variables...");

   {      
      /* Create a file with a variable of each type. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
      if (nc_def_dim(ncid, DIM3_NAME, DIM3_LEN, &dimids[2])) ERR;
      if (nc_def_var(ncid, VAR_BYTE_NAME, NC_BYTE, 2, dimids, &byte_varid)) ERR;
      if (nc_def_var(ncid, VAR_CHAR_NAME, NC_CHAR, 3, dimids, &char_varid)) ERR;
      if (nc_def_var(ncid, VAR_SHORT_NAME, NC_SHORT, 2, dimids, &short_varid)) ERR;
      if (nc_def_var(ncid, VAR_INT_NAME, NC_INT, 2, dimids, &int_varid)) ERR;
      if (nc_def_var(ncid, VAR_FLOAT_NAME, NC_FLOAT, 2, dimids, &float_varid)) ERR;
      if (nc_def_var(ncid, VAR_DOUBLE_NAME, NC_DOUBLE, 2, dimids, &double_varid)) ERR;
      if (nc_def_var(ncid, VAR_UBYTE_NAME, NC_UBYTE, 2, dimids, &ubyte_varid)) ERR;
      if (nc_def_var(ncid, VAR_USHORT_NAME, NC_USHORT, 2, dimids, &ushort_varid)) ERR;
      if (nc_def_var(ncid, VAR_UINT_NAME, NC_UINT, 2, dimids, &uint_varid)) ERR;
      if (nc_def_var(ncid, VAR_INT64_NAME, NC_INT64, 2, dimids, &int64_varid)) ERR;
      if (nc_def_var(ncid, VAR_UINT64_NAME, NC_UINT64, 2, dimids, &uint64_varid)) ERR;
      if (nc_put_var_schar(ncid, byte_varid, (signed char *)byte_out)) ERR;
      if (nc_put_var_text(ncid, char_varid, (char *)char_out)) ERR;
      if (nc_put_var_short(ncid, short_varid, (short *)short_out)) ERR;
      if (nc_put_var_int(ncid, int_varid, (int *)int_out)) ERR;
      if (nc_put_var_float(ncid, float_varid, (float *)float_out)) ERR;
      if (nc_put_var_double(ncid, double_varid, (double *)double_out)) ERR;
      if (nc_put_var_ubyte(ncid, ubyte_varid, (unsigned char *)ubyte_out)) ERR;
      if (nc_put_var_ushort(ncid, ushort_varid, (unsigned short *)ushort_out)) ERR;
      if (nc_put_var_uint(ncid, uint_varid, (unsigned int *)uint_out)) ERR;
      if (nc_put_var_longlong(ncid, int64_varid, (long long *)int64_out)) ERR;
      if (nc_put_var_ulonglong(ncid, uint64_varid, (unsigned long long *)uint64_out)) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and check metadata. */
      {
	 nc_type xtype_in;
	 int ndims_in, dimids_in[10], natts_in, varid_in;
	 char name_in[NC_MAX_NAME+1];

	 if (nc_open(FILE_NAME, 0, &ncid)) ERR;
	 if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, 
			&natts_in)) ERR;
	 if (strcmp(name_in, VAR_BYTE_NAME) || xtype_in != NC_BYTE || 
	     ndims_in != 2 || natts_in != 0 || dimids_in[0] != dimids[0] ||
	     dimids_in[1] != dimids[1]) ERR;
	 if (nc_inq_varid(ncid, VAR_BYTE_NAME, &varid_in)) ERR;
	 if (varid_in != 0) ERR;
	 if (nc_inq_varid(ncid, VAR_CHAR_NAME, &varid_in)) ERR;
	 if (varid_in != 1) ERR;
	 if (nc_inq_varid(ncid, VAR_SHORT_NAME, &varid_in)) ERR;
	 if (varid_in != 2) ERR;
	 if (nc_inq_varname(ncid, 0, name_in)) ERR;
	 if (strcmp(name_in, VAR_BYTE_NAME)) ERR;
	 if (nc_inq_varname(ncid, 1, name_in)) ERR;
	 if (strcmp(name_in, VAR_CHAR_NAME)) ERR;
	 if (nc_inq_varname(ncid, 2, name_in)) ERR;
	 if (strcmp(name_in, VAR_SHORT_NAME)) ERR;
	 if (nc_inq_vartype(ncid, 0, &xtype_in)) ERR;      
	 if (xtype_in != NC_BYTE) ERR;
	 if (nc_inq_vartype(ncid, 1, &xtype_in)) ERR;      
	 if (xtype_in != NC_CHAR) ERR;
	 if (nc_inq_vartype(ncid, 2, &xtype_in)) ERR;      
	 if (xtype_in != NC_SHORT) ERR;
	 if (nc_close(ncid)) ERR;
      }

      /* Open the file and check data. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_var_schar(ncid, byte_varid, (signed char *)byte_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != byte_out[i][j]) ERR;
      if (nc_get_var_short(ncid, short_varid, (short *)short_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (short_in[i][j] != short_out[i][j]) ERR;
      if (nc_get_var_int(ncid, int_varid, (int *)int_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (int_in[i][j] != int_out[i][j]) ERR;
      if (nc_get_var_float(ncid, float_varid, (float *)float_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (float_in[i][j] != float_out[i][j]) ERR;
      if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != double_out[i][j]) ERR;
      if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != double_out[i][j]) ERR;
      if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != double_out[i][j]) ERR;
      if (nc_get_var_uint(ncid, uint_varid, (unsigned int *)uint_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (uint_in[i][j] != uint_out[i][j]) ERR;
      if (nc_get_var_longlong(ncid, int64_varid, (long long *)int64_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (int64_in[i][j] != int64_out[i][j]) ERR;
      if (nc_get_var_ulonglong(ncid, uint64_varid, (unsigned long long *)uint64_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (uint64_in[i][j] != uint64_out[i][j]) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and read everything as double. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_var_double(ncid, byte_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)byte_out[i][j]) ERR;
      if (nc_get_var_double(ncid, ubyte_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)ubyte_out[i][j]) ERR;
      if (nc_get_var_double(ncid, short_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)short_out[i][j]) ERR;
      if (nc_get_var_double(ncid, ushort_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)ushort_out[i][j]) ERR;
      if (nc_get_var_double(ncid, int_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)int_out[i][j]) ERR;
      if (nc_get_var_double(ncid, uint_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)uint_out[i][j]) ERR;
      if (nc_get_var_double(ncid, float_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)float_out[i][j]) ERR;
      if (nc_get_var_double(ncid, int64_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)int64_out[i][j]) ERR;
      if (nc_get_var_double(ncid, uint64_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)uint64_out[i][j]) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and read everything as NC_BYTE. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_var_schar(ncid, byte_varid, (signed char *)byte_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)byte_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, ubyte_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)ubyte_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, short_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)short_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, ushort_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)ushort_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, int_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)int_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, uint_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)uint_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, float_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)float_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, int64_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)int64_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, uint64_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)uint64_out[i][j]) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;

#define DEFLATE_LEVEL_4 4

   printf("*** testing simple variables with deflation...");
   {
      /* Create a file with a variable of each type. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
      if (nc_def_dim(ncid, DIM3_NAME, DIM3_LEN, &dimids[2])) ERR;
      if (nc_def_var(ncid, VAR_BYTE_NAME, NC_BYTE, 2, dimids, &byte_varid)) ERR;
      if (nc_def_var_deflate(ncid, byte_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_CHAR_NAME, NC_CHAR, 3, dimids, &char_varid)) ERR;
      if (nc_def_var_deflate(ncid, byte_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_SHORT_NAME, NC_SHORT, 2, dimids, &short_varid)) ERR;
      if (nc_def_var_deflate(ncid, short_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_INT_NAME, NC_INT, 2, dimids, &int_varid)) ERR;
      if (nc_def_var_deflate(ncid, int_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_FLOAT_NAME, NC_FLOAT, 2, dimids, &float_varid)) ERR;
      if (nc_def_var_deflate(ncid, float_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_DOUBLE_NAME, NC_DOUBLE, 2, dimids, &double_varid)) ERR;
      if (nc_def_var_deflate(ncid, double_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_UBYTE_NAME, NC_UBYTE, 2, dimids, &ubyte_varid)) ERR;
      if (nc_def_var_deflate(ncid, ubyte_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_USHORT_NAME, NC_USHORT, 2, dimids, &ushort_varid)) ERR;
      if (nc_def_var_deflate(ncid, ushort_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_UINT_NAME, NC_UINT, 2, dimids, &uint_varid)) ERR;
      if (nc_def_var_deflate(ncid, uint_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_INT64_NAME, NC_INT64, 2, dimids, &int64_varid)) ERR;
      if (nc_def_var_deflate(ncid, int64_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_UINT64_NAME, NC_UINT64, 2, dimids, &uint64_varid)) ERR;
      if (nc_def_var_deflate(ncid, uint64_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;

      if (nc_put_var_schar(ncid, byte_varid, (signed char *)byte_out)) ERR;
      if (nc_put_var_text(ncid, char_varid, (char *)char_out)) ERR;
      if (nc_put_var_short(ncid, short_varid, (short *)short_out)) ERR;
      if (nc_put_var_int(ncid, int_varid, (int *)int_out)) ERR;
      if (nc_put_var_float(ncid, float_varid, (float *)float_out)) ERR;
      if (nc_put_var_double(ncid, double_varid, (double *)double_out)) ERR;
      if (nc_put_var_ubyte(ncid, ubyte_varid, (unsigned char *)ubyte_out)) ERR;
      if (nc_put_var_ushort(ncid, ushort_varid, (unsigned short *)ushort_out)) ERR;
      if (nc_put_var_uint(ncid, uint_varid, (unsigned int *)uint_out)) ERR;
      if (nc_put_var_longlong(ncid, int64_varid, (long long *)int64_out)) ERR;
      if (nc_put_var_ulonglong(ncid, uint64_varid, (unsigned long long *)uint64_out)) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and check metadata. */
      {
	 nc_type xtype_in;
	 int ndims_in, dimids_in[10], natts_in, varid_in;
	 char name_in[NC_MAX_NAME+1];

	 if (nc_open(FILE_NAME, 0, &ncid)) ERR;
	 if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, 
			&natts_in)) ERR;
	 if (strcmp(name_in, VAR_BYTE_NAME) || xtype_in != NC_BYTE || 
	     ndims_in != 2 || natts_in != 0 || dimids_in[0] != dimids[0] ||
	     dimids_in[1] != dimids[1]) ERR;
	 if (nc_inq_varid(ncid, VAR_BYTE_NAME, &varid_in)) ERR;
	 if (varid_in != 0) ERR;
	 if (nc_inq_varid(ncid, VAR_CHAR_NAME, &varid_in)) ERR;
	 if (varid_in != 1) ERR;
	 if (nc_inq_varid(ncid, VAR_SHORT_NAME, &varid_in)) ERR;
	 if (varid_in != 2) ERR;
	 if (nc_inq_varname(ncid, 0, name_in)) ERR;
	 if (strcmp(name_in, VAR_BYTE_NAME)) ERR;
	 if (nc_inq_varname(ncid, 1, name_in)) ERR;
	 if (strcmp(name_in, VAR_CHAR_NAME)) ERR;
	 if (nc_inq_varname(ncid, 2, name_in)) ERR;
	 if (strcmp(name_in, VAR_SHORT_NAME)) ERR;
	 if (nc_inq_vartype(ncid, 0, &xtype_in)) ERR;      
	 if (xtype_in != NC_BYTE) ERR;
	 if (nc_inq_vartype(ncid, 1, &xtype_in)) ERR;      
	 if (xtype_in != NC_CHAR) ERR;
	 if (nc_inq_vartype(ncid, 2, &xtype_in)) ERR;      
	 if (xtype_in != NC_SHORT) ERR;
	 if (nc_close(ncid)) ERR;
      }

      /* Open the file and check data. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_var_schar(ncid, byte_varid, (signed char *)byte_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != byte_out[i][j]) ERR;
      if (nc_get_var_short(ncid, short_varid, (short *)short_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (short_in[i][j] != short_out[i][j]) ERR;
      if (nc_get_var_int(ncid, int_varid, (int *)int_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (int_in[i][j] != int_out[i][j]) ERR;
      if (nc_get_var_float(ncid, float_varid, (float *)float_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (float_in[i][j] != float_out[i][j]) ERR;
      if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != double_out[i][j]) ERR;
      if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != double_out[i][j]) ERR;
      if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != double_out[i][j]) ERR;
      if (nc_get_var_uint(ncid, uint_varid, (unsigned int *)uint_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (uint_in[i][j] != uint_out[i][j]) ERR;
      if (nc_get_var_longlong(ncid, int64_varid, (long long *)int64_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (int64_in[i][j] != int64_out[i][j]) ERR;
      if (nc_get_var_ulonglong(ncid, uint64_varid, (unsigned long long *)uint64_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (uint64_in[i][j] != uint64_out[i][j]) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and read everything as double. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_var_double(ncid, byte_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)byte_out[i][j]) ERR;
      if (nc_get_var_double(ncid, ubyte_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)ubyte_out[i][j]) ERR;
      if (nc_get_var_double(ncid, short_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)short_out[i][j]) ERR;
      if (nc_get_var_double(ncid, ushort_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)ushort_out[i][j]) ERR;
      if (nc_get_var_double(ncid, int_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)int_out[i][j]) ERR;
      if (nc_get_var_double(ncid, uint_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)uint_out[i][j]) ERR;
      if (nc_get_var_double(ncid, float_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)float_out[i][j]) ERR;
      if (nc_get_var_double(ncid, int64_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)int64_out[i][j]) ERR;
      if (nc_get_var_double(ncid, uint64_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)uint64_out[i][j]) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and read everything as NC_BYTE. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_var_schar(ncid, byte_varid, (signed char *)byte_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)byte_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, ubyte_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)ubyte_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, short_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)short_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, ushort_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)ushort_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, int_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)int_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, uint_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)uint_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, float_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)float_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, int64_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)int64_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, uint64_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)uint64_out[i][j]) ERR;
      if (nc_close(ncid)) ERR;

   }
   SUMMARIZE_ERR;

#define NDIMS4 1
#define NVARS4 1
#define DIM4_NAME "treaty_of_paris_1783"
#define DIM4_LEN 5
#define VAR_NAME4 "John_Adams"
#define DEFLATE_LEVEL 6

   printf("*** testing netcdf-4 simple variable define...");
   {
      int dimids[NDIMS4], dimids_in[NDIMS4];
      int varid, varids_in[NVARS4];
      int ndims, nvars, natts, unlimdimid;
      nc_type xtype_in;
      char name_in[NC_MAX_NAME + 1];
      int shuffle_in, deflate_in, deflate_level;

      /* Create a netcdf-4 file with one dim and one var. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM4_NAME, DIM4_LEN, &dimids[0])) ERR;
      if (dimids[0] != 0) ERR;
      if (nc_def_var(ncid, VAR_NAME4, NC_INT64, NDIMS4, dimids, &varid)) ERR;
      if (nc_def_var_deflate(ncid, varid, 0, 1, DEFLATE_LEVEL)) ERR;
      if (varid != 0) ERR;

      /* Check stuff. */
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != NDIMS4 || nvars != NVARS4 || natts != 0 ||
	  unlimdimid != -1) ERR;
      if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
      if (nvars != NVARS4) ERR;
      if (varids_in[0] != 0) ERR;
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims,
		     dimids_in, &natts)) ERR;
      if (strcmp(name_in, VAR_NAME4) || xtype_in != NC_INT64 ||
	  ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
      if (nc_inq_var_deflate(ncid, 0, &shuffle_in, &deflate_in, 
			     &deflate_level)) ERR;
      if (shuffle_in ||!deflate_in || 
	  deflate_level != DEFLATE_LEVEL) ERR;

      if (nc_close(ncid)) ERR;

      /* Open the file and check the same stuff. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != NDIMS4 || nvars != NVARS4 || natts != 0 ||
	  unlimdimid != -1) ERR;
      if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
      if (nvars != NVARS4) ERR;
      if (varids_in[0] != 0) ERR;
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims,
		     dimids_in, &natts)) ERR;
      if (strcmp(name_in, VAR_NAME4) || xtype_in != NC_INT64 ||
	  ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
      if (nc_inq_var_deflate(ncid, 0, &shuffle_in, &deflate_in, 
			     &deflate_level)) ERR;
      if (shuffle_in ||!deflate_in || 
	  deflate_level != DEFLATE_LEVEL) ERR;

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;

#define NDIMS5 1
#define NVARS5 5
#define DIM5_NAME "treaty_of_paris_1783"
#define DIM5_LEN 5

   printf("*** testing netcdf-4 less simple variable define...");
   {
      int dimids[NDIMS5], dimids_in[NDIMS5];
      int varid[NVARS5], varids_in[NVARS5];
      int ndims, nvars, natts, unlimdimid;
      nc_type xtype_in;
      char name_in[NC_MAX_NAME + 1];
      char var_name[NVARS5][NC_MAX_NAME + 1] = {"Jean-Pierre_Blanchard", "Madame_Blanchard",
						"Giffard", "Stanislas_Charles_Henri_Dupuy_de_Lome",
						"Charles_F_Ritchel"};
      int shuffle_in, deflate_in, deflate_level_in;
      int deflate_level[NVARS5];
      int i;

      /* Set up options for this var. */
      for (i = 0; i < NVARS5; i++)
	 deflate_level[i] = i;

      /* Create a netcdf-4 file with one dim and two vars. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM5_NAME, DIM5_LEN, &dimids[0])) ERR;
      if (dimids[0] != 0) ERR;
      for (i = 0; i < NVARS5; i++)
      {
	 if (nc_def_var(ncid, var_name[i], NC_INT64, NDIMS5, dimids, 
			&varid[i])) ERR;
	 if (varid[i] != i) ERR;
	 if (nc_def_var_deflate(ncid, varid[i], 1, 1, deflate_level[i])) ERR;
      }

      /* Check stuff. */
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != NDIMS5 || nvars != NVARS5 || natts != 0 ||
	  unlimdimid != -1) ERR;
      if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
      if (nvars != NVARS5) ERR;
      for (i = 0; i < NVARS5; i++)
      {
	 if (varids_in[i] != i) ERR;
	 if (nc_inq_var(ncid, i, name_in, &xtype_in, &ndims,
			dimids_in, &natts)) ERR;
	 if (strcmp(name_in, var_name[i]) || xtype_in != NC_INT64 ||
	     ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
	 if (nc_inq_var_deflate(ncid, varid[i], &shuffle_in, &deflate_in, 
				&deflate_level_in)) ERR;
	 if (!shuffle_in || !deflate_in || 
	     deflate_level_in != deflate_level[i]) ERR;
      }

      if (nc_close(ncid)) ERR;

      /* Open the file and check the same stuff. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != NDIMS5 || nvars != NVARS5 || natts != 0 ||
	  unlimdimid != -1) ERR;
      if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
      if (nvars != NVARS5) ERR;
      for (i = 0; i < NVARS5; i++)
      {
	 if (varids_in[i] != i) ERR;
	 if (nc_inq_var(ncid, i, name_in, &xtype_in, &ndims,
			dimids_in, &natts)) ERR;
	 if (strcmp(name_in, var_name[i]) || xtype_in != NC_INT64 ||
	     ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
	 if (nc_inq_var_deflate(ncid, varid[i], &shuffle_in, &deflate_in, 
				&deflate_level_in)) ERR;
	 if (!shuffle_in || !deflate_in || 
	     deflate_level_in != deflate_level[i]) ERR;
      }

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;

#define NVARS 5
#define NDIMS 1
#define DIM6_NAME "airship_cross_sectional_area"
#define DIM6_LEN 100
#define TEN_K_M2 10000.0
#define INCREMENT 1000.0

   printf("*** testing more complex netcdf-4 variable defines...");
   {
      int dimids[NDIMS], dimids_in[NDIMS];
      int varid[NVARS], varids_in[NVARS];
      int ndims, nvars, natts, unlimdimid;
      char var_name[NVARS][50] = {"Jean-Pierre_Blanchard", "Madame_Blanchard",
				  "Giffard", "Stanislas_Charles_Henri_Dupuy_de_Lome",
				  "Charles_F_Ritchel"};
      double data[DIM6_LEN];
      nc_type xtype_in;
      char name_in[NC_MAX_NAME + 1];
      int shuffle_in, deflate_in, deflate_level_in;
      int fletcher32_in;
      int i;

      /* Create some phoney data. */
      for (i = 1, data[0] = TEN_K_M2; i < DIM6_LEN; i++)
	 data[i] = data[i - 1] + INCREMENT;

      /* Create a netcdf-4 file with one dim and 5 NC_DOUBLE vars. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM6_NAME, DIM6_LEN, &dimids[0])) ERR;
      for (i = 0; i < NVARS; i++)
      {
	 if (nc_def_var(ncid, var_name[i], NC_DOUBLE, NDIMS, dimids,
			&varid[i])) ERR;
	 if (nc_def_var_deflate(ncid, varid[i], 0, 1, 0)) ERR;
	 if (nc_def_var_fletcher32(ncid, varid[i], 1)) ERR;
      }

      /* Check stuff. */
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != NDIMS || nvars != NVARS || natts != 0 ||
	  unlimdimid != -1) ERR;
      if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
      if (nvars != NVARS) ERR;
      for (i = 0; i < NVARS; i++)
	 if (varids_in[i] != i) ERR;
      for (i = 0; i < NVARS; i++)
      {
	 if (nc_inq_var(ncid, i, name_in, &xtype_in, &ndims,
			dimids_in, &natts)) ERR;
	 if (strcmp(name_in, var_name[i]) || xtype_in != NC_DOUBLE ||
	     ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
	 if (nc_inq_var_deflate(ncid, varid[i], &shuffle_in, &deflate_in, 
				&deflate_level_in)) ERR;
	 if (shuffle_in || !deflate_in || deflate_level_in != 0) ERR;
	 if (nc_inq_var_fletcher32(ncid, varid[i], &fletcher32_in)) ERR;
	 if (!fletcher32_in) ERR;
      }

      if (nc_close(ncid)) ERR;

      /* Open the file and check the same stuff. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != NDIMS || nvars != NVARS || natts != 0 ||
	  unlimdimid != -1) ERR;
      if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
      if (nvars != NVARS) ERR;
      for (i = 0; i < NVARS; i++)
	 if (varids_in[i] != i) ERR;
      for (i = 0; i < NVARS; i++)
      {
	 if (nc_inq_var(ncid, i, name_in, &xtype_in, &ndims,
			dimids_in, &natts)) ERR;
	 if (strcmp(name_in, var_name[i]) || xtype_in != NC_DOUBLE ||
	     ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
	 if (nc_inq_var_deflate(ncid, varid[i], &shuffle_in, &deflate_in, 
				&deflate_level_in)) ERR;
	 if (shuffle_in || !deflate_in || 
	     deflate_level_in != 0) ERR;
	 if (nc_inq_var_fletcher32(ncid, varid[i], &fletcher32_in)) ERR;
	 if (!fletcher32_in) ERR;
      }

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
#define DIM7_LEN 2
#define DIM7_NAME "dim_7_from_Indiana"
#define VAR7_NAME "var_7_from_Idaho"
#define NDIMS 1

   printf("*** testing fill values...");
   {
      int dimids[NDIMS], dimids_in[NDIMS];
      size_t index[NDIMS];
      int varid, ndims, natts;
      nc_type xtype_in;
      char name_in[NC_MAX_NAME + 1];
      int shuffle_in, deflate_in, deflate_level_in;
      int fletcher32_in, no_fill;
      unsigned short ushort_data = 42, ushort_data_in, fill_value_in;

      /* Create a netcdf-4 file with one dim and 1 NC_USHORT var. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM7_NAME, DIM7_LEN, &dimids[0])) ERR;
      if (nc_def_var(ncid, VAR7_NAME, NC_USHORT, NDIMS, dimids,
		     &varid)) ERR;

      /* Check stuff. */
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims,
		     dimids_in, &natts)) ERR;
      if (strcmp(name_in, VAR7_NAME) || xtype_in != NC_USHORT ||
	  ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
      if (nc_inq_var_deflate(ncid, 0, &shuffle_in, &deflate_in, 
			     &deflate_level_in)) ERR;
      if (shuffle_in || deflate_in) ERR;
      if (nc_inq_var_fletcher32(ncid, 0, &fletcher32_in)) ERR;
      if (fletcher32_in) ERR;
      if (nc_inq_var_fill(ncid, 0, &no_fill, &fill_value_in)) ERR;
      if (no_fill || fill_value_in != NC_FILL_USHORT) ERR;

      /* Write the second of two values. */
      index[0] = 1;
      if (nc_put_var1_ushort(ncid, 0, index, &ushort_data)) ERR;

      /* Get the first value, and make sure we get the default fill
       * value for USHORT. */
      index[0] = 0;
      if (nc_get_var1_ushort(ncid, 0, index, &ushort_data_in)) ERR;
      if (ushort_data_in != NC_FILL_USHORT) ERR;

      if (nc_close(ncid)) ERR;

      /* Open the file and check the same stuff. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

      /* Check stuff. */
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims,
		     dimids_in, &natts)) ERR;
      if (strcmp(name_in, VAR7_NAME) || xtype_in != NC_USHORT ||
	  ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
      if (nc_inq_var_deflate(ncid, 0, &shuffle_in, &deflate_in, 
			     &deflate_level_in)) ERR;
      if (shuffle_in || deflate_in) ERR;
      if (nc_inq_var_fletcher32(ncid, 0, &fletcher32_in)) ERR;
      if (fletcher32_in) ERR;

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing more fill values...");
   {
      int dimids[NDIMS];
      size_t index[NDIMS];
      int varid;
      int no_fill;
      unsigned short ushort_data = 42, ushort_data_in, fill_value_in;

      /* Create a netcdf-4 file with one dim and 1 NC_USHORT var. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM7_NAME, DIM7_LEN, &dimids[0])) ERR;
      if (nc_def_var(ncid, VAR7_NAME, NC_USHORT, NDIMS, dimids,
		     &varid)) ERR;
      if (nc_def_var_fill(ncid, varid, 1, NULL)) ERR;

      /* Check stuff. */
      if (nc_inq_var_fill(ncid, varid, &no_fill, &fill_value_in)) ERR;
      if (!no_fill) ERR;

      /* Write the second of two values. */
      index[0] = 1;
      if (nc_put_var1_ushort(ncid, varid, index, &ushort_data)) ERR;

      /* Get the first value, and make sure we get the default fill
       * value for USHORT. */
      index[0] = 0;
      if (nc_get_var1_ushort(ncid, varid, index, &ushort_data_in)) ERR;

      if (nc_close(ncid)) ERR;

      /* Open the file and check the same stuff. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

      /* Check stuff. */
      if (nc_inq_var_fill(ncid, varid, &no_fill, &fill_value_in)) ERR;
      if (!no_fill) ERR;

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing lots of variables...");
#define DIM_A_NAME "x"
#define DIM_A_LEN 10
#define NUM_VARS 2000
#define MAX_VARNAME 10
   {
      /* This simple test failed on HDF5 1.7.58, but passes just fine
       * on 1.8.0 alpha5... */
      int ncid, dimids[1], i;
      char varname[MAX_VARNAME];
      int varids[NUM_VARS];

      /* Create a file with three dimensions. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM_A_NAME, DIM_A_LEN, &dimids[0])) ERR;

      /* Create a large number of variables. */
      for (i = 0; i < NUM_VARS; i++)
      {
	 sprintf(varname, "a_%d", i);
	 if (nc_def_var(ncid, varname, NC_FLOAT, 1, dimids, &varids[i])) ERR;
      }
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
#define NC3_CLASSIC_FILE "tst_pres_temp_4D_classic.nc"
#define NC3_64BIT_OFFSET_FILE "tst_pres_temp_4D_64bit_offset.nc"
#define NC3_NETCDF4_FILE "tst_pres_temp_4D_netcdf4.nc"
#define NC3_NETCDF4_CLASSIC_FILE "tst_pres_temp_4D_netcdf4_classic.nc"
   printf("*** testing 4D example file in classic format...");
   if (create_4D_example(NC3_CLASSIC_FILE, NC_CLOBBER)) ERR;
   if (check_4D_example(NC3_CLASSIC_FILE, NC_FORMAT_CLASSIC)) ERR;      
   SUMMARIZE_ERR;
   printf("*** testing 4D example file in 64-bit offset format...");
   if (create_4D_example(NC3_64BIT_OFFSET_FILE, NC_CLOBBER|NC_64BIT_OFFSET)) ERR;
   if (check_4D_example(NC3_64BIT_OFFSET_FILE, NC_FORMAT_64BIT)) ERR;      
   SUMMARIZE_ERR;
   printf("*** testing 4D example file in netCDF-4/HDF5 format...");
   if (create_4D_example(NC3_NETCDF4_FILE, NC_CLOBBER|NC_NETCDF4)) ERR;
   if (check_4D_example(NC3_NETCDF4_FILE, NC_FORMAT_NETCDF4)) ERR;      
   SUMMARIZE_ERR;
   printf("*** testing 4D example file in netCDF-4/HDF5 format with classic model rules...");
   if (create_4D_example(NC3_NETCDF4_CLASSIC_FILE, NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL)) ERR;
   if (check_4D_example(NC3_NETCDF4_CLASSIC_FILE, NC_FORMAT_NETCDF4_CLASSIC)) ERR;      
   SUMMARIZE_ERR;

   FINAL_RESULTS;
#ifdef USE_PARALLEL
   MPI_Finalize();
#endif   

}
Esempio n. 5
0
int
main(int argc, char **argv) 
{			/* create tst_classic_fills.nc */
   printf("\n*** Testing fill values.\n");
   printf("*** testing empty fill values of a string var...");
   {
#define STRING_VAR_NAME "The_String"
#define NDIMS_STRING 1
#define FILLVALUE_LEN 1 /* There is 1 string, the empty one. */
#define DATA_START 2 /* Real data here. */

      int  ncid, varid, dimid, varid_in;
      const char *missing_val[FILLVALUE_LEN] = {""};
      const char *missing_val_in[FILLVALUE_LEN];
      const char *data_out[1] = {"The evil that men do lives after them; "
				 "the good is oft interred with their bones."};
      char **data_in;
      size_t index = DATA_START;
      int i;

      /* Create file with a 1D string var. Set its fill value to the
       * empty string. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, "rec", NC_UNLIMITED, &dimid)) ERR;
      if (nc_def_var(ncid, STRING_VAR_NAME, NC_STRING, NDIMS_STRING, &dimid, &varid)) ERR;
      if (nc_put_att_string(ncid, varid, "_FillValue", FILLVALUE_LEN, missing_val)) ERR;

      /* Check it out. */
      if (nc_inq_varid(ncid, STRING_VAR_NAME, &varid_in)) ERR;
      if (nc_get_att_string(ncid, varid_in, "_FillValue", (char **)missing_val_in)) ERR;
      if (strcmp(missing_val[0], missing_val_in[0])) ERR;
      if (nc_free_string(FILLVALUE_LEN, (char **)missing_val_in)) ERR;

      /* Write one string, leaving some blank records which will then
       * get the fill value. */
      if (nc_put_var1_string(ncid, varid_in, &index, data_out)) ERR;

      /* Get all the data from the variable. */
      if (!(data_in = malloc((DATA_START + 1) * sizeof(char *)))) ERR;
      if (nc_get_var_string(ncid, varid_in, data_in)) ERR;

      /* First there should be fill values, then the data value we
       * wrote. */
      for (i = 0; i < DATA_START; i++)
	 if (strcmp(data_in[i], "")) ERR;
      if (strcmp(data_in[DATA_START], data_out[0])) ERR;

      /* Close everything up. */
      if (nc_close(ncid)) ERR;

      /* Now re-open file, read data, and check values again. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq_varid(ncid, STRING_VAR_NAME, &varid_in)) ERR;
      if (nc_get_att_string(ncid, varid_in, "_FillValue", (char **)missing_val_in)) ERR;
      if (strcmp(missing_val[0], missing_val_in[0])) ERR;
      if (nc_free_string(FILLVALUE_LEN, (char **)missing_val_in)) ERR;
      if (nc_close(ncid)) ERR;
      free(data_in);
   }

   SUMMARIZE_ERR;
   printf("*** testing non-empty fill values of a string var...");
   {
#define STRING_VAR_NAME2 "CASSIUS"
#define FILLVALUE_LEN2 1 /* There is 1 string in the fillvalue array. */
#define DATA_START2 9 /* Real data starts here. */

      int  ncid, varid, dimid, varid_in;
      const char *missing_val[FILLVALUE_LEN2] = {"I know that virtue to be in you, Brutus"};
      const char *missing_val_in[FILLVALUE_LEN2];
      const char *data_out[1] = {"The evil that men do lives after them; "
				 "the good is oft interred with their bones."};
      char **data_in;
      size_t index = DATA_START2;
      int i;

      /* Create file with a 1D string var. Set its fill value to the
       * a non-empty string. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, "rec", NC_UNLIMITED, &dimid)) ERR;
      if (nc_def_var(ncid, STRING_VAR_NAME2, NC_STRING, NDIMS_STRING, &dimid, &varid)) ERR;
      if (nc_put_att_string(ncid, varid, "_FillValue", FILLVALUE_LEN2, missing_val)) ERR;

      /* Check it out. */
      if (nc_inq_varid(ncid, STRING_VAR_NAME2, &varid_in)) ERR;
      if (nc_get_att_string(ncid, varid_in, "_FillValue", (char **)missing_val_in)) ERR;
      if (strcmp(missing_val[0], missing_val_in[0])) ERR;
      if (nc_free_string(FILLVALUE_LEN2, (char **)missing_val_in)) ERR;

      /* Write one string, leaving some blank records which will then
       * get the fill value. */
      if (nc_put_var1_string(ncid, varid_in, &index, data_out)) ERR;

      /* Get all the data from the variable. */
      if (!(data_in = malloc((DATA_START2 + 1) * sizeof(char *)))) ERR;
      if (nc_get_var_string(ncid, varid_in, data_in)) ERR;

      /* First there should be fill values, then the data value we
       * wrote. */
      for (i = 0; i < DATA_START2; i++)
	 if (strcmp(data_in[i], missing_val[0])) ERR;
      if (strcmp(data_in[DATA_START2], data_out[0])) ERR;

      /* Close everything up. */
      if (nc_close(ncid)) ERR;

      /* Now re-open file, read data, and check values again. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq_varid(ncid, STRING_VAR_NAME2, &varid_in)) ERR;
      if (nc_get_att_string(ncid, varid_in, "_FillValue", (char **)missing_val_in)) ERR;
      if (strcmp(missing_val[0], missing_val_in[0])) ERR;
      if (nc_free_string(FILLVALUE_LEN2, (char **)missing_val_in)) ERR;
      if (nc_close(ncid)) ERR;
      free(data_in);
   }

   SUMMARIZE_ERR;
   printf("*** testing fill values of one var...");
   {
#define V1_NAME "v1"
#define MAX_VALS 10
      int  ncid, varid, rec_id, dims[2];
      static int rec[1] = {1};
      size_t start[2] = {0, 0};
      size_t count[2] = {1, MAX_VALS};
      char vals[MAX_VALS];
      int i;

      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;

      /* Define dimensions and two vars, a 1D coordinate var for
       * unlimited dimension, and a 2D var which uses the unlimited
       * dimension. */
      if (nc_def_dim(ncid, "rec", NC_UNLIMITED, &dims[0])) ERR;
      if (nc_def_dim(ncid, "len", MAX_VALS, &dims[1])) ERR;
      if (nc_def_var(ncid, "rec", NC_INT, 1, dims, &rec_id)) ERR;
      if (nc_def_var(ncid, V1_NAME, NC_CHAR, 2, dims, &varid)) ERR;

      /* Extend record dimension by 1. */
      if (nc_put_vara_int(ncid, rec_id, start, count, rec)) ERR;

      /* Read the other variable; it must have only fill values. */
      if (nc_get_vara_text(ncid, 1, start, count, vals)) ERR;
      for (i = 0; i < MAX_VALS; i++)
	 if(vals[i] != NC_FILL_CHAR) ERR;

      if (nc_close(ncid)) ERR;

      /* Now re-open file, read data, and check values again. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

      /* Read the other variable; it must have only fill values. */
      if (nc_get_vara_text(ncid, 1, start, count, vals)) ERR;
      for (i = 0; i < MAX_VALS; i++)
	 if(vals[i] != NC_FILL_CHAR) ERR;

      if(nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing fill values of lots of vars...");

   {
      int  ncid;			/* netCDF id */

#define NVALS 10		/* values per fixed-size variable or record */
#define NFIXVARS 6		/* number of fixed-size vars, one of each type */
#define NRECVARS 6		/* number of record vars, one of each type */
#define RANK_REC 1
#define RANK_FIXVARS 1
#define RANK_RECVARS 2

      /* dimension ids */
      int rec_dim;
      int len_dim;

      /* dimension lengths */
      size_t rec_len = NC_UNLIMITED;
      size_t len_len = NVALS;

      /* variable ids */
      int rec_id;
      int fixvar_ids[NFIXVARS];
      int recvar_ids[NRECVARS];
      int rec_dims[RANK_REC];
      int fixvar_dims[RANK_FIXVARS];
      int recvar_dims[RANK_RECVARS];
      int fixvar, recvar, i;

      char *fnames[] = {"c", "b", "s", "i", "f", "d"};
      char *rnames[] = {"cr", "br", "sr", "ir", "fr", "dr"};
      nc_type types[] = {NC_CHAR, NC_BYTE, NC_SHORT, NC_INT, NC_FLOAT, NC_DOUBLE};

      /*if (nc_set_default_format(format + 1, NULL)) ERR;*/
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;

      /* define dimensions */
      if (nc_def_dim(ncid, "rec", rec_len, &rec_dim)) ERR;
      if (nc_def_dim(ncid, "len", len_len, &len_dim)) ERR;

      rec_dims[0] = rec_dim;
      if (nc_def_var(ncid, "rec", NC_INT, RANK_REC, rec_dims, &rec_id)) ERR;

      /* define fixed and record variables of all 6 primitive types */
      fixvar_dims[0] = len_dim;
      for (fixvar = 0; fixvar < NFIXVARS; fixvar++)
	 if (nc_def_var(ncid, fnames[fixvar], types[fixvar], RANK_FIXVARS,
			fixvar_dims, &fixvar_ids[fixvar])) ERR;

      recvar_dims[0] = rec_dim;
      recvar_dims[1] = len_dim;
      for (recvar = 0; recvar < NRECVARS; recvar++)
	 if (nc_def_var(ncid, rnames[recvar], types[recvar], RANK_RECVARS,
			recvar_dims, &recvar_ids[recvar])) ERR;

      /* leave define mode */
      if (nc_enddef(ncid)) ERR;

      {			/* store rec */
	 static size_t rec_start[RANK_REC];
	 static size_t rec_count[RANK_REC];
	 static int rec[] = {1};
	 rec_len = 1;			/* number of records of rec data */
	 rec_start[0] = 0;
	 rec_count[0] = rec_len;
	 if (nc_put_vara_int(ncid, rec_id, rec_start, rec_count, rec)) ERR;
      }
      if (nc_close(ncid)) ERR;

      /* Now re-open file, read data, and check values */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

      /* Check that fixed-size variables are full of fill values */
      for (fixvar = 0; fixvar < NFIXVARS; fixvar++) {
	 int varid;
	 nc_type type;

	 if (nc_inq_varid(ncid, fnames[fixvar], &varid)) ERR;
	 if (nc_inq_vartype(ncid, varid, &type)) ERR;
	 switch(type) {
	    case NC_CHAR:
	    {
	       char vals[NVALS];
	       if (nc_get_var_text(ncid, varid, vals)) ERR;
	       for (i = 0; i < NVALS; i++)
		  if(vals[i] != NC_FILL_CHAR) ERR;
	    }
	    break;
	    case NC_BYTE:
	    {
	       signed char vals[NVALS];
	       if (nc_get_var_schar(ncid, varid, vals)) ERR;
	       for (i = 0; i < NVALS; i++)
		  if(vals[i] != NC_FILL_BYTE) ERR;
	    }
	    break;
	    case NC_SHORT:
	    {
	       short vals[NVALS];
	       if (nc_get_var_short(ncid, varid, vals)) ERR;
	       for (i = 0; i < NVALS; i++)
		  if(vals[i] != NC_FILL_SHORT) ERR;
	    }
	    break;
	    case NC_INT:
	    {
	       int vals[NVALS];
	       if (nc_get_var_int(ncid, varid, vals)) ERR;
	       for (i = 0; i < NVALS; i++)
		  if(vals[i] != NC_FILL_INT) ERR;
	    }
	    break;
	    case NC_FLOAT:
	    {
	       float vals[NVALS];
	       if (nc_get_var_float(ncid, varid, vals)) ERR;
	       for (i = 0; i < NVALS; i++)
		  if(vals[i] != NC_FILL_FLOAT) ERR;
	    }
	    break;
	    case NC_DOUBLE:
	    {
	       double vals[NVALS];
	       if (nc_get_var_double(ncid, varid, vals)) ERR;
	       for (i = 0; i < NVALS; i++)
		  if (vals[i] != NC_FILL_DOUBLE) ERR;
	    }
	    break;
	    default:
	       ERR;
	 }
      }

      /* Read record, check record variables have only fill values */
      for (recvar = 0; recvar < NRECVARS; recvar++) {
	 int varid;
	 nc_type type;
	 size_t start[] = {0, 0};
	 size_t count[] = {1, NVALS};

	 if (nc_inq_varid(ncid, rnames[recvar], &varid)) ERR;
	 if (nc_inq_vartype(ncid, varid, &type)) ERR;
	 switch(type) {
	    case NC_CHAR:
	    {
	       char vals[NVALS];
	       if (nc_get_vara_text(ncid, varid, start, count, vals)) ERR;
	       for (i = 0; i < NVALS; i++)
		  if(vals[i] != NC_FILL_CHAR) ERR;
	    }
	    break;
	    case NC_BYTE:
	    {
	       signed char vals[NVALS];
	       if (nc_get_vara_schar(ncid, varid, start, count, vals)) ERR;
	       for (i = 0; i < NVALS; i++)
		  if(vals[i] != NC_FILL_BYTE) ERR;
	    }
	    break;
	    case NC_SHORT:
	    {
	       short vals[NVALS];
	       if (nc_get_vara_short(ncid, varid, start, count, vals)) ERR;
	       for (i = 0; i < NVALS; i++)
		  if(vals[i] != NC_FILL_SHORT) ERR;
	    }
	    break;
	    case NC_INT:
	    {
	       int vals[NVALS];
	       if (nc_get_vara_int(ncid, varid, start, count, vals)) ERR;
	       for (i = 0; i < NVALS; i++)
		  if(vals[i] != NC_FILL_INT) ERR;
	    }
	    break;
	    case NC_FLOAT:
	    {
	       float vals[NVALS];
	       if (nc_get_vara_float(ncid, varid, start, count, vals)) ERR;
	       for (i = 0; i < NVALS; i++)
		  if(vals[i] != NC_FILL_FLOAT) ERR;
	    }
	    break;
	    case NC_DOUBLE:
	    {
	       double vals[NVALS];
	       if (nc_get_vara_double(ncid, varid, start, count, vals)) ERR;
	       for (i = 0; i < NVALS; i++)
		  if(vals[i] != NC_FILL_DOUBLE) ERR;
	    }
	    break;
	    default:
	       ERR;
	 }
      }

      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   FINAL_RESULTS;

   return 0;
}