1 /* This is part of the netCDF package.
2    Copyright 2018 University Corporation for Atmospheric Research/Unidata
3    See COPYRIGHT file for conditions of use.
4 
5    Test netcdf-4 group code some more.
6 
7    @author Ed Hartnett
8 */
9 
10 #include <nc_tests.h>
11 #include "err_macros.h"
12 #include "netcdf.h"
13 
14 #define FILE_NAME "tst_grps2.nc"
15 #define DIM1_NAME "kingdom"
16 #define DIM1_LEN 3
17 #define DIM2_NAME "year"
18 #define DIM2_LEN 5
19 #define VAR1_NAME "Number_of_Beheadings_in_Family"
20 #define DYNASTY "Tudor"
21 #define HENRY_VII "Henry_VII"
22 #define MARGARET "Margaret"
23 #define JAMES_V_OF_SCOTLAND "James_V_of_Scotland"
24 #define MARY_I_OF_SCOTLAND "Mary_I_of_Scotland"
25 #define JAMES_VI_OF_SCOTLAND_AND_I_OF_ENGLAND "James_VI_of_Scotland_and_I_of_England"
26 #define MAX_SIBLING_GROUPS 10
27 #define NUM_CASTLES_NAME "Number_of_Castles"
28 
29 int
main(int argc,char ** argv)30 main(int argc, char **argv)
31 {
32    printf("\n*** Testing netcdf-4 group functions.\n");
33    printf("*** testing use of unlimited dim in parent group...");
34    {
35 #define NDIMS_IN_VAR 1
36 #define NDIMS_IN_FILE 2
37 #define BABE_LIMIT 3
38 #define DIM_NAME1 "Influence"
39 #define DIM_NAME2 "Babe_Factor"
40 #define VAR_NAME1 "Court_of_Star_Chamber"
41 #define VAR_NAME2 "Justice_of_the_Peace"
42 #define VAR_NAME3 "Bosworth_Field"
43       int ncid, dimid1, dimid2, varid1, varid2, varid3, henry_vii_id;
44       int grpid_in, varid_in1, varid_in2, varid_in3;
45       nc_type xtype_in;
46       int ndims_in, dimids_in[NDIMS_IN_FILE], dimid1_in, natts;
47       char name_in[NC_MAX_NAME + 1];
48       size_t len_in, index[NDIMS_IN_VAR] = {0};
49       long long value = NC_FILL_INT64 + 1, value_in;
50 
51       /* Create a file with an unlimited dim and a limited, used by
52        * variables in child groups. */
53       if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
54       if (nc_def_dim(ncid, DIM_NAME1, NC_UNLIMITED, &dimid1)) ERR;
55       if (nc_def_dim(ncid, DIM_NAME2, BABE_LIMIT, &dimid2)) ERR;
56       if (nc_def_grp(ncid, HENRY_VII, &henry_vii_id)) ERR;
57       if (nc_def_var(henry_vii_id, VAR_NAME1, NC_INT64, NDIMS_IN_VAR, &dimid1, &varid1)) ERR;
58       if (nc_def_var(henry_vii_id, VAR_NAME2, NC_INT64, NDIMS_IN_VAR, &dimid1, &varid2)) ERR;
59       if (nc_def_var(henry_vii_id, VAR_NAME3, NC_INT64, NDIMS_IN_VAR, &dimid2, &varid3)) ERR;
60 
61       /* Check it out. Find the group by name. */
62       if (nc_inq_ncid(ncid, HENRY_VII, &grpid_in)) ERR;
63 
64       /* Ensure that dimensions in parent are visible and correct. */
65       if (nc_inq_dimids(grpid_in, &ndims_in, dimids_in, 1)) ERR;
66       if (ndims_in != NDIMS_IN_FILE || dimids_in[0] != dimid1 || dimids_in[1] != dimid2) ERR;
67       if (nc_inq_dim(grpid_in, dimids_in[0], name_in, &len_in)) ERR;
68       if (strcmp(name_in, DIM_NAME1) || len_in != 0) ERR;
69       if (nc_inq_dim(grpid_in, dimids_in[1], name_in, &len_in)) ERR;
70       if (strcmp(name_in, DIM_NAME2) || len_in != BABE_LIMIT) ERR;
71 
72       /* Check the vars in the group. */
73       if (nc_inq_varid(grpid_in, VAR_NAME1, &varid_in1)) ERR;
74       if (nc_inq_varid(grpid_in, VAR_NAME2, &varid_in2)) ERR;
75       if (nc_inq_varid(grpid_in, VAR_NAME3, &varid_in3)) ERR;
76       if (varid_in1 != varid1 || varid_in2 != varid2 || varid_in3 != varid3) ERR;
77       if (nc_inq_var(grpid_in, varid1, name_in, &xtype_in, &ndims_in, &dimid1_in, &natts)) ERR;
78       if (strcmp(name_in, VAR_NAME1) || xtype_in != NC_INT64 || ndims_in != NDIMS_IN_VAR ||
79           dimid1_in != dimid1 || natts != 0) ERR;
80       if (nc_inq_var(grpid_in, varid2, name_in, &xtype_in, &ndims_in, &dimid1_in, &natts)) ERR;
81       if (strcmp(name_in, VAR_NAME2) || xtype_in != NC_INT64 || ndims_in != NDIMS_IN_VAR ||
82           dimid1_in != dimid1 || natts != 0) ERR;
83       if (nc_inq_var(grpid_in, varid3, name_in, &xtype_in, &ndims_in, &dimid1_in, &natts)) ERR;
84       if (strcmp(name_in, VAR_NAME3) || xtype_in != NC_INT64 || ndims_in != NDIMS_IN_VAR ||
85           dimid1_in != dimid2 || natts != 0) ERR;
86 
87       /* Write one value to one variable. */
88       if (nc_put_var1_longlong(grpid_in, varid_in1, index, &value)) ERR;
89 
90       /* Read one value from the second unlim dim variable. It should
91        * be the fill value. */
92       if (nc_get_var1_longlong(grpid_in, varid_in2, index, &value_in)) ERR;
93       if (value_in != NC_FILL_INT64) ERR;
94 
95       /* Read one value from the variable with limited dim. It should
96        * be the fill value. */
97       if (nc_get_var1_longlong(grpid_in, varid_in3, index, &value_in)) ERR;
98       if (value_in != NC_FILL_INT64) ERR;
99 
100       /* Attempt to read beyond end of dimensions to generate error. */
101       index[0] = BABE_LIMIT;
102       if (nc_get_var1_longlong(grpid_in, varid_in1, index, &value_in) != NC_EINVALCOORDS) ERR;
103       if (nc_get_var1_longlong(grpid_in, varid_in2, index, &value_in) != NC_EINVALCOORDS) ERR;
104       if (nc_get_var1_longlong(grpid_in, varid_in3, index, &value_in) != NC_EINVALCOORDS) ERR;
105 
106       if (nc_close(ncid)) ERR;
107 
108       /* Check it out again. */
109       if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
110 
111       /* Find the group by name. */
112       if (nc_inq_ncid(ncid, HENRY_VII, &grpid_in)) ERR;
113 
114       /* Ensure that dimensions in parent are visible and correct. */
115       if (nc_inq_dimids(grpid_in, &ndims_in, dimids_in, 1)) ERR;
116       if (ndims_in != NDIMS_IN_FILE || dimids_in[0] != dimid1 || dimids_in[1] != dimid2) ERR;
117       if (nc_inq_dim(grpid_in, dimids_in[0], name_in, &len_in)) ERR;
118       if (strcmp(name_in, DIM_NAME1) || len_in != 1) ERR;
119       if (nc_inq_dim(grpid_in, dimids_in[1], name_in, &len_in)) ERR;
120       if (strcmp(name_in, DIM_NAME2) || len_in != BABE_LIMIT) ERR;
121 
122       /* Check the vars in the group. */
123       if (nc_inq_varid(grpid_in, VAR_NAME1, &varid_in1)) ERR;
124       if (nc_inq_varid(grpid_in, VAR_NAME2, &varid_in2)) ERR;
125       if (nc_inq_varid(grpid_in, VAR_NAME3, &varid_in3)) ERR;
126       if (varid_in1 != varid1 || varid_in2 != varid2 || varid_in3 != varid3) ERR;
127       if (nc_inq_var(grpid_in, varid1, name_in, &xtype_in, &ndims_in, &dimid1_in, &natts)) ERR;
128       if (strcmp(name_in, VAR_NAME1) || xtype_in != NC_INT64 || ndims_in != NDIMS_IN_VAR ||
129           dimid1_in != dimid1 || natts != 0) ERR;
130       if (nc_inq_var(grpid_in, varid2, name_in, &xtype_in, &ndims_in, &dimid1_in, &natts)) ERR;
131       if (strcmp(name_in, VAR_NAME2) || xtype_in != NC_INT64 || ndims_in != NDIMS_IN_VAR ||
132           dimid1_in != dimid1 || natts != 0) ERR;
133       if (nc_inq_var(grpid_in, varid3, name_in, &xtype_in, &ndims_in, &dimid1_in, &natts)) ERR;
134       if (strcmp(name_in, VAR_NAME3) || xtype_in != NC_INT64 || ndims_in != NDIMS_IN_VAR ||
135           dimid1_in != dimid2 || natts != 0) ERR;
136 
137       /* Read one value from the second unlim dim variable. It should
138        * be the fill value. */
139       index[0] = 0;
140       if (nc_get_var1_longlong(grpid_in, varid_in2, index, &value_in)) ERR;
141       if (value_in != NC_FILL_INT64) ERR;
142 
143       /* Read one value from the variable with limited dim. It should
144        * be the fill value. */
145       if (nc_get_var1_longlong(grpid_in, varid_in3, index, &value_in)) ERR;
146       if (value_in != NC_FILL_INT64) ERR;
147 
148       /* Attempt to read beyond end of dimensions to generate error. */
149       index[0] = BABE_LIMIT;
150       if (nc_get_var1_longlong(grpid_in, varid_in1, index, &value_in) != NC_EINVALCOORDS) ERR;
151       if (nc_get_var1_longlong(grpid_in, varid_in2, index, &value_in) != NC_EINVALCOORDS) ERR;
152       if (nc_get_var1_longlong(grpid_in, varid_in3, index, &value_in) != NC_EINVALCOORDS) ERR;
153 
154       if (nc_close(ncid)) ERR;
155    }
156 
157    SUMMARIZE_ERR;
158    printf("*** testing groups and unlimited dimensions...");
159    {
160       int ncid;
161       int henry_vii_id;
162       int tudor_id;
163       int dimids_in[MAX_SIBLING_GROUPS], ndims_in;
164       int num_grps;
165       int dimid, dynasty, varid;
166       size_t len_in;
167       int natts_in;
168       int grpids_in[10];
169       nc_type xtype_in;
170       char name_in[NC_MAX_NAME + 1];
171       int data_out[DIM1_LEN] = {0, 2, 6}, data_in[DIM1_LEN];
172       size_t start[1] = {0}, count[1] = {3};
173       int j;
174 
175       /* Create one group, with one var, which has one dimension, which is unlimited. */
176       if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
177       if (nc_def_grp(ncid, DYNASTY, &tudor_id)) ERR;
178       if (nc_def_dim(tudor_id, DIM1_NAME, NC_UNLIMITED, &dimid)) ERR;
179       if (nc_def_grp(tudor_id, HENRY_VII, &henry_vii_id)) ERR;
180       if (nc_def_var(henry_vii_id, VAR1_NAME, NC_INT, 1, &dimid, &varid)) ERR;
181       if (nc_put_vara_int(henry_vii_id, varid, start, count, data_out)) ERR;
182       if (nc_close(ncid)) ERR;
183 
184       /* Now check the file to see if the dimension and variable are
185        * there. */
186       if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
187       if (nc_inq_grps(ncid, &num_grps, &dynasty)) ERR;
188       if (num_grps != 1) ERR;
189       if (nc_inq_grps(dynasty, &num_grps, grpids_in)) ERR;
190       if (num_grps != 1) ERR;
191       if (nc_inq_dim(grpids_in[0], 0, name_in, &len_in)) ERR;
192       if (strcmp(name_in, DIM1_NAME) || len_in != DIM1_LEN) ERR;
193       if (nc_inq_var(grpids_in[0], 0, name_in, &xtype_in, &ndims_in, dimids_in,
194 		     &natts_in)) ERR;
195       if (strcmp(name_in, VAR1_NAME) || xtype_in != NC_INT || ndims_in != 1 ||
196 	  dimids_in[0] != 0 || natts_in != 0) ERR;
197       if (nc_get_vara_int(grpids_in[0], 0, start, count, data_in)) ERR;
198       for (j=0; j<DIM1_LEN; j++)
199 	 if (data_in[j] != data_out[j]) ERR;
200       if (nc_close(ncid)) ERR;
201    }
202    SUMMARIZE_ERR;
203    FINAL_RESULTS;
204 }
205