netcdf-c/nc_test/tst_def_var_fill.c
2024-03-18 15:51:04 -05:00

147 lines
4.8 KiB
C

/* This is part of the netCDF package.
* Copyright 2018 University Corporation for Atmospheric Research/Unidata
* See COPYRIGHT file for conditions of use.
*
* Test per-variable fill mode for classic file formats.
*
* Author: Wei-keng Liao.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netcdf.h>
#define CHECK_ERR { \
if (err != NC_NOERR) { \
nerrs++; \
printf("Error at line %d in %s: (%s)\n", \
__LINE__,__FILE__,nc_strerror(err)); \
} \
}
#define EXP_ERR(exp) { \
if (err != exp) { \
nerrs++; \
printf("Error at line %d in %s: expecting %s but got %s\n", \
__LINE__,__FILE__,#exp, nc_strerror(err)); \
} \
}
#define NY 8
#define NX 5
int main(int argc, char** argv) {
char filename[256];
int i, j, k, err, nerrs=0, ncid, varid[2], dimid[2], *buf;
size_t start[2], count[2];
int formats[5]={NC_FORMAT_CLASSIC, NC_FORMAT_64BIT_OFFSET, NC_FORMAT_CDF5,
NC_FORMAT_NETCDF4, NC_FORMAT_NETCDF4_CLASSIC};
if (argc > 2) {
printf("Usage: %s [filename]\n",argv[0]);
return 1;
}
if (argc == 2) snprintf(filename, 256, "%s", argv[1]);
else strcpy(filename, "tst_def_var_fill.nc");
size_t cmd_str_len = strlen(argv[0]) + 256;
char *cmd_str = (char*)malloc(cmd_str_len);
snprintf(cmd_str, cmd_str_len, "*** TESTING C %s for def_var_fill ", argv[0]);
printf("%-66s ------ ", cmd_str); fflush(stdout);
free(cmd_str);
buf = (int*) malloc(NY*NX * sizeof(int));
for (k=0; k<5; k++) {
#ifndef NETCDF_ENABLE_CDF5
if (formats[k] == NC_FORMAT_CDF5) continue;
#endif
#ifndef USE_HDF5
if (formats[k] == NC_FORMAT_NETCDF4 ||
formats[k] == NC_FORMAT_NETCDF4_CLASSIC)
continue;
#endif
nc_set_default_format(formats[k], NULL);
/* create a new file for writing ------------------------------------*/
err = nc_create(filename, NC_CLOBBER, &ncid); CHECK_ERR
/* define dimension */
err = nc_def_dim(ncid, "Y", NY, &dimid[0]); CHECK_ERR
err = nc_def_dim(ncid, "X", NX, &dimid[1]); CHECK_ERR
/* define variables */
err = nc_def_var(ncid, "var_nofill", NC_INT, 2, dimid, &varid[0]); CHECK_ERR
err = nc_def_var(ncid, "var_fill", NC_INT, 2, dimid, &varid[1]); CHECK_ERR
/* set fill mode for variables */
err = nc_def_var_fill(ncid, NC_GLOBAL, 0, NULL); EXP_ERR(NC_EGLOBAL)
err = nc_def_var_fill(ncid, varid[0], 1, NULL); CHECK_ERR
err = nc_def_var_fill(ncid, varid[1], 0, NULL); CHECK_ERR
err = nc_enddef(ncid); CHECK_ERR
/* write a subarray to both variables */
for (i=0; i<NY*NX; i++) buf[i] = 5;
start[0] = 0;
start[1] = 2;
count[0] = NY;
count[1] = 2;
err = nc_put_vara_int(ncid, varid[0], start, count, buf); CHECK_ERR
err = nc_put_vara_int(ncid, varid[1], start, count, buf); CHECK_ERR
err = nc_close(ncid); CHECK_ERR
/* Now, reopen the file and read variables back */
err = nc_open(filename, NC_WRITE, &ncid); CHECK_ERR
/* get variable IDs */
err = nc_inq_varid(ncid, "var_nofill", &varid[0]); CHECK_ERR
err = nc_inq_varid(ncid, "var_fill", &varid[1]); CHECK_ERR
/* read variable "var_nofill" and check contents */
for (i=0; i<NY*NX; i++) buf[i] = -1;
err = nc_get_var_int(ncid, varid[0], buf); CHECK_ERR
for (i=0; i<NY; i++) {
for (j=0; j<NX; j++) {
if (2 <= j && j < 4) {
if (buf[i*NX+j] != 5) {
printf("Error at line %d in %s: expect get buf[%d]=%d but got %d\n",
__LINE__,__FILE__,i*NX+j, 5, buf[i*NX+j]);
nerrs++;
}
}
else if (buf[i*NX+j] == NC_FILL_INT) {
printf("Warning at line %d in %s: get buf[%d] same as NC_FILL_INT\n",
__LINE__,__FILE__,i*NX+j);
}
}
}
/* read variable "var_fill" and check contents */
for (i=0; i<NY*NX; i++) buf[i] = -1;
err = nc_get_var_int(ncid, varid[1], buf); CHECK_ERR
for (i=0; i<NY; i++) {
for (j=0; j<NX; j++) {
int expect = NC_FILL_INT;
if (2 <= j && j< 4) expect = 5;
if (buf[i*NX+j] != expect) {
printf("Error at line %d in %s: expect get buf[%d]=%d but got %d\n",
__LINE__,__FILE__,i*NX+j, expect, buf[i*NX+j]);
nerrs++;
}
}
}
err = nc_close(ncid); CHECK_ERR
}
free(buf);
if (nerrs) printf("fail with %d mismatches\n",nerrs);
else printf("pass\n");
return (nerrs > 0);
}