netcdf-c/nc_test4/tst_atts2.c
2018-01-31 08:44:33 -07:00

263 lines
8.1 KiB
C

/* This is part of the netCDF package. Copyright 2005-2018 University
Corporation for Atmospheric Research/Unidata. See COPYRIGHT file
for conditions of use.
Test copy of attributes.
Ed Hartnett, Denis Heimbigner, Ward Fisher
*/
#include <nc_tests.h>
#include "err_macros.h"
#include "netcdf.h"
#define FILE_NAME1 "tst_atts2.nc"
#define FILE_NAME2 "tst_atts2_2.nc"
int
main(int argc, char **argv)
{
printf("\n*** Testing netcdf-4 attribute copies.\n");
printf("*** testing compound attribute copy to different type of same name...");
{
#define CMP_NAME1 "Ireland"
#define I1_NAME "Cork"
#define I2_NAME "Dublin"
#define DIM_LEN 3
#define ATT_NAME3 "Rain"
#define NUM_FILES 2
int ncid[NUM_FILES], typeid;
char file_name[NUM_FILES][NC_MAX_NAME + 1] = {FILE_NAME1, FILE_NAME2};
int i;
struct s1
{
int i1;
int i2;
};
struct s1 data[DIM_LEN];
struct s2
{
short i1;
int i2;
};
/* Create some phony data. */
for (i = 0; i < DIM_LEN; i++)
{
data[i].i1 = 32768;
data[i].i2 = 32767;
}
/* Create two files with different compound types of the same name. */
for (i = 0; i < NUM_FILES; i++)
if (nc_create(file_name[i], NC_NETCDF4, &ncid[i])) ERR;
/* Define s1 in file 1. */
if (nc_def_compound(ncid[0], sizeof(struct s1), CMP_NAME1, &typeid)) ERR;
if (nc_insert_compound(ncid[0], typeid, I1_NAME,
NC_COMPOUND_OFFSET(struct s1, i1), NC_INT)) ERR;
if (nc_insert_compound(ncid[0], typeid, I2_NAME,
NC_COMPOUND_OFFSET(struct s1, i2), NC_INT)) ERR;
/* Define s2 in file 2, but named the same as s1. */
if (nc_def_compound(ncid[1], sizeof(struct s2), CMP_NAME1, &typeid)) ERR;
if (nc_insert_compound(ncid[1], typeid, I1_NAME,
NC_COMPOUND_OFFSET(struct s2, i1), NC_SHORT)) ERR;
if (nc_insert_compound(ncid[1], typeid, I2_NAME,
NC_COMPOUND_OFFSET(struct s2, i2), NC_INT)) ERR;
/* Write an att in one file. */
if (nc_put_att(ncid[0], NC_GLOBAL, ATT_NAME3, typeid, DIM_LEN,
data)) ERR;
/* Try to copy. It must fail, because the two types are not the
* same. */
if (nc_copy_att(ncid[0], NC_GLOBAL, ATT_NAME3, ncid[1],
NC_GLOBAL) != NC_EBADTYPE) ERR;
/* Close the files. */
for (i = 0; i < NUM_FILES; i++)
if (nc_close(ncid[i])) ERR;
}
SUMMARIZE_ERR;
printf("*** testing string attribute copy...");
{
#define ATT_NAME "Irish_Leader"
#define ATT_LEN 1
int ncid1, ncid2;
const char *mc[ATT_LEN] = {"Michael Collins"};
char *mc_in;
/* Create a file with a string att. */
if (nc_create(FILE_NAME1, NC_NETCDF4, &ncid1)) ERR;
if (nc_put_att_string(ncid1, NC_GLOBAL, ATT_NAME, ATT_LEN, mc)) ERR;
/* Create another file, and copy the att. */
if (nc_create(FILE_NAME2, NC_NETCDF4, &ncid2)) ERR;
/* These will not work. */
if (nc_copy_att(ncid1 + TEST_VAL_42, NC_GLOBAL, ATT_NAME, ncid2, NC_GLOBAL) != NC_EBADID) ERR;
if (nc_copy_att(ncid1, TEST_VAL_42, ATT_NAME, ncid2, NC_GLOBAL) != NC_ENOTVAR) ERR;
if (nc_copy_att(ncid1, NC_GLOBAL, NULL, ncid2, NC_GLOBAL) != NC_EBADNAME) ERR;
if (nc_copy_att(ncid1, NC_GLOBAL, ATT_NAME, ncid2 + TEST_VAL_42, NC_GLOBAL) != NC_EBADID) ERR;
if (nc_copy_att(ncid1, NC_GLOBAL, ATT_NAME, ncid2, TEST_VAL_42) != NC_ENOTVAR) ERR;
/* Copy the attribute. */
if (nc_copy_att(ncid1, NC_GLOBAL, ATT_NAME, ncid2, NC_GLOBAL)) ERR;
/* Close up. */
if (nc_close(ncid1)) ERR;
if (nc_close(ncid2)) ERR;
/* Reopen file 2 and see that attribute is correct. */
if (nc_open(FILE_NAME2, 0, &ncid2)) ERR;
if (nc_get_att_string(ncid2, NC_GLOBAL, ATT_NAME, &mc_in)) ERR;
if (strcmp(mc[0], mc_in)) ERR;
if (nc_close(ncid2)) ERR;
if (nc_free_string(ATT_LEN, &mc_in)) ERR;
}
SUMMARIZE_ERR;
printf("*** testing non-string atomic attribute copy...");
{
#define ATT_LEN 1
#define NUM_ATT 5
int ncid1, ncid2;
char name[NUM_ATT][NC_MAX_NAME + 1];
long long data = 0, data_in[NUM_ATT];
int a;
/* Create a file with non-string atomic atts. */
if (nc_create(FILE_NAME1, NC_NETCDF4, &ncid1)) ERR;
for (a = 0; a < NUM_ATT; a++)
{
sprintf(name[a], "atomic_att_type_%d", a + 1);
nc_put_att(ncid1, NC_GLOBAL, name[a], a + 1, ATT_LEN,
(void *)&data);
}
/* Create another file, and copy the att. */
if (nc_create(FILE_NAME2, NC_NETCDF4, &ncid2)) ERR;
for (a = 0; a < NUM_ATT; a++)
if (nc_copy_att(ncid1, NC_GLOBAL, name[a], ncid2, NC_GLOBAL)) ERR;
/* Close up. */
if (nc_close(ncid1)) ERR;
if (nc_close(ncid2)) ERR;
/* Reopen file 2 and see that attributes are present. */
if (nc_open(FILE_NAME2, 0, &ncid2)) ERR;
for (a = 0; a < NUM_ATT; a++)
nc_get_att(ncid1, NC_GLOBAL, name[a], (void *)&data_in[a]);
if (nc_close(ncid2)) ERR;
}
SUMMARIZE_ERR;
printf("*** testing simple compound attribute copy...");
{
#define CMP_NAME "cmp"
#define I1 "i1"
#define I2 "i2"
#define DIM_LEN 3
#define ATT_NAME2 "att"
#define NUM_FILES 2
int ncid[NUM_FILES], typeid;
char file_name[NUM_FILES][NC_MAX_NAME + 1] = {FILE_NAME1, FILE_NAME2};
int i;
struct s1
{
int i1;
int i2;
};
struct s1 data[DIM_LEN], data_in[DIM_LEN];
/* Create some phony data. */
for (i = 0; i < DIM_LEN; i++)
{
data[i].i1 = 5;
data[i].i2 = 10;
}
/* Create two files with the same compound type. */
for (i = 0; i < NUM_FILES; i++)
{
if (nc_create(file_name[i], NC_NETCDF4, &ncid[i])) ERR;
if (nc_def_compound(ncid[i], sizeof(struct s1), CMP_NAME, &typeid)) ERR;
if (nc_insert_compound(ncid[i], typeid, I1,
NC_COMPOUND_OFFSET(struct s1, i1), NC_INT)) ERR;
if (nc_insert_compound(ncid[i], typeid, I2,
NC_COMPOUND_OFFSET(struct s1, i2), NC_INT)) ERR;
}
/* Write an att in one file and copy it. */
if (nc_put_att(ncid[0], NC_GLOBAL, ATT_NAME2, typeid, DIM_LEN,
data)) ERR;
if (nc_copy_att(ncid[0], NC_GLOBAL, ATT_NAME2, ncid[1],
NC_GLOBAL)) ERR;
/* Close the files. */
for (i = 0; i < NUM_FILES; i++)
if (nc_close(ncid[i])) ERR;
/* Open the second file and take a peek. */
if (nc_open(FILE_NAME1, NC_WRITE, &ncid[1])) ERR;
if (nc_get_att(ncid[1], NC_GLOBAL, ATT_NAME2, data_in)) ERR;
for (i=0; i<DIM_LEN; i++)
if (data[i].i1 != data_in[i].i1 || data[i].i2 != data_in[i].i2) ERR;
if (nc_close(ncid[1])) ERR;
}
SUMMARIZE_ERR;
printf("*** testing simple enum attribute copy...");
{
#define DIM_LEN_10 10
#define ATT_NAME2 "att"
#define TYPE_NAME "Irish_Province_Type"
#define NUM_FILES 2
#define NUM_MEMBERS 4
int ncid[NUM_FILES], typeid;
char file_name[NUM_FILES][NC_MAX_NAME + 1] = {FILE_NAME1, FILE_NAME2};
char member_name[NUM_MEMBERS][NC_MAX_NAME + 1] = {"Munster", "Connacht",
"Leinster", "Ulster"};
int member_value[NUM_MEMBERS] = {0, 1, 2, 3};
int data_in[DIM_LEN_10], data[DIM_LEN_10] = {0, 1, 2, 3, 0, 1, 2, 3, 0, 1};
int i, j;
/* Create two files with the same enum type. */
for (i = 0; i < NUM_FILES; i++)
{
if (nc_create(file_name[i], NC_NETCDF4, &ncid[i])) ERR;
if (nc_def_enum(ncid[i], NC_INT, TYPE_NAME, &typeid)) ERR;
for (j = 0; j < NUM_MEMBERS; j++)
if (nc_insert_enum(ncid[i], typeid, member_name[j],
&member_value[j])) ERR;
}
/* Write an att in one file and copy it. */
if (nc_put_att(ncid[0], NC_GLOBAL, ATT_NAME2, typeid, DIM_LEN_10,
data)) ERR;
if (nc_copy_att(ncid[0], NC_GLOBAL, ATT_NAME2, ncid[1],
NC_GLOBAL)) ERR;
/* Close the files. */
for (i = 0; i < NUM_FILES; i++)
if (nc_close(ncid[i])) ERR;
/* Open the second file and take a peek. */
if (nc_open(FILE_NAME1, NC_WRITE, &ncid[1])) ERR;
if (nc_get_att(ncid[1], NC_GLOBAL, ATT_NAME2, data_in)) ERR;
/* Check the data. */
for (i = 0; i < DIM_LEN_10; i++)
if (data[i] != data_in[i]) ERR;
if (nc_close(ncid[1])) ERR;
}
SUMMARIZE_ERR;
FINAL_RESULTS;
}