2016-06-07 04:51:57 +08:00
|
|
|
/* This is part of the netCDF package.
|
2018-12-07 06:27:32 +08:00
|
|
|
Copyright 2018 University Corporation for Atmospheric Research/Unidata
|
2016-06-07 04:51:57 +08:00
|
|
|
See COPYRIGHT file for conditions of use.
|
|
|
|
|
|
|
|
Based on tst_fillbug.c
|
|
|
|
|
|
|
|
Added in support of https://github.com/Unidata/netcdf-c/issues/239
|
|
|
|
|
|
|
|
The issue in a nutshell is that if _FillValue is added to a file
|
|
|
|
defined without it, previously existing attributes with
|
|
|
|
preexisting variables are wiped out, only the _FillValue attribute
|
|
|
|
exists.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <nc_tests.h>
|
2016-10-22 03:24:40 +08:00
|
|
|
#include "err_macros.h"
|
2016-06-07 04:51:57 +08:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <netcdf.h>
|
|
|
|
|
|
|
|
#define FILENAME "tst_fill_attr_vanish.nc"
|
|
|
|
#define RANK_Time 1
|
|
|
|
#define RANK_P 3
|
|
|
|
#define LEN 4
|
|
|
|
|
2016-06-07 06:10:10 +08:00
|
|
|
#define ATTNAME "TextAttribute"
|
|
|
|
#define ATTVAL "This is a text attribute used for testing."
|
2021-07-07 01:34:30 +08:00
|
|
|
#define ATTVAL_LEN 43
|
2016-06-07 06:10:10 +08:00
|
|
|
|
2016-06-11 07:03:08 +08:00
|
|
|
/*! Main function for tst_fill_attr_vanish.c
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
int main()
|
2016-06-07 04:51:57 +08:00
|
|
|
{
|
2017-03-30 01:16:25 +08:00
|
|
|
int ncid, dimids[RANK_P], time_id, p_id, test_id, status;
|
2016-06-07 05:44:38 +08:00
|
|
|
int test_data[1] = {1};
|
|
|
|
size_t test_start[1] = {0}, test_count[1] = {1};
|
|
|
|
int test_fill_val[] = {5};
|
|
|
|
double data[1] = {3.14159};
|
|
|
|
size_t start[1] = {0}, count[1] = {1};
|
2016-06-07 04:51:57 +08:00
|
|
|
|
2016-06-07 05:44:38 +08:00
|
|
|
printf("\n*** Testing for a netCDF-4 fill-value bug.\n");
|
|
|
|
printf("*** Creating a file with no _FillValue defined. ***\n");
|
2016-06-07 05:08:20 +08:00
|
|
|
|
2016-06-07 05:44:38 +08:00
|
|
|
/* Create a 3D test file. */
|
|
|
|
if (nc_create(FILENAME, NC_CLOBBER|NC_NETCDF4, &ncid)) ERR;
|
|
|
|
if (nc_set_fill(ncid, NC_NOFILL, NULL)) ERR;
|
2016-06-07 04:51:57 +08:00
|
|
|
|
2016-06-07 05:44:38 +08:00
|
|
|
/* define dimensions */
|
|
|
|
if (nc_def_dim(ncid, "Time", NC_UNLIMITED, &dimids[0])) ERR;
|
|
|
|
if (nc_def_dim(ncid, "X", 4, &dimids[2])) ERR;
|
|
|
|
if (nc_def_dim(ncid, "Y", 3, &dimids[1])) ERR;
|
2016-06-07 04:51:57 +08:00
|
|
|
|
2016-06-07 05:44:38 +08:00
|
|
|
/* define variables */
|
|
|
|
if (nc_def_var(ncid, "Time", NC_DOUBLE, 1, dimids, &time_id)) ERR;
|
|
|
|
if (nc_def_var(ncid, "P", NC_FLOAT, RANK_P, dimids, &p_id)) ERR;
|
|
|
|
if (nc_def_var(ncid, "Test", NC_INT, 1, &dimids[1], &test_id)) ERR;
|
|
|
|
|
|
|
|
/* Add a _FillValue attribute */
|
2016-06-07 06:10:10 +08:00
|
|
|
|
|
|
|
if (nc_put_att_text(ncid, test_id, ATTNAME, strlen(ATTVAL), ATTVAL)) ERR;
|
|
|
|
/* Add a value to the test variable */
|
2016-06-07 05:44:38 +08:00
|
|
|
if (nc_put_vara(ncid, test_id, test_start, test_count, test_data)) ERR;
|
|
|
|
|
|
|
|
/* Add one record in coordinate variable. */
|
|
|
|
if (nc_put_vara(ncid, time_id, start, count, data)) ERR;
|
|
|
|
|
|
|
|
/* That's it! */
|
|
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
|
|
|
|
/********************************************/
|
|
|
|
|
|
|
|
/* Reopen the file, add a fillvalue attribute. */
|
2016-06-07 06:10:10 +08:00
|
|
|
if (nc_open(FILENAME, NC_NOCLOBBER|NC_WRITE, &ncid)) ERR;
|
|
|
|
if (nc_redef(ncid)) ERR;
|
|
|
|
if (nc_inq_varid(ncid, "Test", &test_id)) ERR;
|
2016-06-07 04:51:57 +08:00
|
|
|
|
2016-06-07 06:10:10 +08:00
|
|
|
/* Query existing attribute. */
|
|
|
|
{
|
2021-07-07 01:34:30 +08:00
|
|
|
char *attval = (char*)malloc(1+(sizeof(char) * strlen(ATTVAL)));
|
|
|
|
memset(attval,'\0',(1+(sizeof(char) * strlen(ATTVAL))));
|
2017-01-12 03:36:30 +08:00
|
|
|
printf("**** Checking that attribute still exists:\t");
|
2021-07-07 01:34:30 +08:00
|
|
|
if(nc_get_att_text(ncid,test_id,ATTNAME,attval))
|
|
|
|
{printf("Fail\n"); ERR;}
|
|
|
|
else
|
|
|
|
{printf("%42s\n",attval);}
|
2016-06-07 06:10:10 +08:00
|
|
|
free(attval);
|
2016-06-07 04:51:57 +08:00
|
|
|
|
2016-06-07 06:10:10 +08:00
|
|
|
}
|
|
|
|
|
2017-03-30 01:16:25 +08:00
|
|
|
printf("**** Expecting NC_ELATEFILL when adding _FillValue attribute if variable exists.\n");
|
|
|
|
status = nc_put_att_int(ncid, test_id, "_FillValue", NC_INT, 1, test_fill_val);
|
|
|
|
if (status != NC_ELATEFILL) {
|
|
|
|
fflush(stdout); /* Make sure our stdout is synced with stderr. */
|
|
|
|
err++;
|
|
|
|
fprintf(stderr, "Sorry! Expecting NC_ELATEFILL but got %s, at file %s line: %d\n",
|
|
|
|
nc_strerror(status), __FILE__, __LINE__);
|
|
|
|
return 2;
|
|
|
|
}
|
2016-06-07 06:10:10 +08:00
|
|
|
|
|
|
|
/* Query existing attribute. */
|
|
|
|
{
|
2021-07-07 01:34:30 +08:00
|
|
|
char *attval = (char*)malloc(1+(sizeof(char) * strlen(ATTVAL)));
|
|
|
|
memset(attval,'\0',(1+(sizeof(char) * strlen(ATTVAL))));
|
2017-01-12 03:36:30 +08:00
|
|
|
printf("**** Checking that attribute still exists, pre-write:\t");
|
2016-06-07 06:10:10 +08:00
|
|
|
if(nc_get_att_text(ncid,test_id,ATTNAME,attval)) {printf("Fail\n"); ERR;}
|
|
|
|
else {printf("%s\n",attval);}
|
|
|
|
free(attval);
|
|
|
|
|
|
|
|
}
|
2016-06-07 04:51:57 +08:00
|
|
|
|
2016-06-07 05:44:38 +08:00
|
|
|
/* Close file again. */
|
2016-06-07 06:10:10 +08:00
|
|
|
printf( "**** Saving, closing file.\n");
|
|
|
|
if (nc_close(ncid)) ERR;
|
|
|
|
/********************************************/
|
|
|
|
printf( "*** Reopening file.\n");
|
|
|
|
/* Reopen the file, checking that all attributes are preserved. */
|
|
|
|
if (nc_open(FILENAME, NC_NOCLOBBER|NC_WRITE, &ncid)) ERR;
|
|
|
|
if (nc_redef(ncid)) ERR;
|
|
|
|
if (nc_inq_varid(ncid, "Test", &test_id)) ERR;
|
|
|
|
|
|
|
|
/* Query existing attribute. */
|
|
|
|
{
|
2021-07-07 01:34:30 +08:00
|
|
|
char *attval = (char*)malloc(1+(sizeof(char) * strnlen(ATTVAL,ATTVAL_LEN)));
|
|
|
|
memset(attval,'\0',(1+(sizeof(char) * strlen(ATTVAL))));
|
2017-01-12 03:36:30 +08:00
|
|
|
printf("**** Checking that attribute still exists:\t");
|
2016-06-07 06:10:10 +08:00
|
|
|
if(nc_get_att_text(ncid,test_id,ATTNAME,attval)) {printf("Fail\n"); ERR;}
|
|
|
|
else {printf("%s\n",attval);}
|
|
|
|
free(attval);
|
|
|
|
|
|
|
|
}
|
2016-06-07 04:51:57 +08:00
|
|
|
|
2016-06-07 06:10:10 +08:00
|
|
|
if (nc_close(ncid)) ERR;
|
2016-06-07 05:44:38 +08:00
|
|
|
/********************************************/
|
2016-06-07 04:51:57 +08:00
|
|
|
|
2016-06-15 00:47:24 +08:00
|
|
|
SUMMARIZE_ERR;
|
|
|
|
|
|
|
|
FINAL_RESULTS;
|
|
|
|
return 0;
|
2016-06-07 04:51:57 +08:00
|
|
|
}
|