1/*
2 * Demonstrate netcdf-4 rename bug.
3 */
4
5#include <netcdf.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9
10/* On error, prints line number and file of test program. */
11#define ERR do {                                     \
12fflush(stdout);                                      \
13fprintf(stderr, "Unexpected result, %s, line: %d\n", \
14 __FILE____LINE__);                         \
15return 2;                                            \
16} while (0)
17
18#define FILE_NAME3 "tst_rnfix3.nc"
19#define FILE_NAME4 "tst_rnfix4.nc"
20#define ODIM_NAME "lat" /* name for coord dim */
21#define NDIM_NAME "tal" /* new name for coord dim */
22#define OVAR_NAME "lat" /* name for coord var */
23#define NVAR_NAME "tal" /* new name for coord var */
24#define OVAR2_NAME "rh" /* name for non-coord var that uses coord dim */
25#define VAR_RANK 1 /* all vars in this test are of same rank */
26#define DIM_LEN 2 /* all dims in this test are of same len */
27
28/* For renaming tests.  Create small test file of specified format
29 * with a coordinate dimension, corresponding coordinate variable, and
30 * a non-coordinate variable that uses the coordinate dimension.
31 */
32int
33create_test_file(
34    char *path, /* filename */
35    int format /* NC_FORMAT_CLASSIC, NC_FORMAT_64BIT,
36    NC_FORMAT_NETCDF4, or NC_FORMAT_NETCDF4_CLASSIC */
37    )
38{
39    int nciddimidvaridvar2id;
40    int dims[VAR_RANK];
41    int lats[DIM_LEN] = {-90, 90};
42    float rh[DIM_LEN] = {0.25, 0.75};
43    switch (format) {
44    case (NC_FORMAT_CLASSIC):
45 if (nc_create(path, 0, &ncid)) ERR;
46 break;
47    case (NC_FORMAT_64BIT_OFFSET):
48 if (nc_create(pathNC_64BIT_OFFSET, &ncid)) ERR;
49 break;
50    case (NC_FORMAT_NETCDF4):
51 if (nc_create(pathNC_NETCDF4, &ncid)) ERR;
52 break;
53    case(NC_FORMAT_NETCDF4_CLASSIC):
54 if (nc_create(pathNC_NETCDF4 | NC_CLASSIC_MODEL, &ncid)) ERR;
55 break;
56    default:
57 ERR;
58 return NC_ENOTNC;
59    }
60    if (nc_def_dim(ncidODIM_NAMEDIM_LEN, &dimid)) ERR;
61    dims[0] = dimid;
62    if (nc_def_var(ncidOVAR_NAMENC_INTVAR_RANKdims, &varid)) ERR;
63    if (nc_def_var(ncidOVAR2_NAMENC_FLOATVAR_RANKdims, &var2id)) ERR;
64    if (nc_enddef(ncid)) ERR; /* not necessary for netCDF-4 files */
65    if (nc_put_var_int(ncidvaridlats)) ERR;
66    if (nc_put_var_float(ncidvar2idrh)) ERR;
67    if (nc_close(ncid)) ERR;
68    return 0;
69}
70
71int
72main(int argc, char **argv)
73{
74#define NUM_FORMATS 2
75  int formats[NUM_FORMATS] = {NC_FORMAT_NETCDF4NC_FORMAT_NETCDF4_CLASSIC};
76  char *fmt_names[] = {"netCDF-4", "netCDF-4 classic model"};
77  char *file_names[] = {FILE_NAME3FILE_NAME4};
78  int format;
79
80  fprintf(stderr,"*** Testing netcdf rename bugs and fixes.\n");
81
82  for(format = 0; format < NUM_FORMATSformat++)
83    {
84      int nciddimidvaridvar2id;
85      int lats[DIM_LEN] = {-90, 90};
86      int lats_in[DIM_LEN];
87      float rh[DIM_LEN] = {0.25, 0.75};
88      float rh_in[DIM_LEN];
89      int ii;
90
91      fprintf(stderr,"*** Test renaming coordinate variable and its dimension for %s...\n",
92      fmt_names[format]);
93      if (create_test_file(file_names[format], formats[format])) ERR;
94      if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
95      if (nc_inq_dimid(ncidODIM_NAME, &dimid)) ERR;
96      if (nc_inq_varid(ncidOVAR_NAME, &varid)) ERR;
97      if (nc_inq_varid(ncidOVAR2_NAME, &var2id)) ERR;
98      if (nc_redef(ncid)) ERR; /* omitting this and nc_enddef call eliminates bug */
99      if (nc_rename_dim(nciddimidNDIM_NAME)) ERR;
100      if (nc_rename_var(ncidvaridNVAR_NAME)) ERR;
101      if (nc_enddef(ncid)) ERR;
102      if (nc_get_var_int(ncidvaridlats_in)) ERR;
103      for (ii = 0; ii < DIM_LENii++) {
104 if (lats_in[ii] != lats[ii])
105   fprintf(stderr, "\tlats_in[%d] is %d, should be %d\n", iilats_in[ii], lats[ii]);
106      }
107      if (nc_get_var_float(ncidvar2idrh_in)) ERR;
108      for (ii = 0; ii < DIM_LENii++) {
109 if (rh_in[ii] != rh[ii])
110   fprintf(stderr, "\trh_in[%d] is %g, should be %g\n", iirh_in[ii], rh[ii]);
111      }
112      if (nc_close(ncid)) ERR;
113
114      fprintf(stderr,"*** Test renaming just coordinate variable for %s...\n",
115      fmt_names[format]);
116      if (create_test_file(file_names[format], formats[format])) ERR;
117      if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
118      if (nc_inq_dimid(ncidODIM_NAME, &dimid)) ERR;
119      if (nc_inq_varid(ncidOVAR_NAME, &varid)) ERR;
120      if (nc_inq_varid(ncidOVAR2_NAME, &var2id)) ERR;
121      if (nc_redef(ncid)) ERR;  /* omitting this and nc_enddef call eliminates bug */
122      /* if (nc_rename_dim(ncid, dimid, NDIM_NAME)) ERR; */
123      if (nc_rename_var(ncidvaridNVAR_NAME)) ERR;
124      if (nc_enddef(ncid)) ERR;
125      if (nc_get_var_int(ncidvaridlats_in)) ERR;
126      for (ii = 0; ii < DIM_LENii++) {
127 if (lats_in[ii] != lats[ii])
128   fprintf(stderr, "\tlats_in[%d] is %d, should be %d\n", iilats_in[ii], lats[ii]);
129      }
130      if (nc_get_var_float(ncidvar2idrh_in)) ERR;
131      for (ii = 0; ii < DIM_LENii++) {
132 if (rh_in[ii] != rh[ii])
133   fprintf(stderr, "\trh_in[%d] is %g, should be %g\n", iirh_in[ii], rh[ii]);
134      }
135      if (nc_close(ncid)) ERR;
136
137
138      fprintf(stderr,"*** Test renaming just coordinate dimension for %s...\n",
139      fmt_names[format]);
140      if (create_test_file(file_names[format], formats[format])) ERR;
141      if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
142      if (nc_inq_dimid(ncidODIM_NAME, &dimid)) ERR;
143      if (nc_inq_varid(ncidOVAR_NAME, &varid)) ERR;
144      if (nc_inq_varid(ncidOVAR2_NAME, &var2id)) ERR;
145      if (nc_redef(ncid)) ERR; /* omitting this and nc_enddef call eliminates bug */
146      if (nc_rename_dim(nciddimidNDIM_NAME)) ERR;
147      /* if (nc_rename_var(ncid, varid, NVAR_NAME)) ERR; */
148      if (nc_enddef(ncid)) ERR;
149      if (nc_get_var_int(ncidvaridlats_in)) ERR;
150      for (ii = 0; ii < DIM_LENii++) {
151 if (lats_in[ii] != lats[ii])
152   fprintf(stderr, "\tlats_in[%d] is %d, should be %d\n", iilats_in[ii], lats[ii]);
153      }
154      if (nc_get_var_float(ncidvar2idrh_in)) ERR;
155      for (ii = 0; ii < DIM_LENii++) {
156 if (rh_in[ii] != rh[ii])
157   fprintf(stderr, "\trh_in[%d] is %g, should be %g\n", iirh_in[ii], rh[ii]);
158      }
159      if (nc_close(ncid)) ERR;
160
161      if (formats[format] == NC_FORMAT_NETCDF4) {
162          printf("*** Test renaming attribute in sub-group for %s...\n",
163                fmt_names[format]);
164          {
165#define DIMNAME "lon"
166#define VARNAME "lon"
167#define G1_VARNAME "lon"
168#define OLD_NAME "units"
169#define NEW_NAME "new_units"
170#define CONTENTS "degrees_east"
171#define RANK_lon 1
172#define GRP_NAME "g1"
173#define RANK_g1_lon 1
174
175            /* IDs of file, groups, dimensions, variables, attributes */
176            int ncidg1_grplon_dimlon_varg1_lon_varunits_att;
177            size_t lon_len = 4;
178            char *data_in;
179
180            /* variable shapes */
181            int lon_dims[RANK_lon];
182            int g1_lon_dims[RANK_g1_lon];
183
184            if (!(data_in = malloc(strlen(CONTENTS) + 1))) ERR;
185
186            /* Create test file */
187            if (nc_create(file_names[format], NC_NETCDF4 | NC_CLOBBER, &ncid)) ERR;
188            /* Create subgroup and outer dimension */
189            if (nc_def_grp(ncidGRP_NAME, &g1_grp)) ERR;
190            if (nc_def_dim(ncidDIMNAMElon_len, &lon_dim)) ERR;
191            /* Create outer variable and subgroup variable */
192            lon_dims[0] = lon_dim;
193            if (nc_def_var(ncidVARNAMENC_FLOATRANK_lonlon_dims, &lon_var)) ERR;
194            g1_lon_dims[0] = lon_dim;
195            if (nc_def_var(g1_grpG1_VARNAMENC_FLOATRANK_g1_long1_lon_dims, &g1_lon_var)) ERR;
196            /* assign per-variable attributes */
197            if (nc_put_att_text(ncidlon_varOLD_NAME, strlen(CONTENTS), CONTENTS)) ERR;
198            if (nc_put_att_text(g1_grpg1_lon_varOLD_NAME, strlen(CONTENTS), CONTENTS)) ERR;
199            if (nc_enddef (ncid)) ERR;
200            /* write variable data */
201            {
202              float lon_data[4] = {0, 90, 180, 270};
203              size_t start[] = {0};
204              size_t count[] = {4};
205              if (nc_put_vara(ncidlon_varstartcountlon_data)) ERR;
206            }
207            {
208              float g1_lon_data[4] = {0, 90, 180, 270};
209              size_t start[] = {0};
210              size_t count[] = {4};
211              if (nc_put_vara(g1_grpg1_lon_varstartcountg1_lon_data)) ERR;
212            }
213            if (nc_close(ncid)) ERR;
214
215            /* reopen the file and rename the attribute in the subgroup */
216            if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
217            if (nc_inq_grp_ncid(ncidGRP_NAME, &g1_grp)) ERR;
218            if (nc_inq_varid(g1_grp,VARNAME,&g1_lon_var)) ERR;
219            if (nc_rename_att(g1_grpg1_lon_varOLD_NAMENEW_NAME)) ERR;
220            if (nc_close(ncid)) ERR;
221
222            /* reopen the file again and see if renamed attribute exists and
223               has expected value */
224            {
225              nc_type att_type;
226              size_t att_len;
227
228              if (nc_open(file_names[format], NC_NOWRITE, &ncid)) ERR;
229              if (nc_inq_grp_ncid(ncidGRP_NAME, &g1_grp)) ERR;
230              if (nc_inq_varid(g1_grpVARNAME, &g1_lon_var)) ERR;
231              if (nc_get_att_text(g1_grpg1_lon_varNEW_NAMEdata_in)) ERR;
232              if (strncmp(CONTENTSdata_in, strlen(CONTENTS))) ERR;
233              if (nc_close(ncid)) ERR;
234            }
235            free(data_in);
236          }
237      }
238    }
239
240  return(0);
241}


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed