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.
6
7 Ed Hartnett
8 */
9
10 #include <nc_tests.h>
11 #include "err_macros.h"
12 #include "netcdf.h"
13
14 #define FILE_NAME "tst_grps.nc"
15 #define FILE_NAME_CLASSIC "tst_grps_classic.nc"
16 #define FILE_NAME_CLASSIC_MODEL "tst_grps_classic_model.nc"
17 #define DIM1_NAME "kingdom"
18 #define DIM1_LEN 3
19 #define DIM2_NAME "year"
20 #define DIM2_LEN 5
21 #define VAR1_NAME "Number_of_Beheadings_in_Family"
22 #define DYNASTY "Tudor"
23 #define HENRY_IV "Henry_IV"
24 #define HENRY_VII "Henry_VII"
25 #define HENRY_VIII "Henry_VIII"
26 #define MARGARET "Margaret"
27 #define JAMES_V_OF_SCOTLAND "James_V_of_Scotland"
28 #define MARY_I_OF_SCOTLAND "Mary_I_of_Scotland"
29 #define JAMES_VI_OF_SCOTLAND_AND_I_OF_ENGLAND "James_VI_of_Scotland_and_I_of_England"
30 #define MAX_SIBLING_GROUPS 10
31 #define NUM_CASTLES_NAME "Number_of_Castles"
32
33 int
main(int argc,char ** argv)34 main(int argc, char **argv)
35 {
36 printf("\n*** Testing netcdf-4 group functions.\n");
37 printf("*** testing simple group create...");
38 {
39 int ncid, ncid2;
40 char name_in[NC_MAX_NAME + 1];
41 int henry_vii_id;
42 int henry_viii_id;
43 int grpid_in[MAX_SIBLING_GROUPS], varids_in[MAX_SIBLING_GROUPS];
44 int nvars_in, ncid_in;
45 int parent_ncid;
46 char name_out[NC_MAX_NAME + 1];
47 int num_grps;
48
49 /* Create a netCDF classic file. Groups will not be allowed. */
50 if (nc_create(FILE_NAME_CLASSIC, 0, &ncid2)) ERR;
51 if (nc_def_grp(ncid2, name_out, &henry_vii_id) != NC_ENOTNC4) ERR;
52 if (nc_close(ncid2)) ERR;
53
54 /* Create a file with one group, a group to contain data about
55 * Henry VII. */
56 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
57 if (nc_inq_grp_parent(ncid, &parent_ncid) != NC_ENOGRP) ERR;
58 /* This should also work as simple "is this the root group" test */
59 if (nc_inq_grp_parent(ncid, NULL) != NC_ENOGRP) ERR;
60 strcpy(name_out, HENRY_VII);
61
62 /* These will not work. */
63 if (nc_def_grp(ncid + TEST_VAL_42, name_out, &henry_vii_id) != NC_EBADID) ERR;
64 if (nc_def_grp(ncid, NULL, &henry_vii_id) != NC_EINVAL) ERR;
65 if (nc_def_grp(ncid, BAD_NAME, &henry_vii_id) != NC_EBADNAME) ERR;
66
67 /* Define the group. */
68 if (nc_def_grp(ncid, name_out, &henry_vii_id)) ERR;
69
70 /* Check it out. */
71 if (nc_inq_grp_parent(henry_vii_id, &parent_ncid)) ERR;
72 if (parent_ncid != ncid) ERR;
73 if (nc_inq_ncid(ncid, HENRY_VII, &ncid_in)) ERR;
74 if (ncid_in != henry_vii_id) ERR;
75 if (nc_inq_ncid(ncid, MARGARET, &ncid_in) != NC_ENOGRP) ERR;
76 if (nc_close(ncid)) ERR;
77
78 /* Check it out. */
79 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
80 if (nc_inq_grp_parent(ncid, &parent_ncid) != NC_ENOGRP) ERR;
81 if (nc_inq_grps(ncid, &num_grps, NULL)) ERR;
82 if (num_grps != 1) ERR;
83 if (nc_inq_grps(ncid, NULL, grpid_in)) ERR;
84 if (nc_inq_grpname(ncid, name_in)) ERR;
85 if (strcmp(name_in, "/")) ERR;
86 if (nc_inq_grpname(grpid_in[0], name_in)) ERR;
87 if (nc_inq_grp_parent(grpid_in[0], &parent_ncid)) ERR;
88 if (parent_ncid != ncid) ERR;
89 if (strcmp(name_in, HENRY_VII)) ERR;
90 if (nc_inq_varids(grpid_in[0], &nvars_in, varids_in)) ERR;
91 if (nvars_in != 0) ERR;
92 if (nc_inq_varids(grpid_in[0], NULL, varids_in)) ERR;
93 if (nc_inq_varids(grpid_in[0], &nvars_in, NULL)) ERR;
94 if (nc_inq_varids(grpid_in[0], NULL, NULL)) ERR;
95
96 if (nc_inq_ncid(ncid, HENRY_VII, &ncid_in)) ERR;
97 if (ncid_in != grpid_in[0]) ERR;
98
99 /* These should fail - file is read-only. */
100 if (nc_def_grp(ncid, HENRY_VIII, &henry_viii_id) != NC_EPERM) ERR;
101 if (nc_rename_grp(grpid_in[0], HENRY_VIII) != NC_EPERM) ERR;
102
103 /* Close the file. */
104 if (nc_close(ncid)) ERR;
105 }
106 SUMMARIZE_ERR;
107 printf("*** testing simple group rename...");
108 {
109 int ncid, ncid2;
110 int grpid_in;
111 char name_in[NC_MAX_NAME + 1];
112 int henry_vii_id;
113
114 /* Create a classic model file. No groups will be allowed. */
115 if (nc_create(FILE_NAME_CLASSIC_MODEL, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid2)) ERR;
116 if (nc_def_grp(ncid2, HENRY_VII, &henry_vii_id) != NC_ESTRICTNC3) ERR;
117 if (nc_def_var(ncid2, HENRY_IV, NC_INT, 0, NULL, NULL)) ERR;
118 if (nc_close(ncid2)) ERR;
119
120 /* Create a file with one group, a group to contain data about
121 * Henry VII. */
122 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
123 if (nc_def_var(ncid, HENRY_IV, NC_INT, 0, NULL, NULL)) ERR;
124
125 /* Turn off define mode. It will automatically be turned back on
126 * when nc_def_grp is called. */
127 if (nc_enddef(ncid)) ERR;
128 if (nc_def_grp(ncid, HENRY_VII, &henry_vii_id)) ERR;
129
130 /* Check it out. */
131 if (nc_inq_grpname(henry_vii_id, name_in)) ERR;
132 if (strcmp(name_in, HENRY_VII)) ERR;
133
134 /* These will not work. */
135 if (nc_rename_grp(henry_vii_id, BAD_NAME) != NC_EBADNAME) ERR;
136 if (nc_rename_grp(henry_vii_id, HENRY_IV) != NC_ENAMEINUSE) ERR;
137 if (nc_rename_grp(ncid, HENRY_IV) != NC_EBADGRPID) ERR;
138
139 /* Rename the group. */
140 if (nc_rename_grp(henry_vii_id, HENRY_VIII)) ERR;
141
142 /* Check it out. */
143 if (nc_inq_grpname(henry_vii_id, name_in)) ERR;
144 if (strcmp(name_in, HENRY_VIII)) ERR;
145
146 /* Close the file. */
147 if (nc_close(ncid)) ERR;
148
149 /* Re-open the file. */
150 if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
151
152 /* Check it out. */
153 if (nc_inq_grps(ncid, NULL, &grpid_in)) ERR;
154 if (nc_inq_grpname(grpid_in, name_in)) ERR;
155 if (strcmp(name_in, HENRY_VIII)) ERR;
156
157 /* Rename it. */
158 if (nc_rename_grp(grpid_in, HENRY_VII)) ERR;
159 if (nc_inq_grpname(grpid_in, name_in)) ERR;
160 if (strcmp(name_in, HENRY_VII)) ERR;
161
162 /* Close the file. */
163 if (nc_close(ncid)) ERR;
164 }
165 SUMMARIZE_ERR;
166
167 printf("*** testing netcdf-3 and group functions...");
168 {
169 int ncid;
170 char name_in[NC_MAX_NAME + 1];
171 size_t len_in;
172
173 /* Create a classic file. */
174 if (nc_create(FILE_NAME, NC_CLOBBER, &ncid)) ERR;
175 if (nc_inq_grpname(ncid, name_in)) ERR;
176 if (strcmp(name_in, "/")) ERR;
177 if (nc_inq_grpname_full(ncid, &len_in, name_in)) ERR;
178 if (strcmp(name_in, "/") || len_in != 1) ERR;
179 if (nc_close(ncid)) ERR;
180 }
181 SUMMARIZE_ERR;
182
183 printf("*** testing use of unlimited dim in parent group...");
184 {
185 #define NDIMS_IN_VAR 1
186 #define NDIMS_IN_FILE 2
187 #define BABE_LIMIT 3
188 #define DIM_NAME1 "Influence"
189 #define DIM_NAME2 "Babe_Factor"
190 #define VAR_NAME1 "Court_of_Star_Chamber"
191 #define VAR_NAME2 "Justice_of_the_Peace"
192 #define VAR_NAME3 "Bosworth_Field"
193 int ncid, dimid1, dimid2, varid1, varid2, varid3, henry_vii_id;
194 int grpid_in, varid_in1, varid_in2, varid_in3;
195 nc_type xtype_in;
196 int ndims_in, dimids_in[NDIMS_IN_FILE], dimid1_in, natts;
197 char name_in[NC_MAX_NAME + 1];
198 size_t len_in, index[NDIMS_IN_VAR] = {0};
199 long long value = NC_FILL_INT64 + 1, value_in;
200
201 /* Create a file with an unlimited dim and a limited, used by
202 * variables in child groups. */
203 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
204 if (nc_def_dim(ncid, DIM_NAME1, NC_UNLIMITED, &dimid1)) ERR;
205 if (nc_def_dim(ncid, DIM_NAME2, BABE_LIMIT, &dimid2)) ERR;
206 if (nc_def_grp(ncid, HENRY_VII, &henry_vii_id)) ERR;
207 if (nc_def_var(henry_vii_id, VAR_NAME1, NC_INT64, NDIMS_IN_VAR, &dimid1, &varid1)) ERR;
208 if (nc_def_var(henry_vii_id, VAR_NAME2, NC_INT64, NDIMS_IN_VAR, &dimid1, &varid2)) ERR;
209 if (nc_def_var(henry_vii_id, VAR_NAME3, NC_INT64, NDIMS_IN_VAR, &dimid2, &varid3)) ERR;
210
211 /* These won't work. */
212 if (nc_inq_ncid(ncid + TEST_VAL_42, HENRY_VII, &grpid_in) != NC_EBADID) ERR;
213
214 /* Check it out. Find the group by name. */
215 if (nc_inq_ncid(ncid, HENRY_VII, &grpid_in)) ERR;
216
217 /* Ensure that dimensions in parent are visible and correct. */
218 memset(dimids_in,0,sizeof(dimids_in));
219 if (nc_inq_dimids(grpid_in, &ndims_in, dimids_in, 1)) ERR;
220 if (ndims_in != NDIMS_IN_FILE || dimids_in[0] != dimid1 || dimids_in[1] != dimid2) ERR;
221 if (nc_inq_dim(grpid_in, dimids_in[0], name_in, &len_in)) ERR;
222 if (strcmp(name_in, DIM_NAME1) || len_in != 0) ERR;
223 if (nc_inq_dim(grpid_in, dimids_in[1], name_in, &len_in)) ERR;
224 if (strcmp(name_in, DIM_NAME2) || len_in != BABE_LIMIT) ERR;
225
226 /* Check the vars in the group. */
227 if (nc_inq_varid(grpid_in, VAR_NAME1, &varid_in1)) ERR;
228 if (nc_inq_varid(grpid_in, VAR_NAME2, &varid_in2)) ERR;
229 if (nc_inq_varid(grpid_in, VAR_NAME3, &varid_in3)) ERR;
230 if (varid_in1 != varid1 || varid_in2 != varid2 || varid_in3 != varid3) ERR;
231 if (nc_inq_var(grpid_in, varid1, name_in, &xtype_in, &ndims_in, &dimid1_in, &natts)) ERR;
232 if (strcmp(name_in, VAR_NAME1) || xtype_in != NC_INT64 || ndims_in != NDIMS_IN_VAR ||
233 dimid1_in != dimid1 || natts != 0) ERR;
234 if (nc_inq_var(grpid_in, varid2, name_in, &xtype_in, &ndims_in, &dimid1_in, &natts)) ERR;
235 if (strcmp(name_in, VAR_NAME2) || xtype_in != NC_INT64 || ndims_in != NDIMS_IN_VAR ||
236 dimid1_in != dimid1 || natts != 0) ERR;
237 if (nc_inq_var(grpid_in, varid3, name_in, &xtype_in, &ndims_in, &dimid1_in, &natts)) ERR;
238 if (strcmp(name_in, VAR_NAME3) || xtype_in != NC_INT64 || ndims_in != NDIMS_IN_VAR ||
239 dimid1_in != dimid2 || natts != 0) ERR;
240
241 /* Write one value to one variable. */
242 if (nc_put_var1_longlong(grpid_in, varid_in1, index, &value)) ERR;
243
244 /* Read one value from the second unlim dim variable. It should
245 * be the fill value. */
246 if (nc_get_var1_longlong(grpid_in, varid_in2, index, &value_in)) ERR;
247 if (value_in != NC_FILL_INT64) ERR;
248
249 /* Read one value from the variable with limited dim. It should
250 * be the fill value. */
251 if (nc_get_var1_longlong(grpid_in, varid_in3, index, &value_in)) ERR;
252 if (value_in != NC_FILL_INT64) ERR;
253
254 /* Attempt to read beyond end of dimensions to generate error. */
255 index[0] = BABE_LIMIT;
256 if (nc_get_var1_longlong(grpid_in, varid_in1, index, &value_in) != NC_EINVALCOORDS) ERR;
257 if (nc_get_var1_longlong(grpid_in, varid_in2, index, &value_in) != NC_EINVALCOORDS) ERR;
258 if (nc_get_var1_longlong(grpid_in, varid_in3, index, &value_in) != NC_EINVALCOORDS) ERR;
259
260 if (nc_close(ncid)) ERR;
261
262 /* Check it out again. */
263 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
264
265 /* Find the group by name. */
266 if (nc_inq_ncid(ncid, HENRY_VII, &grpid_in)) ERR;
267
268 /* Ensure that dimensions in parent are visible and correct. */
269 if (nc_inq_dimids(grpid_in, &ndims_in, dimids_in, 1)) ERR;
270 if (ndims_in != NDIMS_IN_FILE || dimids_in[0] != dimid1 || dimids_in[1] != dimid2) ERR;
271 if (nc_inq_dim(grpid_in, dimids_in[0], name_in, &len_in)) ERR;
272 if (strcmp(name_in, DIM_NAME1) || len_in != 1) ERR;
273 if (nc_inq_dim(grpid_in, dimids_in[1], name_in, &len_in)) ERR;
274 if (strcmp(name_in, DIM_NAME2) || len_in != BABE_LIMIT) ERR;
275
276 /* Check the vars in the group. */
277 if (nc_inq_varid(grpid_in, VAR_NAME1, &varid_in1)) ERR;
278 if (nc_inq_varid(grpid_in, VAR_NAME2, &varid_in2)) ERR;
279 if (nc_inq_varid(grpid_in, VAR_NAME3, &varid_in3)) ERR;
280 if (varid_in1 != varid1 || varid_in2 != varid2 || varid_in3 != varid3) ERR;
281 if (nc_inq_var(grpid_in, varid1, name_in, &xtype_in, &ndims_in, &dimid1_in, &natts)) ERR;
282 if (strcmp(name_in, VAR_NAME1) || xtype_in != NC_INT64 || ndims_in != NDIMS_IN_VAR ||
283 dimid1_in != dimid1 || natts != 0) ERR;
284 if (nc_inq_var(grpid_in, varid2, name_in, &xtype_in, &ndims_in, &dimid1_in, &natts)) ERR;
285 if (strcmp(name_in, VAR_NAME2) || xtype_in != NC_INT64 || ndims_in != NDIMS_IN_VAR ||
286 dimid1_in != dimid1 || natts != 0) ERR;
287 if (nc_inq_var(grpid_in, varid3, name_in, &xtype_in, &ndims_in, &dimid1_in, &natts)) ERR;
288 if (strcmp(name_in, VAR_NAME3) || xtype_in != NC_INT64 || ndims_in != NDIMS_IN_VAR ||
289 dimid1_in != dimid2 || natts != 0) ERR;
290
291 /* Read one value from the second unlim dim variable. It should
292 * be the fill value. */
293 index[0] = 0;
294 if (nc_get_var1_longlong(grpid_in, varid_in2, index, &value_in)) ERR;
295 if (value_in != NC_FILL_INT64) ERR;
296
297 /* Read one value from the variable with limited dim. It should
298 * be the fill value. */
299 if (nc_get_var1_longlong(grpid_in, varid_in3, index, &value_in)) ERR;
300 if (value_in != NC_FILL_INT64) ERR;
301
302 /* Attempt to read beyond end of dimensions to generate error. */
303 index[0] = BABE_LIMIT;
304 if (nc_get_var1_longlong(grpid_in, varid_in1, index, &value_in) != NC_EINVALCOORDS) ERR;
305 if (nc_get_var1_longlong(grpid_in, varid_in2, index, &value_in) != NC_EINVALCOORDS) ERR;
306 if (nc_get_var1_longlong(grpid_in, varid_in3, index, &value_in) != NC_EINVALCOORDS) ERR;
307
308 if (nc_close(ncid)) ERR;
309 }
310 SUMMARIZE_ERR;
311
312 printf("*** testing simple nested group creates...");
313 {
314 char root_name[] = "/";
315 int ncid, grp_ncid;
316 int henry_vii_id, margaret_id, james_v_of_scotland_id, mary_i_of_scotland_id;
317 char name_in[NC_MAX_NAME + 1];
318 char full_name[NC_MAX_NAME * 10], full_name_in[NC_MAX_NAME * 10];
319 char full_name_in1[NC_MAX_NAME * 10];
320 char wrong_name[NC_MAX_NAME * 10];
321 int grpid_in[MAX_SIBLING_GROUPS];
322 int grp_in;
323 int grp_in2;
324 int num_grps;
325 size_t len, len1;
326
327 /* This name is wrong. */
328 strcpy(wrong_name, "/");
329 strcat(wrong_name, HENRY_VII);
330 strcpy(wrong_name, "/");
331 strcat(wrong_name, MARGARET);
332 strcpy(wrong_name, "/");
333 strcat(wrong_name, MARGARET);
334
335 /* Create a file with some nested groups in it, suitable
336 * to storing information about the Tudor dynasty of England. */
337 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
338 if (nc_def_grp(ncid, HENRY_VII, &henry_vii_id)) ERR;
339 if (nc_def_grp(henry_vii_id, MARGARET, &margaret_id)) ERR;
340 if (nc_def_grp(margaret_id, JAMES_V_OF_SCOTLAND, &james_v_of_scotland_id)) ERR;
341 if (nc_def_grp(james_v_of_scotland_id, MARY_I_OF_SCOTLAND, &mary_i_of_scotland_id)) ERR;
342 /* nc_def_grp will accept NULL as ID pointer. Group will be
343 * created, but ID not returned. */
344 if (nc_def_grp(mary_i_of_scotland_id, JAMES_VI_OF_SCOTLAND_AND_I_OF_ENGLAND, NULL)) ERR;
345
346 strcpy(full_name, "/");
347 if (nc_inq_grpname_full(ncid, &len, full_name_in)) ERR;
348 if (len != 1 || strcmp(full_name_in, full_name)) ERR;
349 if (nc_inq_grpname_len(ncid, &len)) ERR;
350 if (len != 1) ERR;
351
352 /* These won't work. */
353 if (nc_inq_grp_full_ncid(ncid + TEST_VAL_42, full_name, &grp_in) != NC_EBADID) ERR;
354 if (nc_inq_grp_full_ncid(ncid, NULL, &grp_in) != NC_EINVAL) ERR;
355
356 /* Get the ncid from the full name. */
357 if (nc_inq_grp_full_ncid(ncid, full_name, &grp_in)) ERR;
358 if (grp_in != ncid) ERR;
359
360 /* Works (pretty pointlessly) with NULL for ID pointer. */
361 if (nc_inq_grp_full_ncid(ncid, full_name, NULL)) ERR;
362
363 /* Get the root group ID from '/'. */
364 if (nc_inq_grp_full_ncid(ncid, root_name, &grp_in2)) ERR;
365 if (grp_in2 != ncid) ERR;
366
367 /* But the root group does not exist within another group. */
368 if (nc_inq_grp_full_ncid(mary_i_of_scotland_id, root_name, &grp_in2) != NC_ENOGRP) ERR;
369
370 /* This name is wrong. */
371 if (nc_inq_grp_full_ncid(ncid, wrong_name, &grp_in2) != NC_ENOGRP) ERR;
372
373 if (nc_inq_grp_ncid(ncid, HENRY_VII, NULL)) ERR;
374 if (nc_inq_grp_ncid(ncid, HENRY_VII, &grp_ncid)) ERR;
375 if (nc_inq_grps(ncid, &num_grps, NULL)) ERR;
376 if (num_grps != 1) ERR;
377 if (nc_inq_grps(ncid, NULL, grpid_in)) ERR;
378 if (nc_inq_grpname(grpid_in[0], name_in)) ERR;
379 if (strcmp(name_in, HENRY_VII)) ERR;
380 if (nc_inq_grpname(grpid_in[0], NULL)) ERR;
381 if (grpid_in[0] != grp_ncid) ERR;
382 strcat(full_name, HENRY_VII);
383 if (nc_inq_grpname_full(grpid_in[0], &len, full_name_in)) ERR;
384 if (len != strlen(HENRY_VII) + 1 || strcmp(full_name_in, full_name)) ERR;
385 if (nc_inq_grp_full_ncid(ncid, full_name, &grp_in)) ERR;
386 if (grp_in != grpid_in[0]) ERR;
387
388 /* Also works with NULL last param. */
389 if (nc_inq_grp_full_ncid(ncid, full_name, NULL)) ERR;
390
391 if (nc_inq_grp_ncid(grpid_in[0], MARGARET, &grp_ncid)) ERR;
392 if (nc_inq_grps(grpid_in[0], &num_grps, grpid_in)) ERR;
393 if (num_grps != 1) ERR;
394 if (nc_inq_grpname(grpid_in[0], name_in)) ERR;
395 if (strcmp(name_in, MARGARET)) ERR;
396 if (grpid_in[0] != grp_ncid) ERR;
397 strcat(full_name, "/");
398 strcat(full_name, MARGARET);
399 if (nc_inq_grpname_full(grpid_in[0], &len, full_name_in)) ERR;
400 if (len != strlen(full_name) || strcmp(full_name_in, full_name)) ERR;
401 if (nc_inq_grp_full_ncid(ncid, full_name, &grp_in)) ERR;
402 if (grp_in != grpid_in[0]) ERR;
403
404 if (nc_inq_grp_ncid(grpid_in[0], JAMES_V_OF_SCOTLAND, &grp_ncid)) ERR;
405 if (nc_inq_grps(grpid_in[0], &num_grps, grpid_in)) ERR;
406 if (num_grps != 1) ERR;
407 if (nc_inq_grpname(grpid_in[0], name_in)) ERR;
408 if (strcmp(name_in, JAMES_V_OF_SCOTLAND)) ERR;
409 if (grpid_in[0] != grp_ncid) ERR;
410 strcat(full_name, "/");
411 strcat(full_name, JAMES_V_OF_SCOTLAND);
412 if (nc_inq_grpname_full(grpid_in[0], &len, full_name_in)) ERR;
413 if (len != strlen(full_name) || strcmp(full_name_in, full_name)) ERR;
414 if (nc_inq_grp_full_ncid(ncid, full_name, &grp_in)) ERR;
415 if (grp_in != grpid_in[0]) ERR;
416
417 if (nc_inq_grp_ncid(grpid_in[0], MARY_I_OF_SCOTLAND, &grp_ncid)) ERR;
418 if (nc_inq_grps(grpid_in[0], &num_grps, grpid_in)) ERR;
419 if (num_grps != 1) ERR;
420 if (nc_inq_grpname(grpid_in[0], name_in)) ERR;
421 if (strcmp(name_in, MARY_I_OF_SCOTLAND)) ERR;
422 if (grpid_in[0] != grp_ncid) ERR;
423 strcat(full_name, "/");
424 strcat(full_name, MARY_I_OF_SCOTLAND);
425 if (nc_inq_grpname_full(grpid_in[0], &len, full_name_in)) ERR;
426 if (len != strlen(full_name) || strcmp(full_name_in, full_name)) ERR;
427 if (nc_inq_grp_full_ncid(ncid, full_name, &grp_in)) ERR;
428 if (grp_in != grpid_in[0]) ERR;
429
430 if (nc_inq_grp_ncid(grpid_in[0], JAMES_VI_OF_SCOTLAND_AND_I_OF_ENGLAND, &grp_ncid)) ERR;
431 if (nc_inq_grps(grpid_in[0], &num_grps, grpid_in)) ERR;
432 if (num_grps != 1) ERR;
433 if (nc_inq_grpname(grpid_in[0], name_in)) ERR;
434 if (strcmp(name_in, JAMES_VI_OF_SCOTLAND_AND_I_OF_ENGLAND)) ERR;
435 if (grpid_in[0] != grp_ncid) ERR;
436 strcat(full_name, "/");
437 strcat(full_name, JAMES_VI_OF_SCOTLAND_AND_I_OF_ENGLAND);
438 if (nc_inq_grpname_full(grpid_in[0], &len, full_name_in)) ERR;
439 if (len != strlen(full_name) || strcmp(full_name_in, full_name)) ERR;
440 if (nc_inq_grp_full_ncid(ncid, full_name, &grp_in)) ERR;
441 if (grp_in != grpid_in[0]) ERR;
442 if (nc_inq_grpname_full(grpid_in[0], NULL, NULL)) ERR;
443 if (nc_inq_grpname_full(grpid_in[0], &len1, NULL)) ERR;
444 if (len1 != strlen(full_name)) ERR;
445 if (nc_inq_grpname_full(grpid_in[0], &len, full_name_in1)) ERR;
446 if (strcmp(full_name_in1, full_name)) ERR;
447
448 if (nc_close(ncid)) ERR;
449
450 /* Check it out. */
451 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
452 if (nc_inq_grp_ncid(ncid, HENRY_VII, &grp_ncid)) ERR;
453 if (nc_inq_grps(ncid, &num_grps, NULL)) ERR;
454 if (num_grps != 1) ERR;
455 if (nc_inq_grps(ncid, NULL, grpid_in)) ERR;
456 if (nc_inq_grpname(grpid_in[0], name_in)) ERR;
457 if (strcmp(name_in, HENRY_VII)) ERR;
458 if (grpid_in[0] != grp_ncid) ERR;
459
460 if (nc_inq_grp_ncid(grpid_in[0], MARGARET, &grp_ncid)) ERR;
461 if (nc_inq_grps(grpid_in[0], &num_grps, grpid_in)) ERR;
462 if (num_grps != 1) ERR;
463 if (nc_inq_grpname(grpid_in[0], name_in)) ERR;
464 if (strcmp(name_in, MARGARET)) ERR;
465 if (grpid_in[0] != grp_ncid) ERR;
466
467 if (nc_inq_grp_ncid(grpid_in[0], JAMES_V_OF_SCOTLAND, &grp_ncid)) ERR;
468 if (nc_inq_grps(grpid_in[0], &num_grps, grpid_in)) ERR;
469 if (num_grps != 1) ERR;
470 if (nc_inq_grpname(grpid_in[0], name_in)) ERR;
471 if (strcmp(name_in, JAMES_V_OF_SCOTLAND)) ERR;
472 if (grpid_in[0] != grp_ncid) ERR;
473
474 if (nc_inq_grp_ncid(grpid_in[0], MARY_I_OF_SCOTLAND, &grp_ncid)) ERR;
475 if (nc_inq_grps(grpid_in[0], &num_grps, grpid_in)) ERR;
476 if (num_grps != 1) ERR;
477 if (nc_inq_grpname(grpid_in[0], name_in)) ERR;
478 if (strcmp(name_in, MARY_I_OF_SCOTLAND)) ERR;
479 if (grpid_in[0] != grp_ncid) ERR;
480
481 if (nc_inq_grp_ncid(grpid_in[0], JAMES_VI_OF_SCOTLAND_AND_I_OF_ENGLAND, &grp_ncid)) ERR;
482 if (nc_inq_grps(grpid_in[0], &num_grps, grpid_in)) ERR;
483 if (num_grps != 1) ERR;
484 if (nc_inq_grpname(grpid_in[0], name_in)) ERR;
485 if (strcmp(name_in, JAMES_VI_OF_SCOTLAND_AND_I_OF_ENGLAND)) ERR;
486 if (grpid_in[0] != grp_ncid) ERR;
487
488 /* Close up shop. */
489 if (nc_close(ncid)) ERR;
490 }
491 SUMMARIZE_ERR;
492
493 printf("*** testing simple sibling group creates...");
494 {
495 int ncid;
496 int henry_vii_id, margaret_id, james_v_of_scotland_id, mary_i_of_scotland_id;
497 int james_i_of_england_id, tudor_id;
498 char name_in[NC_MAX_NAME + 1];
499 int grpid_in[MAX_SIBLING_GROUPS];
500 int ncid_in;
501 int num_grps;
502 int dynasty;
503
504 /* Create a file with one group, and beneath it a group for each Tudor. */
505 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
506 if (nc_def_grp(ncid, DYNASTY, &tudor_id)) ERR;
507 if (nc_def_grp(tudor_id, HENRY_VII, &henry_vii_id)) ERR;
508 if (nc_def_grp(tudor_id, MARGARET, &margaret_id)) ERR;
509 if (nc_def_grp(tudor_id, JAMES_V_OF_SCOTLAND, &james_v_of_scotland_id)) ERR;
510 if (nc_def_grp(tudor_id, MARY_I_OF_SCOTLAND, &mary_i_of_scotland_id)) ERR;
511 if (nc_def_grp(tudor_id, JAMES_VI_OF_SCOTLAND_AND_I_OF_ENGLAND, &james_i_of_england_id)) ERR;
512 if (nc_close(ncid)) ERR;
513
514 /* Make sure we've got all the tudors where we want them. */
515 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
516 if (nc_inq_grps(ncid, &num_grps, &dynasty)) ERR;
517 if (num_grps != 1) ERR;
518 if (nc_inq_grpname(dynasty, name_in)) ERR;
519 if (strcmp(name_in, DYNASTY)) ERR;
520 if (nc_inq_grps(dynasty, &num_grps, grpid_in)) ERR;
521 if (num_grps != 5) ERR;
522 if (nc_inq_ncid(dynasty, HENRY_VII, &ncid_in)) ERR;
523 if (nc_inq_grpname(ncid_in, name_in)) ERR;
524 if (strcmp(name_in, HENRY_VII)) ERR;
525 if (nc_inq_ncid(dynasty, MARGARET, &ncid_in)) ERR;
526 if (nc_inq_grpname(ncid_in, name_in)) ERR;
527 if (strcmp(name_in, MARGARET)) ERR;
528 if (nc_inq_ncid(dynasty, JAMES_V_OF_SCOTLAND, &ncid_in)) ERR;
529 if (nc_inq_grpname(ncid_in, name_in)) ERR;
530 if (strcmp(name_in, JAMES_V_OF_SCOTLAND)) ERR;
531 if (nc_inq_ncid(dynasty, MARY_I_OF_SCOTLAND, &ncid_in)) ERR;
532 if (nc_inq_grpname(ncid_in, name_in)) ERR;
533 if (strcmp(name_in, MARY_I_OF_SCOTLAND)) ERR;
534 if (nc_inq_ncid(dynasty, JAMES_VI_OF_SCOTLAND_AND_I_OF_ENGLAND, &ncid_in)) ERR;
535 if (nc_inq_grpname(ncid_in, name_in)) ERR;
536 if (strcmp(name_in, JAMES_VI_OF_SCOTLAND_AND_I_OF_ENGLAND)) ERR;
537 if (nc_close(ncid)) ERR;
538 }
539 SUMMARIZE_ERR;
540
541 printf("*** testing more group attributes...");
542 {
543 int ncid, num_grps, dynasty, ncid_in;
544 int grpid_in[MAX_SIBLING_GROUPS];
545 int henry_vii_id, margaret_id, james_v_of_scotland_id, mary_i_of_scotland_id;
546 int james_i_of_england_id, tudor_id;
547 int num_castles_henry_vii = 1, num_castles_margaret = 0, num_castles_james_v = 2;
548 int num_castles_mary_i = 3, num_castles_james_vi = 4;
549 char name_in[NC_MAX_NAME + 1];
550
551 /* Create a file with one group, and beneath it a group for each
552 * Tudor. We will have some attributes in the groups.*/
553 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
554 if (nc_def_grp(ncid, DYNASTY, &tudor_id)) ERR;
555 if (nc_def_grp(tudor_id, HENRY_VII, &henry_vii_id)) ERR;
556 if (nc_put_att_int(henry_vii_id, NC_GLOBAL, NUM_CASTLES_NAME, NC_INT,
557 1, &num_castles_henry_vii)) ERR;
558 if (nc_def_grp(tudor_id, MARGARET, &margaret_id)) ERR;
559 if (nc_put_att_int(margaret_id, NC_GLOBAL, NUM_CASTLES_NAME, NC_INT,
560 1, &num_castles_margaret)) ERR;
561 if (nc_def_grp(tudor_id, JAMES_V_OF_SCOTLAND, &james_v_of_scotland_id)) ERR;
562 if (nc_put_att_int(james_v_of_scotland_id, NC_GLOBAL, NUM_CASTLES_NAME, NC_INT,
563 1, &num_castles_james_v)) ERR;
564 if (nc_def_grp(tudor_id, MARY_I_OF_SCOTLAND, &mary_i_of_scotland_id)) ERR;
565 if (nc_put_att_int(mary_i_of_scotland_id, NC_GLOBAL, NUM_CASTLES_NAME, NC_INT,
566 1, &num_castles_mary_i)) ERR;
567 if (nc_def_grp(tudor_id, JAMES_VI_OF_SCOTLAND_AND_I_OF_ENGLAND,
568 &james_i_of_england_id)) ERR;
569 if (nc_put_att_int(james_i_of_england_id, NC_GLOBAL, NUM_CASTLES_NAME,
570 NC_INT, 1, &num_castles_james_vi)) ERR;
571 if (nc_close(ncid)) ERR;
572
573 /* Make sure we've got all the tudors where we want them. */
574 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
575 if (nc_inq_grps(ncid, &num_grps, &dynasty)) ERR;
576 if (num_grps != 1) ERR;
577 if (nc_inq_grpname(dynasty, name_in)) ERR;
578 if (strcmp(name_in, DYNASTY)) ERR;
579 if (nc_inq_grps(dynasty, &num_grps, grpid_in)) ERR;
580 if (num_grps != 5) ERR;
581 if (nc_inq_ncid(dynasty, HENRY_VII, &ncid_in)) ERR;
582 if (nc_inq_grpname(ncid_in, name_in)) ERR;
583 if (strcmp(name_in, HENRY_VII)) ERR;
584 if (nc_inq_ncid(dynasty, MARGARET, &ncid_in)) ERR;
585 if (nc_inq_grpname(ncid_in, name_in)) ERR;
586 if (strcmp(name_in, MARGARET)) ERR;
587 if (nc_inq_ncid(dynasty, JAMES_V_OF_SCOTLAND, &ncid_in)) ERR;
588 if (nc_inq_grpname(ncid_in, name_in)) ERR;
589 if (strcmp(name_in, JAMES_V_OF_SCOTLAND)) ERR;
590 if (nc_inq_ncid(dynasty, MARY_I_OF_SCOTLAND, &ncid_in)) ERR;
591 if (nc_inq_grpname(ncid_in, name_in)) ERR;
592 if (strcmp(name_in, MARY_I_OF_SCOTLAND)) ERR;
593 if (nc_inq_ncid(dynasty, JAMES_VI_OF_SCOTLAND_AND_I_OF_ENGLAND, &ncid_in)) ERR;
594 if (nc_inq_grpname(ncid_in, name_in)) ERR;
595 if (strcmp(name_in, JAMES_VI_OF_SCOTLAND_AND_I_OF_ENGLAND)) ERR;
596 if (nc_close(ncid)) ERR;
597 }
598 SUMMARIZE_ERR;
599
600 printf("*** testing groups and dimensions...");
601 {
602 int ncid;
603 int tudor_id;
604 int num_grps;
605 int dimid, dimid_in, dynasty;
606 size_t len_in;
607 char name_in[NC_MAX_NAME + 1];
608
609 /* Create a file with one group, and within that group, a dimension.*/
610 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
611 if (nc_def_grp(ncid, DYNASTY, &tudor_id)) ERR;
612 if (nc_def_dim(tudor_id, DIM1_NAME, DIM1_LEN, &dimid)) ERR;
613 if (nc_close(ncid)) ERR;
614
615 /* Now check the file to see if the dimension is there. */
616 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
617 if (nc_inq_grps(ncid, &num_grps, &dynasty)) ERR;
618 if (num_grps != 1) ERR;
619 if (nc_inq_grpname(dynasty, name_in)) ERR;
620 if (strcmp(name_in, DYNASTY)) ERR;
621 if (nc_inq_dimid(dynasty, DIM1_NAME, &dimid_in)) ERR;
622 if (dimid_in != 0) ERR;
623 if (nc_inq_dimname(dynasty, 0, name_in)) ERR;
624 if (strcmp(name_in, DIM1_NAME)) ERR;
625 if (nc_inq_dim(dynasty, 0, name_in, &len_in)) ERR;
626 if (strcmp(name_in, DIM1_NAME)) ERR;
627 if (len_in != DIM1_LEN) ERR;
628 if (nc_close(ncid)) ERR;
629 }
630 SUMMARIZE_ERR;
631
632 printf("*** testing groups and vars...");
633 {
634 int ncid, ndims_in;
635 int tudor_id;
636 int num_grps;
637 int dimid, dynasty, varid;
638 size_t len_in;
639 int natts_in;
640 nc_type xtype_in;
641 char name_in[NC_MAX_NAME + 1];
642 int dimids_in[MAX_SIBLING_GROUPS];
643
644 /* Create a file with one group, and within that group, a
645 * dimension, and a variable.*/
646 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
647 if (nc_def_grp(ncid, DYNASTY, &tudor_id)) ERR;
648 if (nc_def_dim(tudor_id, DIM1_NAME, DIM1_LEN, &dimid)) ERR;
649 if (nc_def_var(tudor_id, VAR1_NAME, NC_INT, 1, &dimid, &varid)) ERR;
650 if (nc_close(ncid)) ERR;
651
652 /* Now check the file to see if the dimension and variable are
653 * there. */
654 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
655 if (nc_inq_grps(ncid, &num_grps, &dynasty)) ERR;
656 if (num_grps != 1) ERR;
657 if (nc_inq_dim(dynasty, 0, name_in, &len_in)) ERR;
658 if (strcmp(name_in, DIM1_NAME) || len_in != DIM1_LEN) ERR;
659 if (nc_inq_var(dynasty, 0, name_in, &xtype_in, &ndims_in, dimids_in,
660 &natts_in)) ERR;
661 if (strcmp(name_in, VAR1_NAME) || xtype_in != NC_INT || ndims_in != 1 ||
662 dimids_in[0] != 0 || natts_in != 0) ERR;
663 if (nc_close(ncid)) ERR;
664 }
665 SUMMARIZE_ERR;
666
667 printf("*** testing group functions in netCDF classic file...");
668 {
669 int ncid;
670 int num_grps;
671
672 /* Create a classic file.*/
673 if (nc_create(FILE_NAME, 0, &ncid)) ERR;
674 if (nc_inq_grps(ncid, &num_grps, NULL)) ERR;
675 if (num_grps) ERR;
676 if (nc_close(ncid)) ERR;
677
678 /* Now check the file to see if the dimension and variable are
679 * there. */
680 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
681 if (nc_inq_grps(ncid, &num_grps, NULL)) ERR;
682 if (num_grps) ERR;
683 if (nc_close(ncid)) ERR;
684 }
685 SUMMARIZE_ERR;
686
687 printf("*** testing groups and vars...");
688 {
689 int ncid, ndims_in;
690 int henry_vii_id, margaret_id, james_v_of_scotland_id, mary_i_of_scotland_id;
691 int james_i_of_england_id, tudor_id;
692 int dimids_in[MAX_SIBLING_GROUPS];
693 int num_grps;
694 int dimid, dynasty, varid;
695 size_t len_in;
696 int natts_in;
697 int grpids_in[10];
698 nc_type xtype_in;
699 char name_in[NC_MAX_NAME + 1];
700 int data_out[DIM1_LEN] = {-99, 0, 99}, data_in[DIM1_LEN];
701 int i, j;
702
703 /* Create a file with a group, DYNASTY, containing 5 groups,
704 * each with a dimension and one int variable. */
705 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
706 if (nc_def_grp(ncid, DYNASTY, &tudor_id)) ERR;
707 /* Henry VII. */
708 if (nc_def_grp(tudor_id, HENRY_VII, &henry_vii_id)) ERR;
709 if (nc_def_dim(henry_vii_id, DIM1_NAME, DIM1_LEN, &dimid)) ERR;
710 if (nc_def_var(henry_vii_id, VAR1_NAME, NC_INT, 1, &dimid, &varid)) ERR;
711 if (nc_put_var_int(henry_vii_id, varid, data_out)) ERR;
712 /* Margaret. */
713 if (nc_def_grp(tudor_id, MARGARET, &margaret_id)) ERR;
714 if (nc_def_dim(margaret_id, DIM1_NAME, DIM1_LEN, &dimid)) ERR;
715 if (nc_def_var(margaret_id, VAR1_NAME, NC_INT, 1, &dimid, &varid)) ERR;
716 if (nc_put_var_int(margaret_id, varid, data_out)) ERR;
717 /* James V of Scotland. */
718 if (nc_def_grp(tudor_id, JAMES_V_OF_SCOTLAND, &james_v_of_scotland_id)) ERR;
719 if (nc_def_dim(james_v_of_scotland_id, DIM1_NAME, DIM1_LEN, &dimid)) ERR;
720 if (nc_def_var(james_v_of_scotland_id, VAR1_NAME, NC_INT, 1, &dimid, &varid)) ERR;
721 if (nc_put_var_int(james_v_of_scotland_id, varid, data_out)) ERR;
722 /* Mary I of Scotland. */
723 if (nc_def_grp(tudor_id, MARY_I_OF_SCOTLAND, &mary_i_of_scotland_id)) ERR;
724 if (nc_def_dim(mary_i_of_scotland_id, DIM1_NAME, DIM1_LEN, &dimid)) ERR;
725 if (nc_def_var(mary_i_of_scotland_id, VAR1_NAME, NC_INT, 1, &dimid, &varid)) ERR;
726 if (nc_put_var_int(mary_i_of_scotland_id, varid, data_out)) ERR;
727 /* James VI of Scotland and I of England. */
728 if (nc_def_grp(tudor_id, JAMES_VI_OF_SCOTLAND_AND_I_OF_ENGLAND, &james_i_of_england_id)) ERR;
729 if (nc_def_dim(james_i_of_england_id, DIM1_NAME, DIM1_LEN, &dimid)) ERR;
730 if (nc_def_var(james_i_of_england_id, VAR1_NAME, NC_INT, 1, &dimid, &varid)) ERR;
731 if (nc_put_var_int(james_i_of_england_id, varid, data_out)) ERR;
732
733 /*nc_show_metadata(ncid);*/
734
735 /* Check it out. */
736 if (nc_inq_grps(ncid, &num_grps, &dynasty)) ERR;
737 if (num_grps != 1) ERR;
738 if (nc_inq_grps(dynasty, &num_grps, grpids_in)) ERR;
739 if (num_grps != 5) ERR;
740 for (i = 0; i < 5; i++)
741 {
742 if (nc_inq_dim(grpids_in[i], i, name_in, &len_in)) ERR;
743 if (strcmp(name_in, DIM1_NAME) || len_in != DIM1_LEN) ERR;
744 if (nc_inq_var(grpids_in[i], 0, name_in, &xtype_in, &ndims_in, dimids_in,
745 &natts_in)) ERR;
746 if (strcmp(name_in, VAR1_NAME) || xtype_in != NC_INT || ndims_in != 1 ||
747 dimids_in[0] != i || natts_in != 0) ERR;
748 if (nc_get_var_int(grpids_in[i], 0, data_in)) ERR;
749 for (j=0; j<DIM1_LEN; j++)
750 if (data_in[j] != data_out[j]) ERR;
751 }
752
753 if (nc_close(ncid)) ERR;
754
755 /* Reopen. */
756 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
757
758 /* Check it out. */
759 if (nc_inq_grps(ncid, &num_grps, &dynasty)) ERR;
760 if (num_grps != 1) ERR;
761 if (nc_inq_grps(dynasty, &num_grps, grpids_in)) ERR;
762 if (num_grps != 5) ERR;
763 for (i = 0; i < 5; i++)
764 {
765 /* We actually get the groups in alphabetical order, so our
766 * dimid is not i. */
767 /*if (nc_inq_dim(grpids_in[i], i, name_in, &len_in)) ERR;
768 if (strcmp(name_in, DIM1_NAME) || len_in != DIM1_LEN) ERR;*/
769 if (nc_inq_var(grpids_in[i], 0, name_in, &xtype_in, &ndims_in, dimids_in,
770 &natts_in)) ERR;
771 if (strcmp(name_in, VAR1_NAME) || xtype_in != NC_INT || ndims_in != 1 ||
772 natts_in != 0) ERR;
773 if (nc_get_var_int(grpids_in[i], 0, data_in)) ERR;
774 for (j=0; j<DIM1_LEN; j++)
775 if (data_in[j] != data_out[j]) ERR;
776 }
777
778 if (nc_close(ncid)) ERR;
779 }
780 SUMMARIZE_ERR;
781
782 printf("*** testing very simple groups and dimension scoping...");
783 {
784 int ncid;
785 int dimids_in[MAX_SIBLING_GROUPS], nvars_in, ndims_in;
786 int henry_vii_id;
787 int num_grps;
788 int dimid, dimid2, varid;
789 size_t len_in;
790 int natts_in;
791 int unlimdimid_in;
792 int grpids_in[10];
793 nc_type xtype_in;
794 char name_in[NC_MAX_NAME + 1];
795 int data_out[DIM1_LEN] = {0, 2, 6}, data_in[DIM1_LEN];
796 int j;
797
798 /* Create a netCDF-4 file. */
799 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
800
801 /* Define two dimensions, "year" and "kingdom" in the root group. */
802 if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimid2)) ERR;
803 if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimid)) ERR;
804
805 /* Define a HENRY_VII group. It contains a var with dim "kingdom". */
806 if (nc_def_grp(ncid, HENRY_VII, &henry_vii_id)) ERR;
807 if (nc_def_var(henry_vii_id, VAR1_NAME, NC_INT, 1, &dimid, &varid)) ERR;
808 if (nc_put_var_int(henry_vii_id, varid, data_out)) ERR;
809
810 /* Done! */
811 if (nc_close(ncid)) ERR;
812
813 /* Reopen the file. */
814 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
815
816 /* Check the file. */
817 if (nc_inq_grps(ncid, &num_grps, &henry_vii_id)) ERR;
818 if (num_grps != 1) ERR;
819 if (nc_inq_grps(henry_vii_id, &num_grps, grpids_in)) ERR;
820 if (num_grps != 0) ERR;
821 if (nc_inq(henry_vii_id, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
822 if (ndims_in != 0 || nvars_in != 1 || natts_in != 0 || unlimdimid_in != -1) ERR;
823 if (nc_inq_var(henry_vii_id, 0, name_in, &xtype_in, &ndims_in, dimids_in,
824 &natts_in)) ERR;
825 if (strcmp(name_in, VAR1_NAME) || xtype_in != NC_INT || ndims_in != 1 ||
826 dimids_in[0] != dimid || natts_in != 0) ERR;
827 if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
828 if (strcmp(name_in, DIM1_NAME) || len_in != DIM1_LEN) ERR;
829 if (nc_get_var_int(henry_vii_id, 0, data_in)) ERR;
830 for (j=0; j<DIM1_LEN; j++)
831 if (data_in[j] != data_out[j]) ERR;
832
833 /* Close the file. */
834 if (nc_close(ncid)) ERR;
835 }
836 SUMMARIZE_ERR;
837
838 printf("*** testing groups and dimension scoping...");
839 {
840 #define NUM_GRPS 5
841 int ncid;
842 int henry_vii_id, margaret_id, james_v_of_scotland_id, mary_i_of_scotland_id;
843 int james_i_of_england_id, tudor_id;
844 int dimids_in[MAX_SIBLING_GROUPS], nvars_in, ndims_in;
845 int num_grps;
846 int dimid, dimid2, dynasty, varid;
847 size_t len_in;
848 int natts_in;
849 int unlimdimid_in;
850 int grpids_in[10];
851 nc_type xtype_in;
852 char name_in[NC_MAX_NAME + 1];
853 int data_out[DIM1_LEN] = {0, 2, 6}, data_in[DIM1_LEN];
854 int i, j;
855
856 /* Create a netCDF-4 file. */
857 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
858
859 /* Define a bunch of groups, define a variable in each, and
860 * write some data in it. The vars use a shared dimension from
861 * the parent group. */
862
863 /* Create the parent group. */
864 if (nc_def_grp(ncid, DYNASTY, &tudor_id)) ERR;
865
866 /* Define two dimensions, "year" and "kingdom" in the parent group. */
867 if (nc_def_dim(tudor_id, DIM2_NAME, DIM2_LEN, &dimid2)) ERR;
868 if (nc_def_dim(tudor_id, DIM1_NAME, DIM1_LEN, &dimid)) ERR;
869
870 /* Define a HENRY_VII group. It contains a var with dim "kingdom". */
871 if (nc_def_grp(tudor_id, HENRY_VII, &henry_vii_id)) ERR;
872 if (nc_def_var(henry_vii_id, VAR1_NAME, NC_INT, 1, &dimid, &varid)) ERR;
873 if (nc_put_var_int(henry_vii_id, varid, data_out)) ERR;
874
875 /* Define a MARGARET group. */
876 if (nc_def_grp(tudor_id, MARGARET, &margaret_id)) ERR;
877 if (nc_def_var(margaret_id, VAR1_NAME, NC_INT, 1, &dimid, &varid)) ERR;
878 if (nc_put_var_int(margaret_id, varid, data_out)) ERR;
879
880 /* Define a JAMES_V_OF_SCOTLAND group. */
881 if (nc_def_grp(tudor_id, JAMES_V_OF_SCOTLAND, &james_v_of_scotland_id)) ERR;
882 if (nc_def_var(james_v_of_scotland_id, VAR1_NAME, NC_INT, 1, &dimid, &varid)) ERR;
883 if (nc_put_var_int(james_v_of_scotland_id, varid, data_out)) ERR;
884
885 /* Define a MARY_I_OF_SCOTLAND group. */
886 if (nc_def_grp(tudor_id, MARY_I_OF_SCOTLAND, &mary_i_of_scotland_id)) ERR;
887 if (nc_def_var(mary_i_of_scotland_id, VAR1_NAME, NC_INT, 1, &dimid, &varid)) ERR;
888 if (nc_put_var_int(mary_i_of_scotland_id, varid, data_out)) ERR;
889
890 /* Define a JAMES_VI_OF_SCOTLAND_AND_I_OF_ENGLAND group. */
891 if (nc_def_grp(tudor_id, JAMES_VI_OF_SCOTLAND_AND_I_OF_ENGLAND, &james_i_of_england_id)) ERR;
892 if (nc_def_var(james_i_of_england_id, VAR1_NAME, NC_INT, 1, &dimid, &varid)) ERR;
893 if (nc_put_var_int(james_i_of_england_id, varid, data_out)) ERR;
894
895 /* Done! */
896 if (nc_close(ncid)) ERR;
897
898 /* Reopen the file. */
899 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
900
901 /* Check the file. */
902 if (nc_inq_grps(ncid, &num_grps, &dynasty)) ERR;
903 if (num_grps != 1) ERR;
904 if (nc_inq_grps(dynasty, &num_grps, grpids_in)) ERR;
905 if (num_grps != NUM_GRPS) ERR;
906 for (i = 0; i < NUM_GRPS; i++)
907 {
908 if (nc_inq(grpids_in[i], &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
909 if (ndims_in != 0 || nvars_in != 1 || natts_in != 0 || unlimdimid_in != -1) ERR;
910 if (nc_inq_var(grpids_in[i], 0, name_in, &xtype_in, &ndims_in, dimids_in,
911 &natts_in)) ERR;
912 if (strcmp(name_in, VAR1_NAME) || xtype_in != NC_INT || ndims_in != 1 ||
913 dimids_in[0] != dimid || natts_in != 0) ERR;
914 if (nc_inq_dim(grpids_in[i], dimid, name_in, &len_in)) ERR;
915 if (strcmp(name_in, DIM1_NAME) || len_in != DIM1_LEN) ERR;
916 if (nc_get_var_int(grpids_in[i], 0, data_in)) ERR;
917 for (j=0; j<DIM1_LEN; j++)
918 if (data_in[j] != data_out[j]) ERR;
919 }
920
921 /* Close the file. */
922 if (nc_close(ncid)) ERR;
923 }
924 SUMMARIZE_ERR;
925
926 printf("*** testing more groups and dimension scoping...");
927 {
928 int ncid;
929 int henry_vii_id;
930 int tudor_id;
931 int dimids_in[MAX_SIBLING_GROUPS], ndims_in;
932 int year_did, kingdom_did, varid, dimids[2], parent_id;
933 int natts_in;
934 int numgrps;
935 int grpids_in[10];
936 nc_type xtype_in;
937 char name_in[NC_MAX_NAME + 1];
938
939 /* Create a netCDF-4 file. */
940 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
941
942 /* Create the parent group. */
943 if (nc_def_grp(ncid, DYNASTY, &tudor_id)) ERR;
944
945 /* Define two dimensions, "year" and "kingdom" in the parent group. */
946 if (nc_def_dim(tudor_id, DIM1_NAME, DIM1_LEN, &kingdom_did)) ERR;
947 if (nc_def_dim(tudor_id, DIM2_NAME, DIM2_LEN, &year_did)) ERR;
948
949 /* Define a HENRY_VII group. It contains a var using both dimensions. */
950 if (nc_def_grp(tudor_id, HENRY_VII, &henry_vii_id)) ERR;
951 dimids[0] = year_did;
952 dimids[1] = kingdom_did;
953 if (nc_def_var(henry_vii_id, VAR1_NAME, NC_UINT64, 2, dimids, &varid)) ERR;
954 if (nc_inq_var(henry_vii_id, varid, name_in, &xtype_in, &ndims_in,
955 dimids_in, &natts_in)) ERR;
956 if (strcmp(name_in, VAR1_NAME) || xtype_in != NC_UINT64 || ndims_in != 2 ||
957 dimids_in[0] != year_did || dimids_in[1] != kingdom_did ||
958 natts_in != 0) ERR;
959
960 /* Close the file. */
961 if (nc_close(ncid)) ERR;
962
963 /* Reopen the file. */
964 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
965
966 /* Find our group. */
967 if (nc_inq_grps(ncid, &numgrps, grpids_in)) ERR;
968 if (numgrps != 1) ERR;
969 parent_id = grpids_in[0];
970 if (nc_inq_grps(parent_id, &numgrps, grpids_in)) ERR;
971 if (numgrps != 1) ERR;
972 henry_vii_id = grpids_in[0];
973 if (nc_inq_var(henry_vii_id, varid, name_in, &xtype_in, &ndims_in,
974 dimids_in, &natts_in)) ERR;
975 if (strcmp(name_in, VAR1_NAME) || xtype_in != NC_UINT64 || ndims_in != 2 ||
976 dimids_in[0] != year_did || dimids_in[1] != kingdom_did ||
977 natts_in != 0) ERR;
978 /* Close the file. */
979 if (nc_close(ncid)) ERR;
980
981 }
982 SUMMARIZE_ERR;
983 printf("*** testing groups and unlimited dimensions...");
984 {
985 int ncid;
986 int henry_vii_id;
987 int tudor_id;
988 int dimids_in[MAX_SIBLING_GROUPS], ndims_in;
989 int num_grps;
990 int dimid, dynasty, varid;
991 size_t len_in;
992 int natts_in;
993 int grpids_in[10];
994 nc_type xtype_in;
995 char name_in[NC_MAX_NAME + 1];
996 int data_out[DIM1_LEN] = {0, 2, 6}, data_in[DIM1_LEN];
997 size_t start[1] = {0}, count[1] = {3};
998 int j;
999
1000 /* Create one group, with one var, which has one dimension, which is unlimited. */
1001 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
1002 if (nc_def_grp(ncid, DYNASTY, &tudor_id)) ERR;
1003 if (nc_def_dim(tudor_id, DIM1_NAME, NC_UNLIMITED, &dimid)) ERR;
1004 if (nc_def_grp(tudor_id, HENRY_VII, &henry_vii_id)) ERR;
1005 if (nc_def_var(henry_vii_id, VAR1_NAME, NC_INT, 1, &dimid, &varid)) ERR;
1006 if (nc_put_vara_int(henry_vii_id, varid, start, count, data_out)) ERR;
1007 if (nc_close(ncid)) ERR;
1008
1009 /* Now check the file to see if the dimension and variable are
1010 * there. */
1011 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
1012 if (nc_inq_grps(ncid, &num_grps, &dynasty)) ERR;
1013 if (num_grps != 1) ERR;
1014 if (nc_inq_grps(dynasty, &num_grps, grpids_in)) ERR;
1015 if (num_grps != 1) ERR;
1016 if (nc_inq_dim(grpids_in[0], 0, name_in, &len_in)) ERR;
1017 if (strcmp(name_in, DIM1_NAME) || len_in != DIM1_LEN) ERR;
1018 if (nc_inq_var(grpids_in[0], 0, name_in, &xtype_in, &ndims_in, dimids_in,
1019 &natts_in)) ERR;
1020 if (strcmp(name_in, VAR1_NAME) || xtype_in != NC_INT || ndims_in != 1 ||
1021 dimids_in[0] != 0 || natts_in != 0) ERR;
1022 if (nc_get_vara_int(grpids_in[0], 0, start, count, data_in)) ERR;
1023 for (j=0; j<DIM1_LEN; j++)
1024 if (data_in[j] != data_out[j]) ERR;
1025 if (nc_close(ncid)) ERR;
1026 }
1027 SUMMARIZE_ERR;
1028
1029 printf("*** testing nested groups...");
1030 {
1031 #define DIM_NAME "dim"
1032 #define DIM_LEN 3
1033 #define VAR_NAME "var"
1034 #define VAR_RANK 1
1035 #define ATT_NAME "units"
1036 #define ATT_VAL "m/s"
1037 #define GATT_NAME "title"
1038 #define GATT_VAL "for testing groups"
1039 #define G1_NAME "the_in_crowd"
1040 #define G2_NAME "the_out_crowd"
1041 #define G3_NAME "the_confused_crowd"
1042 int ncid;
1043 int dimid, varid;
1044 int var_dims[VAR_RANK];
1045 int g1id, g2id, g3id;
1046
1047 /* Create a file with nested groups. */
1048 if (nc_create(FILE_NAME, NC_CLOBBER | NC_NETCDF4, &ncid)) ERR;
1049 /* At root level define dim, var, atts */
1050 if (nc_def_dim(ncid, DIM_NAME, DIM_LEN, &dimid)) ERR;
1051 var_dims[0] = dimid;
1052 if (nc_def_var(ncid, VAR_NAME, NC_FLOAT, VAR_RANK, var_dims, &varid)) ERR;
1053 if (nc_put_att_text(ncid, varid, ATT_NAME, strlen(ATT_VAL), ATT_VAL)) ERR;
1054 if (nc_put_att_text(ncid, NC_GLOBAL, GATT_NAME, strlen(GATT_VAL),
1055 GATT_VAL)) ERR;
1056
1057 /* put dim, var, atts with same names in a group */
1058 if (nc_def_grp(ncid, G1_NAME, &g1id)) ERR;
1059 if (nc_def_dim(g1id, DIM_NAME, DIM_LEN, &dimid)) ERR;
1060 var_dims[0] = dimid;
1061 if (nc_def_var(g1id, VAR_NAME, NC_FLOAT, VAR_RANK, var_dims, &varid)) ERR;
1062 if (nc_put_att_text(g1id, varid, ATT_NAME, strlen(ATT_VAL), ATT_VAL)) ERR;
1063 if (nc_put_att_text(g1id, NC_GLOBAL, GATT_NAME, strlen(GATT_VAL),
1064 GATT_VAL)) ERR;
1065 if (nc_enddef(g1id)) ERR;
1066
1067 /* put dim, var, atts with same names in a second group */
1068 if (nc_def_grp(ncid, G2_NAME, &g2id)) ERR;
1069 if (nc_def_dim(g2id, DIM_NAME, DIM_LEN, &dimid)) ERR;
1070 var_dims[0] = dimid;
1071 if (nc_def_var(g2id, VAR_NAME, NC_FLOAT, VAR_RANK, var_dims, &varid)) ERR;
1072 if (nc_put_att_text(g2id, varid, ATT_NAME, strlen(ATT_VAL), ATT_VAL)) ERR;
1073 if (nc_put_att_text(g2id, NC_GLOBAL, GATT_NAME, strlen(GATT_VAL),
1074 GATT_VAL)) ERR;
1075 if (nc_enddef(g2id)) ERR;
1076
1077 /* put dim, var, atts with same names in a subgroup of second group */
1078 if (nc_def_grp(g2id, G3_NAME, &g3id)) ERR;
1079 if (nc_def_dim(g3id, DIM_NAME, DIM_LEN, &dimid)) ERR;
1080 var_dims[0] = dimid;
1081 if (nc_def_var(g3id, VAR_NAME, NC_FLOAT, VAR_RANK, var_dims, &varid)) ERR;
1082 if (nc_put_att_text(g3id, varid, ATT_NAME, strlen(ATT_VAL), ATT_VAL)) ERR;
1083 if (nc_put_att_text(g3id, NC_GLOBAL, GATT_NAME, strlen(GATT_VAL),
1084 GATT_VAL)) ERR;
1085 if (nc_enddef(g3id)) ERR;
1086
1087 if (nc_close(ncid)) ERR;
1088
1089 }
1090 SUMMARIZE_ERR;
1091
1092 printf("*** testing nested groups, user defined types, and enddef...");
1093 {
1094 #define SCI_FI "Science_Fiction"
1095 #define BASE_SIZE 2
1096 #define TYPE_NAME "The_Blob"
1097 #define DATE_MOVIE "data_movie"
1098 int ncid, xtype, g1id, class;
1099 char name_in[NC_MAX_NAME + 1];
1100 size_t len_in;
1101 unsigned char data[BASE_SIZE] = {42, 43}, data_in[BASE_SIZE];
1102
1103 /* Create a file. */
1104 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
1105
1106 /* define subgroup with a user defined type. */
1107 if (nc_def_grp(ncid, SCI_FI, &g1id)) ERR;
1108 if (nc_def_opaque(g1id, BASE_SIZE, TYPE_NAME, &xtype)) ERR;
1109 if (nc_put_att(g1id, NC_GLOBAL, DATE_MOVIE, xtype, 1, &data)) ERR;
1110
1111 /* Check it. */
1112 if (nc_inq_user_type(g1id, xtype, name_in, &len_in, NULL, NULL, &class)) ERR;
1113 if (strcmp(name_in, TYPE_NAME) || len_in != BASE_SIZE || class != NC_OPAQUE) ERR;
1114 if (nc_get_att(g1id, NC_GLOBAL, DATE_MOVIE, data_in)) ERR;
1115 if (data[0] != data_in[0] || data[1] != data_in[1]) ERR;
1116
1117 /* Call enddef and try again. */
1118 if (nc_enddef(g1id)) ERR;
1119
1120 if (nc_inq_user_type(g1id, xtype, name_in, &len_in, NULL, NULL, &class)) ERR;
1121 if (strcmp(name_in, TYPE_NAME) || len_in != BASE_SIZE || class != NC_OPAQUE) ERR;
1122 if (nc_get_att(g1id, NC_GLOBAL, DATE_MOVIE, data_in)) ERR;
1123 if (data[0] != data_in[0] || data[1] != data_in[1]) ERR;
1124
1125 if (nc_close(ncid)) ERR;
1126
1127 /* Reopen and recheck. */
1128 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
1129 if (nc_inq_grp_ncid(ncid, SCI_FI, &g1id)) ERR;
1130
1131 if (nc_inq_user_type(g1id, xtype, name_in, &len_in, NULL, NULL, &class)) ERR;
1132 if (strcmp(name_in, TYPE_NAME) || len_in != BASE_SIZE || class != NC_OPAQUE) ERR;
1133 if (nc_get_att(g1id, NC_GLOBAL, DATE_MOVIE, data_in)) ERR;
1134 if (data[0] != data_in[0] || data[1] != data_in[1]) ERR;
1135
1136 if (nc_close(ncid)) ERR;
1137
1138 }
1139 SUMMARIZE_ERR;
1140
1141 printf("*** creating file with lots of user-defined types...");
1142 {
1143 int ncid, typeid;
1144 int g1id, g2id, g3id;
1145
1146 /* Create a file with nested groups. */
1147 if (nc_create(FILE_NAME, NC_CLOBBER | NC_NETCDF4, &ncid)) ERR;
1148 if (nc_def_opaque(ncid, 10, "opaque-1", &typeid)) ERR;
1149 if (nc_def_vlen(ncid, "vlen-1", NC_INT, &typeid)) ERR;
1150 if (nc_enddef(ncid)) ERR;
1151
1152 if (nc_def_grp(ncid, G1_NAME, &g1id)) ERR;
1153 if (nc_def_opaque(g1id, 7, "opaque-2", &typeid)) ERR;
1154 if (nc_def_vlen(g1id, "vlen-2", NC_BYTE, &typeid)) ERR;
1155 if (nc_enddef(g1id)) ERR;
1156
1157 if (nc_def_grp(ncid, G2_NAME, &g2id)) ERR;
1158 if (nc_def_opaque(g2id, 4, "opaque-3", &typeid)) ERR;
1159 if (nc_def_vlen(g2id, "vlen-3", NC_BYTE, &typeid)) ERR;
1160 if (nc_enddef(g2id)) ERR;
1161
1162 /* put dim, var, atts with same names in a subgroup of second group */
1163 if (nc_def_grp(g2id, G3_NAME, &g3id)) ERR;
1164 if (nc_def_opaque(g3id, 13, "opaque-4", &typeid)) ERR;
1165 if (nc_def_vlen(g3id, "vlen-4", NC_BYTE, &typeid)) ERR;
1166 if (nc_enddef(g3id)) ERR;
1167
1168 if (nc_close(ncid)) ERR;
1169
1170 /* Now count how many user-defined types there are */
1171 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
1172 if (nc_close(ncid)) ERR;
1173
1174 }
1175 SUMMARIZE_ERR;
1176
1177 printf("*** creating file with lots of groups...");
1178 {
1179 #define PARENT_NUM_GRPS 6
1180 #define SUB_NUM_GRPS 2
1181
1182 int ncid, g1id, sub_grpid, num_grps, g, s;
1183 char grp_name[NC_MAX_NAME + 1];
1184
1185 /* Create a file with lots of groups. */
1186 if (nc_create(FILE_NAME, NC_CLOBBER | NC_NETCDF4, &ncid)) ERR;
1187 for (g = 0; g < PARENT_NUM_GRPS; g++)
1188 {
1189 sprintf(grp_name, "grp_%d", g);
1190 if (nc_def_grp(ncid, grp_name, &g1id)) ERR;
1191 for (s = 0; s < SUB_NUM_GRPS; s++)
1192 {
1193 sprintf(grp_name, "sub_grp_%d", s);
1194 if (nc_def_grp(g1id, grp_name, &sub_grpid)) ERR;
1195 }
1196 }
1197
1198 if (nc_close(ncid)) ERR;
1199
1200 /* Now count how groups there are. */
1201 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
1202 if (nc_inq_grps(ncid, &num_grps, NULL)) ERR;
1203 if (num_grps != PARENT_NUM_GRPS) ERR;
1204 if (nc_close(ncid)) ERR;
1205
1206 }
1207 SUMMARIZE_ERR;
1208
1209 printf("*** creating file with type defined after group...");
1210 {
1211 #define GRP_NAME "phony_group"
1212 #define CMP1_NAME "cmp1"
1213 #define CMP2_NAME "cmp2"
1214
1215 int ncid, varid, varid2, grpid, numvars, retval;
1216 int typeid, typeid2;
1217 size_t nfields;
1218 char name[NC_MAX_NAME + 1];
1219 size_t size;
1220 struct s1
1221 {
1222 int i1;
1223 int i2;
1224 };
1225 struct s2
1226 {
1227 int i3;
1228 double f1;
1229 };
1230 struct s1 data;
1231 struct s2 data2;
1232
1233 /* Create some phony data. */
1234 data.i1 = 5;
1235 data.i2 = 10;
1236 data2.i3 = 50;
1237 data2.f1 = 100.0;
1238
1239 /* Create file */
1240 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
1241
1242 /* Create compound datatype #1, in root group */
1243 if (nc_def_compound(ncid, sizeof(struct s1), CMP1_NAME, &typeid)) ERR;
1244 if (nc_inq_compound(ncid, typeid, name, &size, &nfields)) ERR;
1245 if (size != sizeof(struct s1) || strcmp(name, CMP1_NAME) || nfields) ERR;
1246 if (nc_insert_compound(ncid, typeid, "i1",
1247 NC_COMPOUND_OFFSET(struct s1, i1), NC_INT)) ERR;
1248 if (nc_insert_compound(ncid, typeid, "i2",
1249 NC_COMPOUND_OFFSET(struct s1, i2), NC_INT)) ERR;
1250
1251 /* Create variable with compound datatype #1, in root group */
1252 if (nc_def_var(ncid, VAR_NAME, typeid, 0, NULL, &varid)) ERR;
1253 if (nc_put_var(ncid, varid, &data)) ERR;
1254
1255 /* Create child group, in root group*/
1256 if (nc_def_grp(ncid, GRP_NAME, &grpid)) ERR;
1257
1258 /* Close and re-open file, to guarantee the creation ordering is difficult
1259 * for the library to deal with.
1260 */
1261 if (nc_close(ncid)) ERR;
1262 if ((retval = nc_open(FILE_NAME, NC_WRITE, &ncid))) ERR;
1263
1264 /* Create compound datatype #2, in root group */
1265 if (nc_def_compound(ncid, sizeof(struct s2), CMP2_NAME, &typeid2)) ERR;
1266 if (nc_inq_compound(ncid, typeid2, name, &size, &nfields)) ERR;
1267 if (size != sizeof(struct s2) || strcmp(name, CMP2_NAME) || nfields) ERR;
1268 if (nc_insert_compound(ncid, typeid2, "i3",
1269 NC_COMPOUND_OFFSET(struct s2, i3), NC_INT)) ERR;
1270 if (nc_insert_compound(ncid, typeid2, "f1",
1271 NC_COMPOUND_OFFSET(struct s2, f1), NC_DOUBLE)) ERR;
1272
1273 /* Create variable with compound datatype #2, in root group */
1274 if (nc_def_var(grpid, VAR_NAME, typeid2, 0, NULL, &varid2)) ERR;
1275 if (nc_put_var(ncid, varid2, &data2)) ERR;
1276
1277 if (nc_close(ncid)) ERR;
1278
1279
1280 /* Verify that the variable in the child group was recognized by the library */
1281 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
1282 if (nc_inq_grp_ncid(ncid, GRP_NAME, &grpid)) ERR;
1283 if (nc_inq_nvars(grpid, &numvars)) ERR;
1284 if (numvars != 1) ERR;
1285 if (nc_close(ncid)) ERR;
1286 }
1287 SUMMARIZE_ERR;
1288
1289 FINAL_RESULTS;
1290 }
1291