forked from Unidata/netcdf-c
/
tst_fill_attr_vanish.c
136 lines (106 loc) · 4.14 KB
/
tst_fill_attr_vanish.c
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;
}