int ex_put_prop (int exoid, ex_entity_type obj_type, ex_entity_id obj_id, const char *prop_name, ex_entity_id value) { int status; int oldfill = 0; int temp; int found = FALSE; int num_props, i, dimid, propid, dims[1]; int int_type; size_t start[1]; size_t prop_name_len, name_length; char name[MAX_VAR_NAME_LENGTH+1]; char tmpstr[MAX_STR_LENGTH+1]; char dim_name[MAX_VAR_NAME_LENGTH+1]; long long vals[1]; char errmsg[MAX_ERR_LENGTH]; exerrval = 0; /* clear error code */ /* check if property has already been created */ num_props = ex_get_num_props(exoid, obj_type); if (num_props > 1) { /* any properties other than the default 1? */ for (i=1; i<=num_props; i++) { switch (obj_type) { case EX_ELEM_BLOCK: strcpy (name, VAR_EB_PROP(i)); break; case EX_EDGE_BLOCK: strcpy (name, VAR_ED_PROP(i)); break; case EX_FACE_BLOCK: strcpy (name, VAR_FA_PROP(i)); break; case EX_NODE_SET: strcpy (name, VAR_NS_PROP(i)); break; case EX_EDGE_SET: strcpy (name, VAR_ES_PROP(i)); break; case EX_FACE_SET: strcpy (name, VAR_FS_PROP(i)); break; case EX_ELEM_SET: strcpy (name, VAR_ELS_PROP(i)); break; case EX_SIDE_SET: strcpy (name, VAR_SS_PROP(i)); break; case EX_ELEM_MAP: strcpy (name, VAR_EM_PROP(i)); break; case EX_FACE_MAP: strcpy (name, VAR_FAM_PROP(i)); break; case EX_EDGE_MAP: strcpy (name, VAR_EDM_PROP(i)); break; case EX_NODE_MAP: strcpy (name, VAR_NM_PROP(i)); break; default: exerrval = EX_BADPARAM; sprintf(errmsg, "Error: object type %d not supported; file id %d", obj_type, exoid); ex_err("ex_put_prop",errmsg,exerrval); return(EX_FATAL); } if ((status = nc_inq_varid(exoid, name, &propid)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to get property array id in file id %d", exoid); ex_err("ex_put_prop",errmsg,exerrval); return (EX_FATAL); } /* compare stored attribute name with passed property name */ memset(tmpstr, 0, MAX_STR_LENGTH+1); if ((status = nc_get_att_text(exoid, propid, ATT_PROP_NAME, tmpstr)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to get property name in file id %d", exoid); ex_err("ex_put_prop",errmsg,exerrval); return (EX_FATAL); } if (strcmp(tmpstr, prop_name) == 0) { found = TRUE; break; } } } /* if property array has not been created, create it */ if (!found) { name_length = ex_inquire_int(exoid, EX_INQ_DB_MAX_ALLOWED_NAME_LENGTH)+1; /* put netcdf file into define mode */ if ((status = nc_redef (exoid)) != NC_NOERR) { exerrval = status; sprintf(errmsg,"Error: failed to place file id %d into define mode",exoid); ex_err("ex_put_prop",errmsg,exerrval); return (EX_FATAL); } /* create a variable with a name xx_prop#, where # is the new number */ /* of the property */ switch (obj_type){ case EX_ELEM_BLOCK: strcpy (name, VAR_EB_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_EL_BLK); break; case EX_FACE_BLOCK: strcpy (name, VAR_FA_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_FA_BLK); break; case EX_EDGE_BLOCK: strcpy (name, VAR_ED_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_ED_BLK); break; case EX_NODE_SET: strcpy (name, VAR_NS_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_NS); break; case EX_EDGE_SET: strcpy (name, VAR_ES_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_ES); break; case EX_FACE_SET: strcpy (name, VAR_FS_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_FS); break; case EX_ELEM_SET: strcpy (name, VAR_ELS_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_ELS); break; case EX_SIDE_SET: strcpy (name, VAR_SS_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_SS); break; case EX_ELEM_MAP: strcpy (name, VAR_EM_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_EM); break; case EX_FACE_MAP: strcpy (name, VAR_FAM_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_FAM); break; case EX_EDGE_MAP: strcpy (name, VAR_EDM_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_EDM); break; case EX_NODE_MAP: strcpy (name, VAR_NM_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_NM); break; default: exerrval = EX_BADPARAM; sprintf(errmsg, "Error: object type %d not supported; file id %d", obj_type, exoid); ex_err("ex_put_prop",errmsg,exerrval); goto error_ret; /* Exit define mode and return */ } /* inquire id of previously defined dimension (number of objects) */ if ((status = nc_inq_dimid(exoid, dim_name, &dimid)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to locate number of objects in file id %d", exoid); ex_err("ex_put_prop",errmsg, exerrval); goto error_ret; /* Exit define mode and return */ } dims[0] = dimid; nc_set_fill(exoid, NC_FILL, &oldfill); /* fill with zeros per routine spec */ int_type = NC_INT; if (ex_int64_status(exoid) & EX_IDS_INT64_DB) { int_type = NC_INT64; } if ((status = nc_def_var(exoid, name, int_type, 1, dims, &propid)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to create property array variable in file id %d", exoid); ex_err("ex_put_prop",errmsg,exerrval); goto error_ret; /* Exit define mode and return */ } vals[0] = 0; /* fill value */ /* create attribute to cause variable to fill with zeros per routine spec */ if ((status = nc_put_att_longlong(exoid, propid, _FillValue, int_type, 1, vals)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to create property name fill attribute in file id %d", exoid); ex_err("ex_put_prop",errmsg,exerrval); goto error_ret; /* Exit define mode and return */ } /* Check that the property name length is less than MAX_NAME_LENGTH */ prop_name_len = strlen(prop_name)+1; if (prop_name_len > name_length) { fprintf(stderr, "Warning: The property name '%s' is too long.\n\tIt will be truncated from %d to %d characters\n", prop_name, (int)prop_name_len-1, (int)name_length-1); prop_name_len = name_length; } /* store property name as attribute of property array variable */ if ((status = nc_put_att_text(exoid, propid, ATT_PROP_NAME, prop_name_len, (void*)prop_name)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to store property name %s in file id %d", prop_name,exoid); ex_err("ex_put_prop",errmsg,exerrval); goto error_ret; /* Exit define mode and return */ } ex_update_max_name_length(exoid, prop_name_len-1); /* leave define mode */ if ((status = nc_enddef (exoid)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to leave define mode in file id %d", exoid); ex_err("ex_put_prop",errmsg,exerrval); return (EX_FATAL); } nc_set_fill(exoid, oldfill, &temp); /* default: nofill */ } /* find index into property array using obj_id; put value in property */ /* array at proper index; ex_id_lkup returns an index that is 1-based,*/ /* but netcdf expects 0-based arrays so subtract 1 */ /* special case: property name ID - check for duplicate ID assignment */ if (strcmp("ID",prop_name) == 0) { start[0] = ex_id_lkup (exoid, obj_type, value); if (exerrval != EX_LOOKUPFAIL) /* found the id */ { exerrval = EX_BADPARAM; sprintf(errmsg, "Warning: attempt to assign duplicate %s ID %"PRId64" in file id %d", ex_name_of_object(obj_type), value, exoid); ex_err("ex_put_prop",errmsg,exerrval); return (EX_WARN); } } start[0] = ex_id_lkup (exoid, obj_type, obj_id); if (exerrval != 0) { if (exerrval == EX_NULLENTITY) { sprintf(errmsg, "Warning: no properties allowed for NULL %s id %"PRId64" in file id %d", ex_name_of_object(obj_type), obj_id,exoid); ex_err("ex_put_prop",errmsg,EX_MSG); return (EX_WARN); } else { sprintf(errmsg, "Error: failed to find value %"PRId64" in %s property array in file id %d", obj_id, ex_name_of_object(obj_type), exoid); ex_err("ex_put_prop",errmsg,exerrval); return (EX_FATAL); } } start[0] = start[0] - 1; /* value is of type 'ex_entity_id' which is a typedef to int64_t or long long */ status = nc_put_var1_longlong(exoid, propid, start, (long long*)&value); if (status != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to store property value in file id %d", exoid); ex_err("ex_put_prop",errmsg,exerrval); return (EX_FATAL); } return (EX_NOERR); /* Fatal error: exit definition mode and return */ error_ret: nc_set_fill(exoid, oldfill, &temp); /* default: nofill */ if (nc_enddef (exoid) != NC_NOERR) { /* exit define mode */ sprintf(errmsg, "Error: failed to complete definition for file id %d", exoid); ex_err("ex_put_prop",errmsg,exerrval); } return (EX_FATAL); }
int ex_put_prop_names(int exoid, ex_entity_type obj_type, int num_props, char **prop_names) { int status; int oldfill, temp; int i, propid, dimid, dims[1]; size_t name_length, prop_name_len; char * name; long long vals[1]; int max_name_len = 0; int int_type = NC_INT; char errmsg[MAX_ERR_LENGTH]; exerrval = 0; /* clear error code */ if (ex_int64_status(exoid) & EX_IDS_INT64_DB) { int_type = NC_INT64; } /* Get the name string length */ name_length = ex_inquire_int(exoid, EX_INQ_DB_MAX_ALLOWED_NAME_LENGTH) + 1; /* inquire id of previously defined dimension (number of objects) */ if ((status = nc_inq_dimid(exoid, ex_dim_num_objects(obj_type), &dimid)) != NC_NOERR) { exerrval = status; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to locate number of %s in file id %d", ex_name_of_object(obj_type), exoid); ex_err("ex_put_prop_names", errmsg, exerrval); return (EX_FATAL); } nc_set_fill(exoid, NC_FILL, &oldfill); /* fill with zeros per routine spec */ /* put netcdf file into define mode */ if ((status = nc_redef(exoid)) != NC_NOERR) { exerrval = status; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to place file id %d into define mode", exoid); ex_err("ex_put_prop_names", errmsg, exerrval); return (EX_FATAL); } /* define num_props variables; we postpend the netcdf variable name with */ /* a counter starting at 2 because "xx_prop1" is reserved for the id array*/ dims[0] = dimid; for (i = 0; i < num_props; i++) { switch (obj_type) { case EX_ELEM_BLOCK: name = VAR_EB_PROP(i + 2); break; case EX_FACE_BLOCK: name = VAR_FA_PROP(i + 2); break; case EX_EDGE_BLOCK: name = VAR_ED_PROP(i + 2); break; case EX_NODE_SET: name = VAR_NS_PROP(i + 2); break; case EX_SIDE_SET: name = VAR_SS_PROP(i + 2); break; case EX_EDGE_SET: name = VAR_ES_PROP(i + 2); break; case EX_FACE_SET: name = VAR_FS_PROP(i + 2); break; case EX_ELEM_SET: name = VAR_ELS_PROP(i + 2); break; case EX_ELEM_MAP: name = VAR_EM_PROP(i + 2); break; case EX_FACE_MAP: name = VAR_FAM_PROP(i + 2); break; case EX_EDGE_MAP: name = VAR_EDM_PROP(i + 2); break; case EX_NODE_MAP: name = VAR_NM_PROP(i + 2); break; default: exerrval = EX_BADPARAM; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: object type %d not supported; file id %d", obj_type, exoid); ex_err("ex_put_prop_names", errmsg, exerrval); goto error_ret; /* Exit define mode and return */ } if ((status = nc_def_var(exoid, name, int_type, 1, dims, &propid)) != NC_NOERR) { exerrval = status; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to create property array variable in file id %d", exoid); ex_err("ex_put_prop_names", errmsg, exerrval); goto error_ret; /* Exit define mode and return */ } vals[0] = 0; /* fill value */ /* create attribute to cause variable to fill with zeros per routine spec */ if ((status = nc_put_att_longlong(exoid, propid, _FillValue, int_type, 1, vals)) != NC_NOERR) { exerrval = status; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to create property name fill attribute in file id %d", exoid); ex_err("ex_put_prop_names", errmsg, exerrval); goto error_ret; /* Exit define mode and return */ } /* Check that the property name length is less than MAX_NAME_LENGTH */ prop_name_len = strlen(prop_names[i]) + 1; if (prop_name_len > name_length) { fprintf(stderr, "Warning: The property name '%s' is too long.\n\tIt will " "be truncated from %d to %d characters\n", prop_names[i], (int)prop_name_len - 1, (int)name_length - 1); prop_name_len = name_length; } if (prop_name_len > max_name_len) { max_name_len = prop_name_len; } /* store property name as attribute of property array variable */ if ((status = nc_put_att_text(exoid, propid, ATT_PROP_NAME, prop_name_len, prop_names[i])) != NC_NOERR) { exerrval = status; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to store property name %s in file id %d", prop_names[i], exoid); ex_err("ex_put_prop_names", errmsg, exerrval); goto error_ret; /* Exit define mode and return */ } } /* leave define mode */ if ((status = nc_enddef(exoid)) != NC_NOERR) { exerrval = status; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to leave define mode in file id %d", exoid); ex_err("ex_put_prop_names", errmsg, exerrval); return (EX_FATAL); } /* Update the maximum_name_length attribute on the file. */ ex_update_max_name_length(exoid, max_name_len - 1); nc_set_fill(exoid, oldfill, &temp); /* default: turn off fill */ return (EX_NOERR); /* Fatal error: exit definition mode and return */ error_ret: if (nc_enddef(exoid) != NC_NOERR) { /* exit define mode */ snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete definition for file id %d", exoid); ex_err("ex_put_prop_names", errmsg, exerrval); } return (EX_FATAL); }
int main(int argc, char **argv) { (void) signal(SIGFPE, SIG_IGN); printf("\n*** Testing netcdf-4 attribute functions.\n"); printf("*** testing really simple global atts..."); #define NUM_SIMPLE_ATTS 9 { int ncid; char name[NUM_SIMPLE_ATTS][ATT_MAX_NAME + 1] = {"Gc", "Gb", "Gs", "Gi", "Gf", "Gd", "G7", "G8", "G9"}; char name_in[NC_MAX_NAME]; int j; /* Create a file with some global atts. */ if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLOBBER, &ncid)) ERR; for (j = 0; j < NUM_SIMPLE_ATTS; j++) if (nc_put_att_int(ncid, NC_GLOBAL, name[j], NC_INT, 0, NULL)) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and check the order. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; for (j = 0; j < NUM_SIMPLE_ATTS; j++) { if (nc_inq_attname(ncid, NC_GLOBAL, j, name_in)) ERR; if (strcmp(name_in, name[j])) ERR; } /* Close up shop. */ if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing simple global atts..."); { int ncid; nc_type att_type; size_t att_len; int i; char *speech_in; signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE}; unsigned char uchar_in[ATT_LEN], uchar_out[ATT_LEN] = {0, 128, NC_MAX_CHAR}; short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT}; /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/ int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000}; float float_in[ATT_LEN], float_out[ATT_LEN] = {.5, 0.25, 0.125}; double double_in[ATT_LEN], double_out[ATT_LEN] = {0.25, .5, 0.125}; unsigned short ushort_in[ATT_LEN], ushort_out[ATT_LEN] = {0, 128, NC_MAX_USHORT}; unsigned int uint_in[ATT_LEN], uint_out[ATT_LEN] = {0, 128, NC_MAX_UINT}; unsigned long long uint64_in[ATT_LEN], uint64_out[ATT_LEN] = {0, 128, 18446744073709551612ULL}; long long int64_in[ATT_LEN], int64_out[ATT_LEN] = {NC_MIN_INT64, 128, NC_MAX_INT64}; /* This won't work, because classic files can't create these types. */ if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR; if (nc_put_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, NC_USHORT, ATT_LEN, ushort_out) != NC_ESTRICTNC3) ERR; if (nc_put_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, NC_UINT, ATT_LEN, uint_out) != NC_ESTRICTNC3) ERR; if (nc_put_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, NC_INT64, ATT_LEN, int64_out) != NC_ESTRICTNC3) ERR; if (nc_put_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, NC_UINT64, ATT_LEN, uint64_out) != NC_ESTRICTNC3) ERR; if (nc_close(ncid)) ERR; /* Create a file with a global attribute of each type. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR; if (nc_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out)) ERR; if (nc_put_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, NC_UBYTE, ATT_LEN, uchar_out)) ERR; if (nc_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, ATT_LEN, short_out)) ERR; if (nc_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, ATT_LEN, int_out)) ERR; if (nc_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, ATT_LEN, float_out)) ERR; if (nc_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, ATT_LEN, double_out)) ERR; if (nc_put_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, NC_USHORT, ATT_LEN, ushort_out)) ERR; if (nc_put_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, NC_UINT, ATT_LEN, uint_out)) ERR; if (nc_put_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, NC_INT64, ATT_LEN, int64_out)) ERR; if (nc_put_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, NC_UINT64, ATT_LEN, uint64_out)) ERR; if (nc_close(ncid)) ERR; /* Open the file and check attributes. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; /* Check text. */ if (nc_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, &att_type, &att_len)) ERR; if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERR; if (!(speech_in = malloc(att_len + 1))) ERR; if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, speech_in)) ERR; if (strcmp(speech, speech_in)) ERR; free(speech_in); /* Check numeric values. */ if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != schar_out[i]) ERR; if (nc_get_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, uchar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (uchar_in[i] != uchar_out[i]) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != short_out[i]) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int_in[i] != int_out[i]) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (float_in[i] != float_out[i]) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (double_in[i] != double_out[i]) ERR; if (nc_get_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, ushort_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (ushort_in[i] != ushort_out[i]) ERR; if (nc_get_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, uint_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (uint_in[i] != uint_out[i]) ERR; if (nc_get_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, int64_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int64_in[i] != int64_out[i]) ERR; if (nc_get_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, uint64_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (uint64_in[i] != uint64_out[i]) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing attribute data type conversions..."); { int ncid; int i; signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE}; short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT}; /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/ int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000}; float float_in[ATT_LEN], float_out[ATT_LEN] = {.5, 0.25, 0.125}; double double_in[ATT_LEN], double_out[ATT_LEN] = {0.25, .5, 0.125}; unsigned short ushort_in[ATT_LEN]; unsigned int uint_in[ATT_LEN]; unsigned long long uint64_in[ATT_LEN]; long long int64_in[ATT_LEN]; /* Reopen the file and try different type conversions. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; /* No text conversions are allowed, and people who try them shold * be locked up, away from decent folk! */ if (nc_get_att_short(ncid, NC_GLOBAL, ATT_TEXT_NAME, short_in) != NC_ECHAR) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_TEXT_NAME, int_in) != NC_ECHAR) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_TEXT_NAME, float_in) != NC_ECHAR) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_TEXT_NAME, double_in) != NC_ECHAR) ERR; /* if (nc_get_att_ubyte(ncid, NC_GLOBAL, ATT_TEXT_NAME, uchar_in) != NC_ECHAR) ERR;*/ if (nc_get_att_ushort(ncid, NC_GLOBAL, ATT_TEXT_NAME, ushort_in) != NC_ECHAR) ERR; if (nc_get_att_uint(ncid, NC_GLOBAL, ATT_TEXT_NAME, uint_in) != NC_ECHAR) ERR; if (nc_get_att_longlong(ncid, NC_GLOBAL, ATT_TEXT_NAME, int64_in) != NC_ECHAR) ERR; if (nc_get_att_ulonglong(ncid, NC_GLOBAL, ATT_TEXT_NAME, uint64_in) != NC_ECHAR) ERR; /* Read all atts (except text) as double. */ if (nc_get_att_double(ncid, NC_GLOBAL, ATT_SCHAR_NAME, double_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (double_in[i] != schar_out[i]) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_SHORT_NAME, double_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (double_in[i] != short_out[i]) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_INT_NAME, double_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (double_in[i] != int_out[i]) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_FLOAT_NAME, double_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (double_in[i] != float_out[i]) ERR; /* Read all atts (except text) as float. */ if (nc_get_att_float(ncid, NC_GLOBAL, ATT_SCHAR_NAME, float_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (float_in[i] != schar_out[i]) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_SHORT_NAME, float_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (float_in[i] != short_out[i]) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_INT_NAME, float_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (float_in[i] != (float)int_out[i]) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, float_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (float_in[i] != (float)double_out[i]) ERR; /* Read all atts (except text) as int. */ if (nc_get_att_int(ncid, NC_GLOBAL, ATT_SCHAR_NAME, int_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int_in[i] != schar_out[i]) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_SHORT_NAME, int_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int_in[i] != short_out[i]) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_FLOAT_NAME, int_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int_in[i] != (int)float_out[i]) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, int_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int_in[i] != (int)double_out[i]) ERR; /* Read all atts (except text) as short. */ if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SCHAR_NAME, short_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != schar_out[i]) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_INT_NAME, short_in) != NC_ERANGE) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != (short)int_out[i]) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_FLOAT_NAME, short_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != (short)float_out[i]) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, short_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != (short)double_out[i]) ERR; /* Read all atts (except text) as schar. Some range errors will * result converting to schar. */ if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SHORT_NAME, schar_in) != NC_ERANGE) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != (signed char)short_out[i]) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_INT_NAME, schar_in) != NC_ERANGE) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != (signed char)int_out[i]) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_FLOAT_NAME, schar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != (signed char)float_out[i]) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, schar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != (signed char)double_out[i]) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing simple variable atts..."); { int ncid, varid, dimids[2]; nc_type att_type; size_t att_len; int i, v; char *speech_in; signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE}; short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT}; /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/ int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000}; float float_in[ATT_LEN], float_out[ATT_LEN] = {.5, 0.25, 0.125}; double double_in[ATT_LEN], double_out[ATT_LEN] = {0.25, .5, 0.125}; /* Create a file with two vars, attaching to each an attribute of * each type. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR; if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR; if (nc_def_var(ncid, VAR1_NAME, NC_INT, 2, dimids, &varid)) ERR; if (nc_put_att_text(ncid, varid, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR; if (nc_put_att_schar(ncid, varid, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out)) ERR; if (nc_put_att_short(ncid, varid, ATT_SHORT_NAME, NC_SHORT, 3, short_out)) ERR; if (nc_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out)) ERR; if (nc_put_att_float(ncid, varid, ATT_FLOAT_NAME, NC_FLOAT, 3, float_out)) ERR; if (nc_put_att_double(ncid, varid, ATT_DOUBLE_NAME, NC_DOUBLE, 3, double_out)) ERR; if (nc_def_var(ncid, VAR2_NAME, NC_UINT, 2, dimids, &varid)) ERR; if (nc_put_att_text(ncid, varid, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR; if (nc_put_att_schar(ncid, varid, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out)) ERR; if (nc_put_att_short(ncid, varid, ATT_SHORT_NAME, NC_SHORT, 3, short_out)) ERR; if (nc_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out)) ERR; if (nc_put_att_float(ncid, varid, ATT_FLOAT_NAME, NC_FLOAT, 3, float_out)) ERR; if (nc_put_att_double(ncid, varid, ATT_DOUBLE_NAME, NC_DOUBLE, 3, double_out)) ERR; if (nc_close(ncid)) ERR; /* Open the file and check attributes. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; for (v=0; v<2; v++) { if (nc_inq_att(ncid, v, ATT_TEXT_NAME, &att_type, &att_len)) ERR; if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERR; if (!(speech_in = malloc(att_len + 1))) ERR; if (nc_get_att_text(ncid, v, ATT_TEXT_NAME, speech_in)) ERR; if (strcmp(speech, speech_in)) ERR; free(speech_in); if (nc_get_att_schar(ncid, v, ATT_SCHAR_NAME, schar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != schar_out[i]) ERR; if (nc_get_att_short(ncid, v, ATT_SHORT_NAME, short_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != short_out[i]) ERR; if (nc_get_att_int(ncid, v, ATT_INT_NAME, int_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int_in[i] != int_out[i]) ERR; if (nc_get_att_float(ncid, v, ATT_FLOAT_NAME, float_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (float_in[i] != float_out[i]) ERR; if (nc_get_att_double(ncid, v, ATT_DOUBLE_NAME, double_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (double_in[i] != double_out[i]) ERR; } if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing zero-length attributes..."); { int ncid; /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/ /* Create a file with a global attribute of each type of zero length. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, 0, NULL)) ERR; if (nc_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, 0, NULL)) ERR; /* if (nc_put_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, NC_UCHAR, ATT_LEN, uchar_out)) ERR;*/ if (nc_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, 0, NULL)) ERR; if (nc_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, 0, NULL)) ERR; if (nc_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, 0, NULL)) ERR; if (nc_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, 0, NULL)) ERR; if (nc_close(ncid)) ERR; } /* Make sure we can read all these zero-length atts. */ { int ncid; signed char schar_in[ATT_LEN]; short short_in[ATT_LEN]; /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/ int int_in[ATT_LEN]; float float_in[ATT_LEN]; double double_in[ATT_LEN]; size_t len; nc_type xtype; if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, NULL)) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, &xtype, &len)) ERR; if (len || xtype != NC_CHAR) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in)) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_SCHAR_NAME, &xtype, &len)) ERR; if (len || xtype != NC_BYTE) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in)) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_SHORT_NAME, &xtype, &len)) ERR; if (len || xtype != NC_SHORT) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in)) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_INT_NAME, &xtype, &len)) ERR; if (len || xtype != NC_INT) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in)) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_FLOAT_NAME, &xtype, &len)) ERR; if (len || xtype != NC_FLOAT) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in)) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, &xtype, &len)) ERR; if (len || xtype != NC_DOUBLE) ERR; /* Conversions no longer result in range errors, since there's no data. */ if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, schar_in)) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_FLOAT_NAME, schar_in)) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_INT_NAME, schar_in)) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SHORT_NAME, schar_in)) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing zero-length attributes and redef...(this test skipped for HDF5-1.8.0 beta1"); { int ncid; signed char schar_in[ATT_LEN]; short short_in[ATT_LEN]; int int_in[ATT_LEN]; float float_in[ATT_LEN]; double double_in[ATT_LEN]; /* Create a file with a global attribute of each type of zero length. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_enddef(ncid)) ERR; if (nc_redef(ncid)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, 0, NULL)) ERR; if (nc_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, 0, NULL)) ERR; /* if (nc_put_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, NC_UCHAR, ATT_LEN, uchar_out)) ERR;*/ if (nc_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, 0, NULL)) ERR; if (nc_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, 0, NULL)) ERR; if (nc_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, 0, NULL)) ERR; if (nc_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, 0, NULL)) ERR; if (nc_close(ncid)) ERR; /* Make sure we can read all these zero-length atts added during a * redef. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, NULL)) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in)) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in)) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in)) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in)) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in)) ERR; /* Conversions no longer result in range errors, since there's no data. */ if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, schar_in)) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_FLOAT_NAME, schar_in)) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_INT_NAME, schar_in)) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SHORT_NAME, schar_in)) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing attribute deletes and renames..."); { int ncid, varid, dimids[2]; nc_type att_type; size_t att_len; char *speech_in; char name_in[NC_MAX_NAME + 1]; int attid_in, natts_in; int int_out[ATT_LEN] = {-100000, 128, 100000}; /* Create a file with a global attribute. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR; if (nc_close(ncid)) ERR; /* Rename it. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq_attid(ncid, NC_GLOBAL, ATT_TEXT_NAME, &attid_in)) ERR; if (attid_in != 0) ERR; if (nc_inq_attname(ncid, NC_GLOBAL, attid_in, name_in)) ERR; if (strcmp(name_in, ATT_TEXT_NAME)) ERR; if (nc_rename_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, ATT_TEXT_NAME2)) ERR; if (nc_inq_attname(ncid, NC_GLOBAL, attid_in, name_in)) ERR; if (strcmp(name_in, ATT_TEXT_NAME2)) ERR; if (nc_close(ncid)) ERR; if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME2, &att_type, &att_len)) ERR; if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERR; if (!(speech_in = malloc(att_len + 1))) ERR; if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME2, speech_in)) ERR; if (strcmp(speech, speech_in)) ERR; free(speech_in); if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, speech_in) != NC_ENOTATT) ERR; if (nc_close(ncid)) ERR; /* Now delete the att. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_del_att(ncid, NC_GLOBAL, ATT_TEXT_NAME2)) ERR; if (nc_close(ncid)) ERR; /* Now create a file with a variable, which has an att. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR; if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR; if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR; if (nc_def_var(ncid, VAR1_NAME, NC_INT, 2, dimids, &varid)) ERR; if (nc_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out)) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and delete it. Make sure it's gone. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_del_att(ncid, 0, ATT_INT_NAME)) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and readd the attribute. Enddef and redef, * and delete it, then check to make sure it's gone. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out)) ERR; if (nc_enddef(ncid)) ERR; if (nc_redef(ncid)) ERR; if (nc_del_att(ncid, 0, ATT_INT_NAME)) ERR; if (nc_inq_varnatts(ncid, 0, &natts_in)) ERR; if (natts_in != 0) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing attribute create order..."); #define ATT0 "Maturin" #define ATT1 "Aubery" { int ncid, varid, dimids[2]; int attid_in; const int number = 42; /* Create a file with several global attributes. */ if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR; if (nc_put_att_int(ncid, NC_GLOBAL, ATT0, NC_INT, 1, &number)) ERR; if (nc_put_att_int(ncid, NC_GLOBAL, ATT1, NC_INT, 1, &number)) ERR; if (nc_close(ncid)) ERR; /* Open it and check the order. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq_attid(ncid, NC_GLOBAL, ATT0, &attid_in)) ERR; if (attid_in != 0) ERR; if (nc_inq_attid(ncid, NC_GLOBAL, ATT1, &attid_in)) ERR; if (attid_in != 1) ERR; if (nc_close(ncid)) ERR; /* Now create a file with a variable, which has two atts. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR; if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR; if (nc_def_var(ncid, VAR1_NAME, NC_INT, 2, dimids, &varid)) ERR; if (nc_put_att_int(ncid, varid, ATT0, NC_INT, 1, &number)) ERR; if (nc_put_att_int(ncid, varid, ATT1, NC_INT, 1, &number)) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and check the order of the attributes on the var. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq_attid(ncid, 0, ATT0, &attid_in)) ERR; if (attid_in != 0) ERR; if (nc_inq_attid(ncid, 0, ATT1, &attid_in)) ERR; if (attid_in != 1) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing attribute ordering some more..."); #define VAR_NAME "i" #define A1_NAME "i" #define A2_NAME "f" #define A3_NAME "d" #define A1_LEN 3 #define A2_LEN 4 #define A3_LEN 5 { int ncid; int varid, natts, nvars; double dvalue[] = {999.99, 999.99, 999.99, 999.99, 999.99}; int varids[1]; char name_in[NC_MAX_NAME + 1]; /* Create a file with one var, and attach three atts to it. */ if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR; if (nc_def_var(ncid, VAR_NAME, NC_INT, 0, NULL, &varid)) ERR; if (nc_put_att_double(ncid, varid, A1_NAME, NC_INT, A1_LEN, dvalue)) ERR; if (nc_put_att_double(ncid, varid, A2_NAME, NC_INT, A2_LEN, dvalue)) ERR; if (nc_put_att_double(ncid, varid, A3_NAME, NC_INT, A3_LEN, dvalue)) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and check. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_inq_varids(ncid, &nvars, varids)) ERR; if (nvars != 1 || varids[0] != 0) ERR; if (nc_inq_varnatts(ncid, 0, &natts)) ERR; if (natts != 3) ERR; if (nc_inq_attname(ncid, 0, 0, name_in)) ERR; if (strcmp(name_in, A1_NAME)) ERR; if (nc_inq_attname(ncid, 0, 1, name_in)) ERR; if (strcmp(name_in, A2_NAME)) ERR; if (nc_inq_attname(ncid, 0, 2, name_in)) ERR; if (strcmp(name_in, A3_NAME)) ERR; /* Close up shop. */ if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing attribute ordering even more..."); /* Test the ordering of atts for each cmode. */ if (tst_att_ordering(NC_CLOBBER)) ERR; if (tst_att_ordering(NC_CLOBBER|NC_64BIT_OFFSET)) ERR; if (tst_att_ordering(NC_CLOBBER|NC_NETCDF4)) ERR; if (tst_att_ordering(NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL)) ERR; SUMMARIZE_ERR; printf("*** testing attributes and enddef/redef..."); #define ATT_1 "a" #define ATT_2 "b" #define ATT_3 "c" { int ncid, att = 1; if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL|NC_CLOBBER, &ncid)) ERR; if (nc_enddef(ncid)) ERR; if (nc_redef(ncid)) ERR; if (nc_put_att(ncid, NC_GLOBAL, ATT_1, NC_INT, 1, &att)) ERR; if (nc_put_att(ncid, NC_GLOBAL, ATT_2, NC_INT, 1, &att)) ERR; if (nc_put_att(ncid, NC_GLOBAL, ATT_3, NC_INT, 1, &att)) ERR; if (nc_close(ncid)) ERR; if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing copy of simple global atts..."); { int ncid, ncid2; nc_type att_type; size_t att_len; int i; char *speech_in; signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE}; unsigned char uchar_in[ATT_LEN], uchar_out[ATT_LEN] = {0, 128, NC_MAX_CHAR}; short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT}; int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000}; float float_in[ATT_LEN], float_out[ATT_LEN] = {.5, 0.25, 0.125}; double double_in[ATT_LEN], double_out[ATT_LEN] = {0.25, .5, 0.125}; unsigned short ushort_in[ATT_LEN], ushort_out[ATT_LEN] = {0, 128, NC_MAX_USHORT}; unsigned int uint_in[ATT_LEN], uint_out[ATT_LEN] = {0, 128, NC_MAX_UINT}; unsigned long long uint64_in[ATT_LEN], uint64_out[ATT_LEN] = {0, 128, 18446744073709551612ULL}; long long int64_in[ATT_LEN], int64_out[ATT_LEN] = {NC_MIN_INT64, 128, NC_MAX_INT64}; /* Create a file with a global attribute of each type. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR; if (nc_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out)) ERR; if (nc_put_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, NC_UBYTE, ATT_LEN, uchar_out)) ERR; if (nc_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, ATT_LEN, short_out)) ERR; if (nc_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, ATT_LEN, int_out)) ERR; if (nc_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, ATT_LEN, float_out)) ERR; if (nc_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, ATT_LEN, double_out)) ERR; if (nc_put_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, NC_USHORT, ATT_LEN, ushort_out)) ERR; if (nc_put_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, NC_UINT, ATT_LEN, uint_out)) ERR; if (nc_put_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, NC_INT64, ATT_LEN, int64_out)) ERR; if (nc_put_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, NC_UINT64, ATT_LEN, uint64_out)) ERR; /* Create another file and copy all the attributes. */ if (nc_create(FILE_NAME2, NC_NETCDF4, &ncid2)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_SCHAR_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_UCHAR_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_SHORT_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_INT_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_FLOAT_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_USHORT_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_UINT_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_INT64_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_UINT64_NAME, ncid2, NC_GLOBAL)) ERR; /* Close both files. */ if (nc_close(ncid)) ERR; if (nc_close(ncid2)) ERR; /* Open the file and check attributes. */ if (nc_open(FILE_NAME2, 0, &ncid)) ERR; /* Check text. */ if (nc_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, &att_type, &att_len)) ERR; if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERR; if (!(speech_in = malloc(att_len + 1))) ERR; if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, speech_in)) ERR; if (strcmp(speech, speech_in)) ERR; free(speech_in); /* Check numeric values. */ if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != schar_out[i]) ERR; if (nc_get_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, uchar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (uchar_in[i] != uchar_out[i]) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != short_out[i]) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int_in[i] != int_out[i]) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (float_in[i] != float_out[i]) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (double_in[i] != double_out[i]) ERR; if (nc_get_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, ushort_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (ushort_in[i] != ushort_out[i]) ERR; if (nc_get_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, uint_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (uint_in[i] != uint_out[i]) ERR; if (nc_get_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, int64_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int64_in[i] != int64_out[i]) ERR; if (nc_get_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, uint64_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (uint64_in[i] != uint64_out[i]) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; FINAL_RESULTS; }