void pthread_exit(void *retval) { /* Get all we need from the tdb before releasing it. */ nc_thread_descriptor_t *tdb = nc_get_tdb(); nc_thread_memory_block_t *stack_node = tdb->stack_node; int32_t *is_used = &stack_node->is_used; nc_basic_thread_data_t *basic_data = tdb->basic_data; int joinable = tdb->joinable; /* Call cleanup handlers. */ while (NULL != __nc_cleanup_handlers) { pthread_cleanup_pop(1); } /* Call the destruction functions for TSD. */ __nc_tsd_exit(); __newlib_thread_exit(); __nc_futex_thread_exit(); if (__nc_initial_thread_id != basic_data) { pthread_mutex_lock(&__nc_thread_management_lock); --__nc_running_threads_counter; pthread_mutex_unlock(&__nc_thread_management_lock); } else { /* This is the main thread - wait for other threads to complete. */ wait_for_threads(); exit(0); } pthread_mutex_lock(&__nc_thread_management_lock); basic_data->retval = retval; if (joinable) { /* If somebody is waiting for this thread, signal. */ basic_data->status = THREAD_TERMINATED; pthread_cond_signal(&basic_data->join_condvar); } /* * We can release TLS+TDB - thread id and its return value are still * kept in basic_data. */ nc_release_tls_node(tdb->tls_node, tdb); if (!joinable) { nc_release_basic_data_mu(basic_data); } /* Now add the stack to the list but keep it marked as used. */ nc_free_memory_block_mu(THREAD_STACK_MEMORY, stack_node); if (1 == __nc_running_threads_counter) { pthread_cond_signal(&__nc_last_thread_cond); } pthread_mutex_unlock(&__nc_thread_management_lock); irt_thread.thread_exit(is_used); nc_abort(); }
NCerror freeNCDAPCOMMON(NCDAPCOMMON* dapcomm) { /* abort the metadata file */ (void)nc_abort(getncid(dapcomm)); freenccache(dapcomm,dapcomm->cdf.cache); nclistfree(dapcomm->cdf.projectedvars); nullfree(dapcomm->cdf.recorddimname); /* free the trees */ freecdfroot34(dapcomm->cdf.ddsroot); dapcomm->cdf.ddsroot = NULL; freecdfroot34(dapcomm->cdf.fullddsroot); dapcomm->cdf.fullddsroot = NULL; if(dapcomm->oc.ocdasroot != NULL) oc_root_free(dapcomm->oc.conn,dapcomm->oc.ocdasroot); dapcomm->oc.ocdasroot = NULL; oc_close(dapcomm->oc.conn); /* also reclaims remaining OC trees */ ncurifree(dapcomm->oc.url); nullfree(dapcomm->oc.urltext); nullfree(dapcomm->oc.rawurltext); dcefree((DCEnode*)dapcomm->oc.dapconstraint); dapcomm->oc.dapconstraint = NULL; free(dapcomm); return NC_NOERR; }
int nc_close(int ncid) { int status = NC_NOERR; NC *ncp; status = NC_check_id(ncid, &ncp); if(status != NC_NOERR) return status; if(NC_indef(ncp)) { status = NC_endef(ncp, 0, 1, 0, 1); /* TODO: defaults */ if(status != NC_NOERR ) { (void) nc_abort(ncid); return status; } } else if(!NC_readonly(ncp)) { status = NC_sync(ncp); /* flush buffers before any filesize comparisons */ (void) ncp->nciop->sync(ncp->nciop); } /* * If file opened for writing and filesize is less than * what it should be (due to previous use of NOFILL mode), * pad it to correct size, as reported by NC_calcsize(). */ if (status == ENOERR) { off_t filesize; /* current size of open file */ off_t calcsize; /* calculated file size, from header */ status = ncio_filesize(ncp->nciop, &filesize); if(status != ENOERR) return status; status = NC_calcsize(ncp, &calcsize); if(status != NC_NOERR) return status; if(filesize < calcsize && !NC_readonly(ncp)) { status = ncio_pad_length(ncp->nciop, calcsize); if(status != ENOERR) return status; } } (void) ncio_close(ncp->nciop, 0); ncp->nciop = NULL; del_from_NCList(ncp); free_NC(ncp); return status; }
int ncabort(int ncid) { const int status = nc_abort(ncid); if(status != NC_NOERR) { nc_advise("ncabort", status, "ncid %d", ncid); return -1; } return 0; }
/* Initializes all globals except for the initial thread structure. */ void __nc_initialize_globals(void) { /* * Fetch the ABI tables from the IRT. If we don't have these, all is lost. */ __nc_initialize_interfaces(&irt_thread); if (pthread_mutex_init(&__nc_thread_management_lock, NULL) != 0) nc_abort(); /* * Tell ThreadSanitizer to not generate happens-before arcs between uses of * this mutex. Otherwise we miss to many real races. * When not running under ThreadSanitizer, this is just a call to an empty * function. */ ANNOTATE_NOT_HAPPENS_BEFORE_MUTEX(&__nc_thread_management_lock); if (pthread_cond_init(&__nc_last_thread_cond, NULL) != 0) nc_abort(); STAILQ_INIT(&__nc_thread_memory_blocks[0]); STAILQ_INIT(&__nc_thread_memory_blocks[1]); __nc_thread_initialized = 1; }
/* Initialize a newly allocated TDB to some default values. */ static void nc_tdb_init(nc_thread_descriptor_t *tdb, nc_basic_thread_data_t *basic_data) { tdb->tls_base = tdb; tdb->joinable = PTHREAD_CREATE_JOINABLE; tdb->join_waiting = 0; tdb->stack_node = NULL; tdb->tls_node = NULL; tdb->start_func = NULL; tdb->state = NULL; tdb->irt_thread_data = NULL; tdb->basic_data = basic_data; basic_data->retval = NULL; basic_data->status = THREAD_RUNNING; if (pthread_cond_init(&basic_data->join_condvar, NULL) != 0) nc_abort(); basic_data->tdb = tdb; }
int NCD3_abort(int ncid) { NC* drno; NCDAPCOMMON* dapcomm; int ncstatus = NC_NOERR; ncstatus = NC_check_id(ncid, (NC**)&drno); if(ncstatus != NC_NOERR) return THROW(ncstatus); dapcomm = (NCDAPCOMMON*)drno->dispatchdata; ncstatus = nc_abort(drno->substrate); /* remove ourselves from NClist */ del_from_NCList(drno); /* clean NC* */ freeNCDAPCOMMON(dapcomm); if(drno->path != NULL) free(drno->path); free(drno); return THROW(ncstatus); }
int main(int argc, char **argv) { printf("\n*** Testing netcdf-4 variable chunking.\n"); printf("**** testing that fixed vars with filter end up being chunked, with good sizes..."); { int ncid; int nvars, ndims, ngatts, unlimdimid; int contig; int ndims_in, natts_in, dimids_in; int small_dimid, medium_dimid, large_dimid; int small_varid, medium_varid, large_varid; char var_name_in[NC_MAX_NAME + 1]; size_t chunksize_in[NDIMS1]; nc_type xtype_in; /* Create a netcdf-4 file with three dimensions. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, D_SMALL, D_SMALL_LEN, &small_dimid)) ERR; if (nc_def_dim(ncid, D_MEDIUM, D_MEDIUM_LEN, &medium_dimid)) ERR; if (nc_def_dim(ncid, D_LARGE, D_LARGE_LEN, &large_dimid)) ERR; /* Add three vars, with filters to force chunking. */ if (nc_def_var(ncid, V_SMALL, NC_INT64, NDIMS1, &small_dimid, &small_varid)) ERR; if (nc_def_var_deflate(ncid, small_varid, 0, 1, 4)) ERR; if (nc_def_var(ncid, V_MEDIUM, NC_INT64, NDIMS1, &medium_dimid, &medium_varid)) ERR; if (nc_def_var_deflate(ncid, medium_varid, 1, 0, 0)) ERR; if (nc_def_var(ncid, V_LARGE, NC_INT64, NDIMS1, &large_dimid, &large_varid)) ERR; if (nc_def_var_fletcher32(ncid, large_varid, 1)) ERR; if (nc_close(ncid)) ERR; /* Open the file and check. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR; if (nvars != 3 || ndims != 3 || ngatts != 0 || unlimdimid != -1) ERR; if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, &dimids_in, &natts_in)) ERR; if (strcmp(var_name_in, V_SMALL) || xtype_in != NC_INT64 || ndims_in != 1 || natts_in != 0) ERR; /* Make sure chunking sizes are what we expect. */ if (nc_inq_var_chunking(ncid, small_varid, &contig, chunksize_in)) ERR; if (contig || chunksize_in[0] != D_SMALL_LEN) ERR; if (nc_inq_var_chunking(ncid, medium_varid, &contig, chunksize_in)) ERR; if (contig || chunksize_in[0] * sizeof(long long) > DEFAULT_CHUNK_SIZE) ERR; if (nc_inq_var_chunking(ncid, large_varid, &contig, chunksize_in)) ERR; if (contig || chunksize_in[0] * sizeof(long long) > DEFAULT_CHUNK_SIZE) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("**** testing default chunksizes..."); { int nvars, ndims, ngatts, unlimdimid; int contig; #define NUM_DIM 4 #define NUM_TYPE 2 int ncid; int dim_len[NUM_DIM] = {NC_UNLIMITED, 100, 1000, 2000}; size_t chunksize_in[NUM_DIM]; int type_id[NUM_TYPE] = {NC_BYTE, NC_INT}; int dimid[NUM_DIM], varid[NUM_TYPE]; char dim_name[NC_MAX_NAME + 1], var_name[NC_MAX_NAME + 1]; int d, t; /* Create a netcdf-4 file with NUM_DIM dimensions. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; for (d = 0; d < NUM_DIM; d++) { sprintf(dim_name, "dim_%d", dim_len[d]); #ifdef PRINT_DEFAULT_CHUNKSIZE_TABLE printf("creating dim %s\n", dim_name); #endif if (nc_def_dim(ncid, dim_name, dim_len[d], &dimid[d])) ERR; } for (t = 0; t < NUM_TYPE; t++) { sprintf(var_name, "var_%d", type_id[t]); if (nc_def_var(ncid, var_name, type_id[t], NUM_DIM, dimid, &varid[t])) ERR; if (nc_inq_var_chunking(ncid, varid[t], &contig, chunksize_in)) ERR; #ifdef PRINT_DEFAULT_CHUNKSIZE_TABLE printf("chunksizes for %d x %d x %d x %d var: %d x %d x %d x %d (=%d)\n", dim_len[0], dim_len[1], dim_len[2], dim_len[3], (int)chunksize_in[0], (int)chunksize_in[1], (int)chunksize_in[2], (int)chunksize_in[3], (int)(chunksize_in[0] * chunksize_in[1] * chunksize_in[2] * chunksize_in[3])); #endif } if (nc_close(ncid)) ERR; /* Open the file and check. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR; if (nvars != NUM_TYPE || ndims != NUM_DIM || ngatts != 0 || unlimdimid != 0) ERR; for (t = 0; t < NUM_TYPE; t++) { sprintf(var_name, "var_%d", type_id[t]); if (nc_inq_var_chunking(ncid, varid[t], &contig, chunksize_in)) ERR; if (contig) ERR; #ifdef PRINT_DEFAULT_CHUNKSIZE_TABLE printf("chunksizes for %d x %d x %d x %d var: %d x %d x %d x %d (=%d)\n", dim_len[0], dim_len[1], dim_len[2], dim_len[3], (int)chunksize_in[0], (int)chunksize_in[1], (int)chunksize_in[2], (int)chunksize_in[3], (int)(chunksize_in[0] * chunksize_in[1] * chunksize_in[2] * chunksize_in[3])); #endif } if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("**** testing that chunking works on classic mode files..."); { #define D_SMALL_LEN2 66 int ncid; int nvars, ndims, ngatts, unlimdimid; int contig; int ndims_in, natts_in, dimids_in; int small_dimid, medium_dimid, large_dimid; int small_varid, medium_varid, large_varid; char var_name_in[NC_MAX_NAME + 1]; size_t chunks[1], chunksize_in; nc_type xtype_in; /* Create a netcdf-4 file with three dimensions. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, D_SMALL, D_SMALL_LEN2, &small_dimid)) ERR; if (nc_def_dim(ncid, D_MEDIUM, D_MEDIUM_LEN, &medium_dimid)) ERR; if (nc_def_dim(ncid, D_LARGE, D_LARGE_LEN, &large_dimid)) ERR; /* Add three vars. */ if (nc_def_var(ncid, V_SMALL, NC_INT64, NDIMS1, &small_dimid, &small_varid)) ERR; if (nc_def_var_chunking(ncid, small_varid, 1, NULL)) ERR; if (nc_def_var(ncid, V_MEDIUM, NC_INT64, NDIMS1, &medium_dimid, &medium_varid)) ERR; chunks[0] = D_MEDIUM_LEN / 100; if (nc_def_var_chunking(ncid, medium_varid, 0, chunks)) ERR; if (nc_def_var_deflate(ncid, medium_varid, 1, 0, 0)) ERR; if (nc_def_var(ncid, V_LARGE, NC_INT64, NDIMS1, &large_dimid, &large_varid)) ERR; chunks[0] = D_LARGE_LEN / 1000; if (nc_def_var_chunking(ncid, large_varid, 0, chunks)) ERR; if (nc_def_var_fletcher32(ncid, large_varid, 1)) ERR; if (nc_close(ncid)) ERR; /* Open the file and check. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR; if (nvars != 3 || ndims != 3 || ngatts != 0 || unlimdimid != -1) ERR; if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, &dimids_in, &natts_in)) ERR; if (strcmp(var_name_in, V_SMALL) || xtype_in != NC_INT64 || ndims_in != 1 || natts_in != 0) ERR; /* Make sure chunking settings are what we expect. */ if (nc_inq_var_chunking(ncid, small_varid, &contig, &chunksize_in)) ERR; if (!contig) ERR; if (nc_inq_var_chunking(ncid, medium_varid, &contig, &chunksize_in)) ERR; if (contig || chunksize_in != D_MEDIUM_LEN / 100) ERR; if (nc_inq_var_chunking(ncid, large_varid, &contig, &chunksize_in)) ERR; if (contig || chunksize_in != D_LARGE_LEN / 1000) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("**** testing many chunking and contiguous variables..."); { #define NDIMS_3 3 #define NUM_PLANS 30 #define D_SNEAKINESS "sneakiness" #define D_SNEAKINESS_LEN 5 #define D_CLEVERNESS "clevernesss" #define D_CLEVERNESS_LEN 3 #define D_EFFECTIVENESS "effectiveness" #define D_EFFECTIVENESS_LEN 2 int ncid, dimids[NDIMS_3], varid[NUM_PLANS]; size_t chunksize[NDIMS_3] = {D_SNEAKINESS_LEN, D_CLEVERNESS_LEN, D_EFFECTIVENESS_LEN}; char plan_name[NC_MAX_NAME + 1]; int contig; size_t chunksize_in[NDIMS_3]; int i, j; /* Create a netcdf-4 file with three dimensions. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, D_SNEAKINESS, D_SNEAKINESS_LEN, &dimids[0])) ERR; if (nc_def_dim(ncid, D_CLEVERNESS, D_CLEVERNESS_LEN, &dimids[1])) ERR; if (nc_def_dim(ncid, D_EFFECTIVENESS, D_EFFECTIVENESS_LEN, &dimids[2])) ERR; /* Oh that tricky Cardinal Richelieu, he had many plans! */ for (i = 0; i < NUM_PLANS; i++) { sprintf(plan_name, "Richelieu_sneaky_plan_%d", i); if (nc_def_var(ncid, plan_name, i % (NC_STRING - 1) + 1, NDIMS_3, dimids, &varid[i])) ERR; if (i % 2 && nc_def_var_chunking(ncid, varid[i], 0, chunksize)) ERR; } /* Check the chunking. */ for (i = 0; i < NUM_PLANS; i++) { if (nc_inq_var_chunking(ncid, varid[i], &contig, chunksize_in)) ERR; if (i % 2) { for (j = 0; j < NDIMS_3; j++) if (chunksize_in[j] != chunksize[j]) ERR; } else if (!contig) ERR; } if (nc_close(ncid)) ERR; /* Open the file and check. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; /* Check the chunking. */ for (i = 0; i < NUM_PLANS; i++) { if (nc_inq_var_chunking(ncid, varid[i], &contig, chunksize_in)) ERR; if (i % 2) { for (j = 0; j < NDIMS_3; j++) if (chunksize_in[j] != chunksize[j]) ERR; } else if (!contig) ERR; } if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("**** testing that too large chunksizes fail..."); { #define D_SMALL_LEN2 66 int stat = NC_NOERR; int ncid; int nvars, ndims, ngatts, unlimdimid; int contig; int ndims_in, natts_in, dimids_in; int small_dimid, medium_dimid, large_dimid; int small_varid; char var_name_in[NC_MAX_NAME + 1]; size_t chunks[1], chunksize_in; nc_type xtype_in; /* Create a netcdf-4 file with three dimensions. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, D_SMALL, D_SMALL_LEN2, &small_dimid)) ERR; /* Add one var. */ if (nc_def_var(ncid, V_SMALL, NC_INT64, NDIMS1, &small_dimid, &small_varid)) ERR; /* Attempt to set too large chunksizes */ chunks[0] = D_SMALL_LEN2 + 1; stat = nc_def_var_chunking(ncid, small_varid, NC_CHUNKED, chunks); if(stat != NC_EBADCHUNK) { printf("Return code is '%s', expected NC_BADCHUNK",nc_strerror(stat)); ERR; } /* try agains with proper chunksize */ chunks[0] = D_SMALL_LEN2; stat = nc_def_var_chunking(ncid, small_varid, NC_CHUNKED, chunks); if(stat != NC_NOERR) { printf("Return code is '%s', expected NC_NOERR",nc_strerror(stat)); ERR; } if (nc_abort(ncid)) ERR; } SUMMARIZE_ERR; FINAL_RESULTS; }
NcBool NcFile::abort( void ) { return NcError::set_err( nc_abort(the_id) ) == NC_NOERR; }
int main(int argc, char* argv[]) { int err = 0; int ecode = 0; int ncid; int cmode, format; int nprocs, rank; MPI_Comm comm=MPI_COMM_SELF; MPI_Info info=MPI_INFO_NULL; printf("\n*** Testing nc_inq_format_extended for pnetcdf..."); MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (nprocs > 1 && rank == 0) printf("This test program is intended to run on ONE process\n"); if (rank > 0) goto fn_exit; /* first, use PnetCDF to create a file with default header/variable alignment */ #ifdef DISABLE_PNETCDF_ALIGNMENT MPI_Info_create(&info); MPI_Info_set(info, "nc_header_align_size", "1"); MPI_Info_set(info, "nc_var_align_size", "1"); #endif /* test CDF-1 file format */ cmode = NC_PNETCDF | NC_CLOBBER; if (nc_create_par(FILENAME, cmode, comm, info, &ncid)) ERR_RET; if (nc_enddef(ncid)) ERR; if(nc_inq_format_extended(ncid,&format,&cmode)) ERR; if((cmode & NC_PNETCDF) != NC_PNETCDF) { printf("***FAIL at line %d: mode was %08x ; expected %08x\n",__LINE__,cmode,NC_PNETCDF); ecode = 1; ERR; } if(format != NC_FORMATX_PNETCDF) { printf("***FAIL at line %d: format was %d ; expected %d\n",__LINE__,format,NC_FORMATX_PNETCDF); ecode = 1; ERR; } /* test CDF-2 file format */ cmode = NC_PNETCDF | NC_CLOBBER | NC_64BIT_OFFSET; if (nc_create_par(FILENAME, cmode, comm, info, &ncid)) ERR_RET; if (nc_enddef(ncid)) ERR; if(nc_inq_format_extended(ncid,&format,&cmode)) ERR; if((cmode & NC_64BIT_OFFSET) != NC_64BIT_OFFSET) { printf("***FAIL at line %d: mode was %08x ; expected %08x\n",__LINE__,cmode,NC_64BIT_OFFSET); ecode = 1; ERR; } if(format != NC_FORMATX_PNETCDF) { printf("***FAIL at line %d: format was %d ; expected %d\n",__LINE__,format,NC_FORMATX_PNETCDF); ecode = 1; ERR; } /* test CDF-5 file format */ cmode = NC_PNETCDF | NC_CLOBBER | NC_64BIT_DATA; if (nc_create_par(FILENAME, cmode, comm, info, &ncid)) ERR_RET; if (nc_enddef(ncid)) ERR; if(nc_inq_format_extended(ncid,&format,&cmode)) ERR; if((cmode & NC_64BIT_DATA) != NC_64BIT_DATA) { printf("***FAIL at line %d: mode was %08x ; expected %08x\n",__LINE__,cmode,NC_64BIT_DATA); ecode = 1; ERR; } if(format != NC_FORMATX_PNETCDF) { printf("***FAIL at line %d: format was %d ; expected %d\n",__LINE__,format,NC_FORMATX_PNETCDF); ecode = 1; ERR; } if (nc_abort(ncid)) ERR; fn_exit: MPI_Finalize(); SUMMARIZE_ERR; FINAL_RESULTS; return ecode; }
int main(int argc, char **argv) { printf("\n*** Testing user-defined formats.\n"); printf("*** testing simple user-defined format..."); { int ncid; NC_Dispatch *disp_in; int i; /* Create an empty file to play with. */ if (nc_create(FILE_NAME, 0, &ncid)) ERR; if (nc_close(ncid)) ERR; /* Test all available user-defined format slots. */ for (i = 0; i < NUM_UDFS; i++) { /* Add our user defined format. */ if (nc_def_user_format(mode[i], &tst_dispatcher, NULL)) ERR; /* Check that our user-defined format has been added. */ if (nc_inq_user_format(mode[i], &disp_in, NULL)) ERR; if (disp_in != &tst_dispatcher) ERR; /* Open file with our defined functions. */ if (nc_open(FILE_NAME, mode[i], &ncid)) ERR; if (nc_close(ncid)) ERR; /* Open file again and abort, which is the same as closing it. */ if (nc_open(FILE_NAME, mode[i], &ncid)) ERR; if (nc_inq_format(ncid, NULL) != TEST_VAL_42) ERR; if (nc_inq_format_extended(ncid, NULL, NULL) != TEST_VAL_42) ERR; if (nc_abort(ncid) != TEST_VAL_42) ERR; } } SUMMARIZE_ERR; printf("*** testing user-defined format with magic number..."); { int ncid; NC_Dispatch *disp_in; char magic_number[5] = "1111"; char dummy_data[11] = "0123456789"; char magic_number_in[NC_MAX_MAGIC_NUMBER_LEN]; FILE *FP; int i; /* Create a file with magic number at start. */ if (!(FP = fopen(FILE_NAME, "w"))) ERR; if (fwrite(magic_number, sizeof(char), strlen(magic_number), FP) != strlen(magic_number)) ERR; if (fwrite(dummy_data, sizeof(char), strlen(dummy_data), FP) != strlen(dummy_data)) ERR; if (fclose(FP)) ERR; /* Test all available user-defined format slots. */ for (i = 0; i < NUM_UDFS; i++) { /* Add our test user defined format. */ if (nc_def_user_format(mode[i], &tst_dispatcher, magic_number)) ERR; /* Check that our user-defined format has been added. */ if (nc_inq_user_format(mode[i], &disp_in, magic_number_in)) ERR; if (disp_in != &tst_dispatcher) ERR; if (strncmp(magic_number, magic_number_in, strlen(magic_number))) ERR; /* Open file with our defined functions. */ if (nc_open(FILE_NAME, mode[i], &ncid)) ERR; if (nc_close(ncid)) ERR; /* Open file again and abort, which is the same as closing * it. This time we don't specify a mode, because the magic * number is used to identify the file. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_inq_format(ncid, NULL) != TEST_VAL_42) ERR; if (nc_inq_format_extended(ncid, NULL, NULL) != TEST_VAL_42) ERR; if (nc_abort(ncid) != TEST_VAL_42) ERR; } } SUMMARIZE_ERR; FINAL_RESULTS; }
NCdsHandle_t *NCdsHandleCreate (const char *pattern, const char *name, int dncid, NCtimeStep tsMode, utUnit *tUnitIn, double sTime, double eTime) { size_t i, j, strLen, strOffset, ncNum = 0, index; char *str [] = { "{year}", "{month}", "{day}", "{hour}", "{minute}", "{second}" }; char *searchStr, *subStr, **fileNames = (char **) NULL, tsUnitStr [NCsizeString]; int *ncids = (int *) NULL, tvarid, status; int endYear, endMonth, year, month, day, hour, minute; float second; double time = 0.0, scale, offset; utUnit tUnitOut; NCdsHandle_t *dsh; if ((searchStr = malloc (strlen (pattern) + 1)) == (char *) NULL) { CMmsgPrint (CMmsgSysError, "Memory allocation error in: NCdsHandleCreate ()!"); return ((NCdsHandle_t *) NULL); } if ((utCalendar (eTime,tUnitIn,&endYear,&endMonth,&day,&hour,&minute,&second) != 0) || (utCalendar (sTime,tUnitIn,&year, &month, &day,&hour,&minute,&second) != 0)) { CMmsgPrint (CMmsgAppError, "Calender scanning error in:%s %d",__FILE__,__LINE__); goto ABORT; } switch (tsMode) { case NCtimeYear: sprintf (tsUnitStr,"years since %04d-01-01 00:00 0.0",year); break; case NCtimeMonth: sprintf (tsUnitStr,"months since %04d-%02d-01 00:00 0.0",year, month); break; case NCtimeDay: sprintf (tsUnitStr,"days since %04d-%02d-%02d 00:00 0.0",year, month, day); break; case NCtimeHour: sprintf (tsUnitStr,"hours since %04d-%02d-%02d %02d:00 0.0",year, month, day, hour); break; case NCtimeMinute: sprintf (tsUnitStr,"minutes since %04d-%02d-%02d %02d:%02d 0.0", year, month, day, hour, minute); break; case NCtimeSecond: sprintf (tsUnitStr,"seconds since %04d-%02d-%02d %02d:%02d %.1f", year, month, day, hour, minute, second); break; } if (tsMode > NCtimeMonth) { if ((utScan (tsUnitStr, &tUnitOut) != 0) || (utConvert (tUnitIn, &tUnitOut, &scale, &offset) != 0)) { CMmsgPrint (CMmsgAppError, "Time unit scanning error in: %s %d",__FILE__,__LINE__); goto ABORT; } sTime = sTime * scale + offset; eTime = eTime * scale + offset; } else { sTime = 0.0; eTime = tsMode > NCtimeYear ? (endYear - year) * 12 + (endMonth - month + 1) : (double) (year - endYear); } do { if (tsMode > NCtimeMonth) { if (utCalendar (sTime + time,&tUnitOut,&year,&month,&day,&hour,&minute,&second) != 0) { CMmsgPrint (CMmsgAppError, "Time unit scaning error in: %s %d",__FILE__,__LINE__); goto ABORT; } } strcpy (searchStr, pattern); for (i = 0;i < tsMode; ++i) if ((subStr = strstr (searchStr,str [i])) == (char *) NULL) break; else { strOffset = strlen (str [i]); strLen = strlen (subStr) - strOffset; switch (i) { case NCtimeYear: sprintf (subStr,"%04d", year); subStr += 4; strOffset -= 4; break; case NCtimeMonth: sprintf (subStr,"%02d", month); subStr += 2; strOffset -= 2; break; case NCtimeDay: sprintf (subStr,"%02d", day); subStr += 2; strOffset -= 2; break; case NCtimeHour: sprintf (subStr,"%02d", hour); subStr += 2; strOffset -= 2; break; case NCtimeMinute: sprintf (subStr,"%02d", minute); subStr += 2; strOffset -= 2; break; case NCtimeSecond: sprintf (subStr,"%04.1f",second); subStr += 4; strOffset -= 4; break; } for (j = 0;j <= strLen; j++) subStr [j] = subStr [j + strOffset]; } if ((ncNum == 0) || (strcmp (fileNames [ncNum - 1], searchStr) != 0)) { if (((fileNames = (char **) realloc (fileNames, (ncNum + 1) * sizeof (char *))) == (char **) NULL) || ((ncids = (int *) realloc (ncids, (ncNum + 1) * sizeof (int))) == (int *) NULL)) { CMmsgPrint (CMmsgSysError, "Memory allocation error in: %s %d",__FILE__,__LINE__); goto ABORT; } else ncNum++; if ((fileNames [ncNum - 1] = (char *) malloc (strlen (searchStr) + 1)) == (char *) NULL) { CMmsgPrint (CMmsgSysError, "Memory allocation error in: %s %d",__FILE__,__LINE__); goto ABORT; } strcpy (fileNames [ncNum - 1], searchStr); if (((ncids [ncNum - 1] = NCfileCreate (fileNames [ncNum - 1], dncid)) == NCfailed) || (NCfileVarAdd (ncids [ncNum - 1], name, NC_FLOAT, NC_DOUBLE, NC_FLOAT) == NCfailed) || (NCfileSetTimeUnit (ncids [ncNum - 1], tsUnitStr) == NCfailed) || (NCfileSetMissingVal (ncids [ncNum - 1], -9999.0) == NCfailed) || ((tvarid = NCdataGetTVarId (ncids [ncNum - 1])) == NCfailed)) goto ABORT; index = 0; } if ((status = nc_put_var1_double (ncids [ncNum - 1],tvarid,&index, &time)) != NC_NOERR) { NCprintNCError (status,"NCdsHandleCreate"); goto ABORT; } index++; if (tsMode == NCtimeMonth) { month++; if (month > 12) { month = 1; year++;} } if (tsMode == NCtimeYear) { year++; } time = time + 1.0; } while ((sTime + time) < eTime); for (i = 0;i < ncNum; i++) nc_sync (ncids [i]); if ((dsh = NCdsHandleOpenByIds (ncids, ncNum)) == (NCdsHandle_t *) NULL) goto ABORT; for (i = 0;i < ncNum; i++) free (fileNames [i]); utClear (&tUnitOut); free (fileNames); free (ncids); free (searchStr); return (dsh); ABORT: for (i = 0;i < ncNum;i++) { nc_abort (ncids [i]); unlink (fileNames [i]); if (fileNames [i] != (char *) NULL) free (fileNames [i]); } utClear (&tUnitOut); if (fileNames != (char **) NULL) free (fileNames); free (searchStr); return ((NCdsHandle_t *) NULL); }