2018-12-07 05:56:42 +08:00
|
|
|
/* This is part of the netCDF package. Copyright 2018 University
|
2012-04-09 06:47:38 +08:00
|
|
|
Corporation for Atmospheric Research/Unidata See COPYRIGHT file for
|
|
|
|
conditions of use. See www.unidata.ucar.edu for more info.
|
|
|
|
|
|
|
|
Test small files.
|
|
|
|
|
|
|
|
$Id: tst_small.c,v 1.15 2008/10/20 01:48:08 ed Exp $
|
|
|
|
*/
|
|
|
|
|
2019-04-20 10:32:26 +08:00
|
|
|
#include "config.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include "netcdf.h"
|
|
|
|
#include "nc_tests.h"
|
2016-10-22 03:24:40 +08:00
|
|
|
#include "err_macros.h"
|
2012-04-09 06:47:38 +08:00
|
|
|
|
2019-04-20 10:32:26 +08:00
|
|
|
#undef DBG
|
2012-04-09 06:47:38 +08:00
|
|
|
|
2019-04-20 10:32:26 +08:00
|
|
|
/* Test extending an existing file */
|
2012-04-09 06:47:38 +08:00
|
|
|
|
2019-04-20 10:32:26 +08:00
|
|
|
#define NCFILENAME "tst_mmap3.nc"
|
2012-04-09 06:47:38 +08:00
|
|
|
|
|
|
|
#define ATT_NAME "Atom"
|
2016-10-22 03:24:40 +08:00
|
|
|
#define MAX_LEN 7
|
2012-04-09 06:47:38 +08:00
|
|
|
|
|
|
|
#define ONE_DIM 1
|
|
|
|
#define MAX_RECS 10
|
|
|
|
|
|
|
|
#define DIM1_NAME "Time"
|
|
|
|
#define DIM2_NAME "DataStrLen"
|
2019-04-20 10:32:26 +08:00
|
|
|
#define DIM3_NAME "X"
|
|
|
|
#define DIM3_LEN 30
|
2012-04-09 06:47:38 +08:00
|
|
|
#define VAR_NAME "Times"
|
2019-04-20 10:32:26 +08:00
|
|
|
#define VAR_NAME2 "var2"
|
|
|
|
#define VAR_NAME3 "var3"
|
2012-04-09 06:47:38 +08:00
|
|
|
#define STR_LEN 19
|
|
|
|
#define NUM_VALS 2
|
|
|
|
#define NDIMS 2
|
|
|
|
#define TITLE " OUTPUT FROM WRF V2.0.3.1 MODEL"
|
|
|
|
#define ATT_NAME2 "TITLE"
|
2019-04-20 10:32:26 +08:00
|
|
|
#define ATT_NAME3 "MISC"
|
|
|
|
|
|
|
|
#define NUM_VARS 2
|
2012-04-09 06:47:38 +08:00
|
|
|
|
2012-05-15 11:47:52 +08:00
|
|
|
static int status = NC_NOERR;
|
|
|
|
|
2012-06-24 03:25:49 +08:00
|
|
|
/* Control flags */
|
2019-04-20 10:32:26 +08:00
|
|
|
static int persist, usenetcdf4, mmap, diskless, file, openfile;
|
|
|
|
static char* filename = NCFILENAME;
|
|
|
|
static int diskmode = 0;
|
|
|
|
|
|
|
|
#ifdef DBG
|
|
|
|
|
|
|
|
static int
|
|
|
|
ERR_report_local(int stat, const char* file, int line)
|
|
|
|
{
|
|
|
|
fflush(stdout);
|
|
|
|
fprintf(stderr, "Sorry! Unexpected result, %s, line: %d; status=(%d)%s\n",
|
|
|
|
file,line,stat,nc_strerror(stat));
|
|
|
|
fflush(stderr);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
#undef ERRSTAT
|
|
|
|
#define ERRSTAT(stat) {err+=ERR_report_local(stat,__FILE__,__LINE__);}
|
2012-06-24 03:25:49 +08:00
|
|
|
|
2019-04-20 10:32:26 +08:00
|
|
|
static int
|
|
|
|
catch(void)
|
|
|
|
{
|
|
|
|
fflush(stdout); /* Make sure our stdout is synced with stderr. */ \
|
|
|
|
err++; \
|
|
|
|
fprintf(stderr, "Sorry! Unexpected result, %s, line: %d\n", \
|
|
|
|
__FILE__, __LINE__); \
|
|
|
|
fflush(stderr); \
|
|
|
|
return 2; \
|
|
|
|
}
|
|
|
|
|
|
|
|
#undef ERR
|
|
|
|
#define ERR return catch()
|
|
|
|
|
|
|
|
#endif
|
2012-06-24 03:25:49 +08:00
|
|
|
|
2019-04-20 10:32:26 +08:00
|
|
|
static char*
|
2018-10-11 03:32:17 +08:00
|
|
|
smode(int mode)
|
|
|
|
{
|
|
|
|
static char ms[8192];
|
|
|
|
ms[0] = '\0';
|
|
|
|
if(mode & NC_NETCDF4)
|
|
|
|
strcat(ms,"NC_NETCDF4");
|
|
|
|
else
|
|
|
|
strcat(ms,"NC_NETCDF3");
|
|
|
|
if(mode & NC_DISKLESS)
|
|
|
|
strcat(ms,"|NC_DISKLESS");
|
|
|
|
if(mode & NC_WRITE)
|
|
|
|
strcat(ms,"|NC_WRITE");
|
|
|
|
if(mode & NC_NOCLOBBER)
|
|
|
|
strcat(ms,"|NC_NOCLOBBER");
|
2019-04-20 10:32:26 +08:00
|
|
|
else
|
|
|
|
strcat(ms,"|NC_CLOBBER");
|
2018-10-11 03:32:17 +08:00
|
|
|
if(mode & NC_INMEMORY)
|
|
|
|
strcat(ms,"|NC_INMEMORY");
|
|
|
|
if(mode & NC_PERSIST)
|
|
|
|
strcat(ms,"|NC_PERSIST");
|
|
|
|
if(mode & NC_MMAP)
|
|
|
|
strcat(ms,"|NC_MMAP");
|
|
|
|
return ms;
|
|
|
|
}
|
|
|
|
|
2019-04-20 10:32:26 +08:00
|
|
|
/* Test a file with two record vars, which grow, and has attributes added. */
|
2012-04-09 06:47:38 +08:00
|
|
|
static int
|
|
|
|
test_two_growing_with_att(const char *testfile)
|
|
|
|
{
|
|
|
|
int ncid, dimid, varid[NUM_VARS];
|
|
|
|
char data[MAX_RECS], data_in;
|
|
|
|
char att_name[NC_MAX_NAME + 1];
|
|
|
|
size_t start[ONE_DIM], count[ONE_DIM], index[ONE_DIM], len_in;
|
|
|
|
int v, r;
|
|
|
|
|
2019-09-18 10:27:43 +08:00
|
|
|
/* Create a file with one unlimited dimensions, and one var. */
|
2018-10-11 03:32:17 +08:00
|
|
|
if((status=nc_create(testfile, diskmode|NC_CLOBBER, &ncid))) ERRSTAT(status);
|
2015-08-16 06:26:35 +08:00
|
|
|
if((status=nc_def_dim(ncid, DIM1_NAME, NC_UNLIMITED, &dimid))) ERRSTAT(status);
|
|
|
|
if((status=nc_def_var(ncid, VAR_NAME, NC_CHAR, 1, &dimid, &varid[0]))) ERRSTAT(status);
|
|
|
|
if((status=nc_def_var(ncid, VAR_NAME2, NC_CHAR, 1, &dimid, &varid[1]))) ERRSTAT(status);
|
2018-10-11 03:32:17 +08:00
|
|
|
if((status=nc_enddef(ncid))) ERRSTAT(status);
|
2012-04-09 06:47:38 +08:00
|
|
|
|
|
|
|
/* Create some phoney data. */
|
|
|
|
for (data[0] = 'a', r = 1; r < MAX_RECS; r++)
|
|
|
|
data[r] = data[r - 1] + 1;
|
|
|
|
|
|
|
|
for (r = 0; r < MAX_RECS; r++)
|
|
|
|
{
|
|
|
|
count[0] = 1;
|
|
|
|
start[0] = r;
|
|
|
|
sprintf(att_name, "a_%d", data[r]);
|
|
|
|
for (v = 0; v < NUM_VARS; v++)
|
|
|
|
{
|
2015-08-16 06:26:35 +08:00
|
|
|
if((status=nc_put_vara_text(ncid, varid[v], start, count, &data[r]))) ERRSTAT(status);
|
|
|
|
if((status=nc_redef(ncid))) ERRSTAT(status);
|
|
|
|
if((status=nc_put_att_text(ncid, varid[v], att_name, 1, &data[r]))) ERRSTAT(status);
|
|
|
|
if((status=nc_enddef(ncid))) ERRSTAT(status);
|
2012-04-09 06:47:38 +08:00
|
|
|
}
|
2016-10-22 03:24:40 +08:00
|
|
|
|
2018-10-11 03:32:17 +08:00
|
|
|
/* verify */
|
2015-08-16 06:26:35 +08:00
|
|
|
if((status=nc_inq_dimlen(ncid, 0, &len_in))) ERRSTAT(status);
|
2019-04-20 10:32:26 +08:00
|
|
|
if (len_in != r + 1)
|
|
|
|
ERR;
|
2012-04-09 06:47:38 +08:00
|
|
|
index[0] = r;
|
|
|
|
for (v = 0; v < NUM_VARS; v++)
|
|
|
|
{
|
2015-08-16 06:26:35 +08:00
|
|
|
if((status=nc_get_var1_text(ncid, varid[v], index, &data_in))) ERRSTAT(status);
|
2019-04-20 10:32:26 +08:00
|
|
|
if (data_in != data[r])
|
|
|
|
ERR;
|
2012-04-09 06:47:38 +08:00
|
|
|
}
|
|
|
|
} /* Next record. */
|
2019-04-20 10:32:26 +08:00
|
|
|
if((status=nc_close(ncid))) ERRSTAT(status);
|
2012-04-09 06:47:38 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-04-20 10:32:26 +08:00
|
|
|
/* Test a diskless file with one new var (dimensioned) */
|
2012-04-09 06:47:38 +08:00
|
|
|
static int
|
2019-04-20 10:32:26 +08:00
|
|
|
test_plus_one(const char *testfile)
|
2012-04-09 06:47:38 +08:00
|
|
|
{
|
2019-04-20 10:32:26 +08:00
|
|
|
int i;
|
2012-04-09 06:47:38 +08:00
|
|
|
int ncid, dimid, varid;
|
2019-04-20 10:32:26 +08:00
|
|
|
size_t count[1];
|
|
|
|
size_t start[1];
|
|
|
|
int idata[DIM3_LEN];
|
2012-04-09 06:47:38 +08:00
|
|
|
int ndims, nvars, natts, unlimdimid;
|
|
|
|
|
2019-04-20 10:32:26 +08:00
|
|
|
/* Open file */
|
|
|
|
if((status=nc_open(testfile, diskmode, &ncid))) ERRSTAT(status);
|
|
|
|
if((status=nc_redef(ncid))) ERRSTAT(status);
|
|
|
|
if((status=nc_def_dim(ncid, DIM3_NAME, DIM3_LEN, &dimid))) ERRSTAT(status);
|
|
|
|
if((status=nc_def_var(ncid, VAR_NAME3, NC_INT, 1, &dimid, &varid))) ERRSTAT(status);
|
2015-08-16 06:26:35 +08:00
|
|
|
if((status=nc_enddef(ncid))) ERRSTAT(status);
|
2012-04-09 06:47:38 +08:00
|
|
|
|
2019-04-20 10:32:26 +08:00
|
|
|
/* Write one record of var data */
|
|
|
|
for(i=0;i<DIM3_LEN;i++)
|
|
|
|
idata[i] = i;
|
|
|
|
count[0] = DIM3_LEN;
|
2012-04-09 06:47:38 +08:00
|
|
|
start[0] = 0;
|
2019-04-20 10:32:26 +08:00
|
|
|
if((status=nc_put_vara_int(ncid, varid, start, count, idata))) ERRSTAT(status);
|
2012-04-09 06:47:38 +08:00
|
|
|
|
|
|
|
/* We're done! */
|
2015-08-16 06:26:35 +08:00
|
|
|
if((status=nc_close(ncid))) ERRSTAT(status);
|
2016-10-22 03:24:40 +08:00
|
|
|
|
2012-04-09 06:47:38 +08:00
|
|
|
/* Reopen the file and check it. */
|
2019-04-20 10:32:26 +08:00
|
|
|
if((status=nc_open(testfile, diskmode & ~NC_WRITE, &ncid))) ERRSTAT(status);
|
2015-08-16 06:26:35 +08:00
|
|
|
if((status=nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid))) ERRSTAT(status);
|
2019-04-20 10:32:26 +08:00
|
|
|
if (ndims != 2 && nvars != 3 && natts != 0 && unlimdimid != 0) ERRSTAT(status);
|
|
|
|
|
|
|
|
if((status=nc_inq_varid(ncid,VAR_NAME3,&varid))) ERRSTAT(status);
|
|
|
|
|
|
|
|
memset(idata,0,sizeof(idata));
|
|
|
|
if((status=nc_get_var_int(ncid, varid, idata))) ERRSTAT(status);
|
|
|
|
for(i=0;i<DIM3_LEN;i++) {
|
|
|
|
if(idata[i] != i)
|
|
|
|
ERR;
|
|
|
|
}
|
2016-10-22 03:24:40 +08:00
|
|
|
if((status=nc_close(ncid))) ERRSTAT(status);
|
2012-04-09 06:47:38 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-04-20 10:32:26 +08:00
|
|
|
static void
|
|
|
|
parse(int argc, char** argv)
|
2012-04-09 06:47:38 +08:00
|
|
|
{
|
2012-06-24 03:25:49 +08:00
|
|
|
int i;
|
|
|
|
|
|
|
|
/* Set defaults */
|
|
|
|
persist = 0;
|
|
|
|
usenetcdf4 = 0;
|
|
|
|
mmap = 0;
|
|
|
|
diskless = 0;
|
2018-10-11 03:32:17 +08:00
|
|
|
file = 0;
|
2012-06-24 03:25:49 +08:00
|
|
|
diskmode = 0;
|
2019-04-20 10:32:26 +08:00
|
|
|
openfile = 0;
|
2012-06-24 03:25:49 +08:00
|
|
|
|
|
|
|
for(i=1;i<argc;i++) {
|
|
|
|
if(strcmp(argv[i],"diskless")==0) diskless=1;
|
|
|
|
else if(strcmp(argv[i],"mmap")==0) mmap=1;
|
2018-10-11 03:32:17 +08:00
|
|
|
else if(strcmp(argv[i],"file")==0) file=1;
|
|
|
|
else if(strcmp(argv[i],"persist")==0) persist=1;
|
2019-04-20 10:32:26 +08:00
|
|
|
else if(strcmp(argv[i],"open")==0) openfile=1;
|
|
|
|
else if(strcmp(argv[i],"create")==0) openfile=0;
|
|
|
|
else if(strncmp(argv[i],"file:",strlen("file:"))==0) {
|
|
|
|
filename = argv[i];
|
|
|
|
filename += strlen("file:");
|
|
|
|
}
|
2012-06-24 03:25:49 +08:00
|
|
|
/* ignore anything not recognized */
|
|
|
|
}
|
|
|
|
|
2018-10-11 03:32:17 +08:00
|
|
|
if(diskless && mmap) {
|
|
|
|
fprintf(stderr,"NC_DISKLESS and NC_MMAP are mutually exclusive\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2019-04-20 10:32:26 +08:00
|
|
|
}
|
2018-10-11 03:32:17 +08:00
|
|
|
|
2019-04-20 10:32:26 +08:00
|
|
|
static void
|
|
|
|
buildmode(void)
|
|
|
|
{
|
|
|
|
diskmode = 0;
|
2012-06-24 03:25:49 +08:00
|
|
|
if(diskless)
|
|
|
|
diskmode |= NC_DISKLESS;
|
2018-10-11 03:32:17 +08:00
|
|
|
if(mmap)
|
2012-06-24 03:25:49 +08:00
|
|
|
diskmode |= NC_MMAP;
|
2018-10-11 03:32:17 +08:00
|
|
|
if(persist)
|
|
|
|
diskmode |= NC_PERSIST;
|
2019-04-20 10:32:26 +08:00
|
|
|
if(openfile)
|
|
|
|
diskmode |= NC_NOCLOBBER|NC_WRITE;
|
|
|
|
}
|
2012-06-24 03:25:49 +08:00
|
|
|
|
2019-04-20 10:32:26 +08:00
|
|
|
int
|
|
|
|
main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
parse(argc,argv);
|
|
|
|
|
|
|
|
if(!diskless && !mmap && !file) {
|
|
|
|
fprintf(stderr,"file or diskless or mmap must be specified\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
buildmode();
|
|
|
|
|
|
|
|
printf("\n*** Testing %s: file=%s mode=%s\n",
|
|
|
|
(openfile?"open+modify":"create"),filename,smode(diskmode));
|
|
|
|
fflush(stdout);
|
2012-04-09 06:47:38 +08:00
|
|
|
|
|
|
|
/* case NC_FORMAT_CLASSIC: only test this format */
|
|
|
|
nc_set_default_format(NC_FORMAT_CLASSIC, NULL);
|
|
|
|
|
2019-04-20 10:32:26 +08:00
|
|
|
if(openfile) {
|
|
|
|
printf("*** testing diskless file with new variable...");
|
|
|
|
#ifdef DBG
|
|
|
|
openfile = 0;
|
|
|
|
buildmode();
|
|
|
|
test_two_growing_with_att(filename);
|
|
|
|
openfile = 1;
|
|
|
|
buildmode();
|
|
|
|
#endif
|
|
|
|
test_plus_one(filename);
|
|
|
|
} else {/* create */
|
|
|
|
printf("*** testing diskless file with two growing record "
|
2012-04-09 06:47:38 +08:00
|
|
|
"variables, with attributes added...");
|
2019-04-20 10:32:26 +08:00
|
|
|
test_two_growing_with_att(filename);
|
|
|
|
}
|
2012-04-09 06:47:38 +08:00
|
|
|
SUMMARIZE_ERR;
|
|
|
|
|
|
|
|
FINAL_RESULTS;
|
|
|
|
}
|