/* This is part of the netCDF package. Copyright 2018 University Corporation for Atmospheric Research/Unidata See COPYRIGHT file for conditions of use. Test netcdf-4 compound type feature. Ed Hartnett */ #include #include #include #include "err_macros.h" #define FILE_NAME "tst_compounds.nc" #define SVC_REC "Service_Record" #define BATTLES_WITH_KLINGONS "Number_of_Battles_with_Klingons" #define DATES_WITH_ALIENS "Dates_with_Alien_Hotties" #define STARDATE "Stardate" #define RANK 1 #define DIM_LEN 3 #define SERVICE_RECORD "Kirk_Service_Record" int main(int argc, char **argv) { printf("\n*** Testing netcdf-4 user defined type functions.\n"); printf("*** testing simple compound scalar variable create..."); { int ncid, typeid, varid; size_t nfields; int ndims, nvars, natts, unlimdimid; char name[NC_MAX_NAME + 1]; size_t size; nc_type xtype, field_xtype; int dimids[] = {0}, fieldid; int field_ndims, field_sizes[NC_TESTS_MAX_DIMS]; size_t offset; struct s1 { int i1; int i2; }; struct s1 data, data_in; /* Create some phony data. */ data.i1 = 5; data.i2 = 10; /* Create a file with a compound type. Write a little data. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_compound(ncid, sizeof(struct s1), SVC_REC, &typeid)) ERR; if (nc_inq_compound(ncid, typeid, name, &size, &nfields)) ERR; if (size != sizeof(struct s1) || strcmp(name, SVC_REC) || nfields) ERR; if (nc_insert_compound(ncid, typeid, BATTLES_WITH_KLINGONS, NC_COMPOUND_OFFSET(struct s1, i1), NC_INT)) ERR; if (nc_insert_compound(ncid, typeid, DATES_WITH_ALIENS, NC_COMPOUND_OFFSET(struct s1, i2), NC_INT)) ERR; /* This won't work due to bad typeid. */ if (nc_def_var(ncid, SERVICE_RECORD, typeid + TEST_VAL_42, 0, NULL, &varid) != NC_EBADTYPE) ERR; /* Define the variable. */ if (nc_def_var(ncid, SERVICE_RECORD, typeid, 0, NULL, &varid)) ERR; if (nc_put_var(ncid, varid, &data)) ERR; if (nc_close(ncid)) ERR; /* Open the file and take a peek. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != 0 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and take a more detailed look at the compound * type. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq_var(ncid, 0, name, &xtype, &ndims, dimids, &natts)) ERR; if (strcmp(name, SERVICE_RECORD) || ndims != 0 || natts != 0) ERR; if (nc_inq_compound(ncid, xtype, name, &size, &nfields)) ERR; if (nfields != 2 || size != sizeof(struct s1) || strcmp(name, SVC_REC)) ERR; if (nc_inq_compound_name(ncid, xtype, name)) ERR; if (strcmp(name, SVC_REC)) ERR; if (nc_inq_compound_size(ncid, xtype, &size)) ERR; if (size != sizeof(struct s1)) ERR; if (nc_inq_compound_nfields(ncid, xtype, &nfields)) ERR; if (nfields != 2) ERR; if (nc_inq_compound_field(ncid, xtype, 0, name, &offset, &field_xtype, &field_ndims, field_sizes)) ERR; if (field_ndims) ERR; if (strcmp(name, BATTLES_WITH_KLINGONS) || offset != 0 || (field_xtype != NC_INT || field_ndims != 0)) ERR; if (nc_inq_compound_field(ncid, xtype, 1, name, &offset, &field_xtype, &field_ndims, field_sizes)) ERR; if (strcmp(name, DATES_WITH_ALIENS) || offset != 4 || field_xtype != NC_INT) ERR; if (nc_inq_compound_fieldname(ncid, xtype, 1, name)) ERR; if (strcmp(name, DATES_WITH_ALIENS)) ERR; if (nc_inq_compound_fieldindex(ncid, xtype, BATTLES_WITH_KLINGONS, &fieldid)) ERR; if (fieldid != 0) ERR; if (nc_inq_compound_fieldoffset(ncid, xtype, 1, &offset)) ERR; if (offset != 4) ERR; if (nc_inq_compound_fieldtype(ncid, xtype, 1, &field_xtype)) ERR; if (field_xtype != NC_INT) ERR; if (nc_get_var(ncid, varid, &data_in)) ERR; if (data.i1 != data_in.i1 || data.i2 != data_in.i2) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing simple compound variable create..."); { int ncid, typeid, varid; size_t nfields; int dimid; int ndims, nvars, natts, unlimdimid; char name[NC_MAX_NAME + 1]; size_t size; nc_type xtype, field_xtype; int dimids[] = {0}, fieldid; int field_ndims, field_sizes[NC_TESTS_MAX_DIMS]; size_t offset; int i; struct s1 { int i1; int i2; }; struct s1 data[DIM_LEN], data_in[DIM_LEN]; char *dummy; /* REALLY initialize the data (even the gaps in the structs). This * is only needed to pass valgrind. */ if (!(dummy = calloc(sizeof(struct s1), DIM_LEN))) return NC_ENOMEM; memcpy((void *)data, (void *)dummy, sizeof(struct s1) * DIM_LEN); free(dummy); /* Create some phony data. */ for (i = 0; i < DIM_LEN; i++) { data[i].i1 = 5; data[i].i2 = 10; } /* Create a file with a compound type. Write a little data. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_compound(ncid, sizeof(struct s1), SVC_REC, &typeid)) ERR; if (nc_inq_compound(ncid, typeid, name, &size, &nfields)) ERR; if (size != sizeof(struct s1) || strcmp(name, SVC_REC) || nfields) ERR; if (nc_insert_compound(ncid, typeid, BATTLES_WITH_KLINGONS, NC_COMPOUND_OFFSET(struct s1, i1), NC_INT)) ERR; if (nc_insert_compound(ncid, typeid, DATES_WITH_ALIENS, NC_COMPOUND_OFFSET(struct s1, i2), NC_INT)) ERR; if (nc_def_dim(ncid, STARDATE, DIM_LEN, &dimid)) ERR; if (nc_def_var(ncid, SERVICE_RECORD, typeid, 1, dimids, &varid)) ERR; if (nc_put_var(ncid, varid, data)) ERR; if (nc_close(ncid)) ERR; /* Open the file and take a peek. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != 1 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and take a more detailed look at the compound * type. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq_var(ncid, 0, name, &xtype, &ndims, dimids, &natts)) ERR; if (strcmp(name, SERVICE_RECORD) || ndims != 1 || natts != 0 || dimids[0] != 0) ERR; if (nc_inq_compound(ncid, xtype, name, &size, &nfields)) ERR; if (nfields != 2 || size != sizeof(struct s1) || strcmp(name, SVC_REC)) ERR; if (nc_inq_compound_name(ncid, xtype, name)) ERR; if (strcmp(name, SVC_REC)) ERR; if (nc_inq_compound_size(ncid, xtype, &size)) ERR; if (size != sizeof(struct s1)) ERR; if (nc_inq_compound_nfields(ncid, xtype, &nfields)) ERR; if (nfields != 2) ERR; if (nc_inq_compound_field(ncid, xtype, 0, name, &offset, &field_xtype, &field_ndims, field_sizes)) ERR; if (field_ndims) ERR; if (strcmp(name, BATTLES_WITH_KLINGONS) || offset != 0 || (field_xtype != NC_INT || field_ndims != 0)) ERR; if (nc_inq_compound_field(ncid, xtype, 1, name, &offset, &field_xtype, &field_ndims, field_sizes)) ERR; if (strcmp(name, DATES_WITH_ALIENS) || offset != 4 || field_xtype != NC_INT) ERR; if (nc_inq_compound_fieldname(ncid, xtype, 1, name)) ERR; if (strcmp(name, DATES_WITH_ALIENS)) ERR; if (nc_inq_compound_fieldindex(ncid, xtype, BATTLES_WITH_KLINGONS, &fieldid)) ERR; if (fieldid != 0) ERR; if (nc_inq_compound_fieldoffset(ncid, xtype, 1, &offset)) ERR; if (offset != 4) ERR; if (nc_inq_compound_fieldtype(ncid, xtype, 1, &field_xtype)) ERR; if (field_xtype != NC_INT) ERR; if (nc_get_var(ncid, varid, data_in)) ERR; for (i=0; i