1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
/* This is part of the netCDF package.
Copyright 2016 University Corporation for Atmospheric Research/Unidata
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>
#include "err_macros.h"
#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
#define ATTNAME "TextAttribute"
#define ATTVAL "This is a text attribute used for testing."
/*! Main function for tst_fill_attr_vanish.c
*
*/
int main()
{
int ncid, dimids[RANK_P], time_id, p_id, test_id, status;
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};
printf("\n*** Testing for a netCDF-4 fill-value bug.\n");
printf("*** Creating a file with no _FillValue defined. ***\n");
/* Create a 3D test file. */
if (nc_create(FILENAME, NC_CLOBBER|NC_NETCDF4, &ncid)) ERR;
if (nc_set_fill(ncid, NC_NOFILL, NULL)) ERR;
/* 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;
/* 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 */
if (nc_put_att_text(ncid, test_id, ATTNAME, strlen(ATTVAL), ATTVAL)) ERR;
/* Add a value to the test variable */
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. */
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. */
{
char *attval = malloc(sizeof(char) * strlen(ATTVAL));
printf("**** Checking that attribute still exists:\t");
if(nc_get_att_text(ncid,test_id,ATTNAME,attval)) {printf("Fail\n"); ERR;}
else {printf("%s\n",attval);}
free(attval);
}
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;
}
/* Query existing attribute. */
{
char *attval = malloc(sizeof(char) * strlen(ATTVAL));
printf("**** Checking that attribute still exists, pre-write:\t");
if(nc_get_att_text(ncid,test_id,ATTNAME,attval)) {printf("Fail\n"); ERR;}
else {printf("%s\n",attval);}
free(attval);
}
/* Close file again. */
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. */
{
char *attval = malloc(sizeof(char) * strlen(ATTVAL));
printf("**** Checking that attribute still exists:\t");
if(nc_get_att_text(ncid,test_id,ATTNAME,attval)) {printf("Fail\n"); ERR;}
else {printf("%s\n",attval);}
free(attval);
}
if (nc_close(ncid)) ERR;
/********************************************/
SUMMARIZE_ERR;
FINAL_RESULTS;
return 0;
}
|