- Fix NCF-158 to modify ncgen flag defaults.

- Fix NCF-157 to modify DAP code to support
  partial variable retrieval.
- Fix of NCF-154 to solve problem of ncgen
  improperly processing data lists for variables
  of size greater than 2**18 bytes.
- Fix ncgen processing of char variables that have
  multiple unlimited dimensions.
- Partly fix Jira issue: NCF-145 (vlen issues).
- Benchmark program nc_test4/tst_ar4_*) requires arguments
  and should only be invoked inside a shell
  script; fixed so that they terminate cleanly
  if invoked with no arguments.
- Fix the Doxygen processing so it will work
  with make distcheck.
- Begin switchover to using an alternative to ncio.
- Begin support for in-memory (diskless) files.
This commit is contained in:
Dennis Heimbigner 2012-03-14 23:26:48 +00:00
parent b77a5faa83
commit 99eef24bc2
51 changed files with 2542 additions and 208 deletions

View File

@ -45,7 +45,6 @@ if USE_NETCDF4
H5_TEST_DIR = h5_test
LIBSRC4_DIR = libsrc4
NC_TEST4 = nc_test4
# LIBDISKLESS = libdiskless
endif
# Build the opendap client?
@ -73,7 +72,7 @@ WIN32=win32
# and run. ncgen must come before ncdump, because their tests
# depend on it.
SUBDIRS = include $(H5_TEST_DIR) libdispatch $(OCLIB) libsrc \
$(LIBDISKLESS) $(LIBSRC4_DIR) $(DAP2) $(LIBCDMR) $(LIBRPC) liblib $(V2_TEST) \
$(LIBSRC4_DIR) $(DAP2) $(LIBCDMR) $(LIBRPC) liblib $(V2_TEST) \
nc_test $(NCGEN3) $(NCGEN) $(NCDUMP) $(NC_TEST4) $(NCDAPTESTDIR) man4 \
$(EXAMPLES) $(WIN32)

View File

@ -4,11 +4,28 @@ Entries are in reverse chronological order (most recent first).
VERSION COMMENTS
------- --------
4.2 Released 2012-??-??
Fix behavior of ncgen flags so that -o => -lb
and, in the absence of any other markers, make
the default be -k1
[NCF-158]
Performance improvement to DAP code to support
fetching partial variables into the cache; especially
important when using nc_get_var() API.
A partial variable is one that has ranges attached
to the projection variables (e.g. x[1:10][20:21])
[NCF-157]
Fixed bug in ncgen in which large variables
(more than 2**18 elements) duplicates the first
2**18 values into subsequent chunks of data.
[NCF-154]
2**18 values into subsequent chunks of data
[NCF-154].
Fix bug in ncgen for vlen arrays as fields
of compound types where datalists for those
types was improperly interpreted
[NCF-145] (but see NCF-155).
4.2-rc2 Released 2012-03-02

14
cf
View File

@ -1,23 +1,27 @@
#!/bin/bash
#X="-x"
if test $# != 0 ; then
cmds=$@
fi
HDF5=1
DAP=1
#CDMR=1
#RPC=1
#PGI=1
#M32=1
#M64=1
#NB=1
if test "x$cmds" = x ; then
cmds=""
#cmds="all"
cmds="all check"
#cmds="all check"
#cmds="all dist"
#cmds="all distcheck"
#cmds="$cmds install"
fi
# Test pgi compiler
if test "x$PGI" = x1 ; then
@ -123,8 +127,8 @@ FLAGS="$FLAGS --disable-pnetcdf"
#FLAGS="$FLAGS --with-udunits"
#FLAGS="$FLAGS --with-libcf"
#FLAGS="$FLAGS --enable-benchmarks"
FLAGS="$FLAGS --enable-extra-tests"
FLAGS="$FLAGS --enable-logging"
#FLAGS="$FLAGS --enable-extra-tests"
#FLAGS="$FLAGS --enable-logging"
FLAGS="$FLAGS --disable-shared"
#FLAGS="$FLAGS --enable-shared"

View File

@ -15,7 +15,7 @@ AC_REVISION([$Id: configure.ac,v 1.450 2010/05/28 19:42:47 dmh Exp $])
AC_PREREQ([2.59])
# Initialize with name, version, and support email address.
AC_INIT([netCDF], [4.2-rc2], [support-netcdf@unidata.ucar.edu])
AC_INIT([netCDF], [4.2], [support-netcdf@unidata.ucar.edu])
# Create the VERSION file, which contains the package version from
# AC_INIT.
@ -334,6 +334,16 @@ test "x$enable_ffio" = xyes || enable_ffio=no
AC_MSG_RESULT($enable_ffio)
AM_CONDITIONAL(USE_FFIO, [test x$enable_ffio = xyes])
# Does the user want to use the new io mechanism?
#AC_MSG_CHECKING([whether new IO module will be used])
#AC_ARG_ENABLE([newio],
# [AS_HELP_STRING([--enable-newio],
# [use new io module (not yet implemented)])])
#test "x$enable_newio" = xyes || enable_newio=no
#AC_MSG_RESULT($enable_newio)
enable_newio=no
AM_CONDITIONAL(USE_NEWIO, [test x$enable_newio = xyes])
# Does the user want to enable the user-provided NEC-SX vectorization
# patch.
dnl AC_MSG_CHECKING([whether netCDF NEC-SX vectorization patch is enabled])
@ -505,32 +515,17 @@ AC_MSG_NOTICE([finding other utilities])
AC_CHECK_PROGS([DOXYGEN], [doxygen])
if test -z "$DOXYGEN"; then
AC_MSG_WARN([Doxygen not found - documentation will not be built])
else
NETCDF_DOC_CODE_FILES='../include/netcdf.h \
../examples/C/simple_xy_wr.c ../examples/C/simple_xy_rd.c \
../examples/C/sfc_pres_temp_wr.c ../examples/C/sfc_pres_temp_rd.c \
../examples/C/pres_temp_4D_wr.c ../examples/C/pres_temp_4D_rd.c \
../examples/C/simple_nc4_wr.c ../examples/C/simple_nc4_rd.c \
../examples/C/simple_xy_nc4_wr.c ../examples/C/simple_xy_nc4_rd.c \
../libdispatch/dfile.c ../libdispatch/ddim.c \
../libdispatch/dattget.c ../libdispatch/dattinq.c ../libdispatch/dattput.c \
../libdispatch/datt.c ../libdispatch/dvar.c ../libdispatch/dvarinq.c \
../libdispatch/dvarput.c ../libdispatch/dvarget.c ../libdispatch/derror.c \
../libdispatch/dcompound.c ../libdispatch/dv2i.c \
../libdispatch/dvlen.c ../libdispatch/denum.c ../libdispatch/dopaque.c \
../libdispatch/dtype.c ../libsrc4/nc4file.c ../ncdump/ncdump.c'
NETCDF_DOC_ONLY_FILES="mainpage.doc tutorial.doc \
../COPYRIGHT install.doc dispatch.doc guide.doc types.doc \
notes.doc cdl.doc architecture.doc internal.doc"
fi
# If we have doxygen, and it's enabled, then process the file.
if test "x$enable_doxygen" != xno; then
if test -n "$DOXYGEN"; then
AC_CONFIG_FILES([man4/Doxyfile])
AC_SUBST(NETCDF_DOC_CODE_FILES, ${NETCDF_DOC_CODE_FILES})
AC_SUBST(NETCDF_DOC_ONLY_FILES, ${NETCDF_DOC_ONLY_FILES})
fi
# Note: the list of files to input to doxygen
# has been moved to man4/Doxyfile.in so
# that make distcheck works correctly.
# Any new inputs should be inserted into
# man4/Doxyfile.in and possibley man4/Makefile.am
fi
# Find the install program.
@ -852,3 +847,6 @@ AC_CONFIG_FILES([Makefile
[test -f nc-config && chmod 755 nc-config])
AC_OUTPUT()

View File

@ -85,7 +85,6 @@ extern int nc_put_vara_ulonglong(int ncid, int varid,
#define NC_DISPATCH_NC4 2
#define NC_DISPATCH_NCD 4
#define NC_DISPATCH_NCR 8
#define NC_DISPATCH_DISKLESS 16
/* Define a type for use when doing e.g. nc_get_vara_long, etc. */
/* Should matche values in libsrc4/netcdf.h */
@ -139,10 +138,6 @@ extern int NCD3_initialize(void);
extern NC_Dispatch* NC4_dispatch_table;
extern int NC4_initialize(void);
/* /\* Diskless *\/ */
/* extern NC_Dispatch* NCD_dispatch_table; */
/* extern int NCD_initialize(void); */
#ifdef USE_DAP
extern NC_Dispatch* NCD4_dispatch_table;
extern int NCD4_initialize(void);

View File

@ -117,8 +117,7 @@ extern "C" {
#define NC_64BIT_OFFSET 0x0200 /**< Use large (64-bit) file offsets. Mode flag for nc_create(). */
#define NC_NETCDF4 0x1000 /**< Use netCDF-4/HDF5 format. Mode flag for nc_create(). */
#define NC_CLASSIC_MODEL 0x0100 /**< Enforce classic model. Mode flag for nc_create(). */
/* NC_DISKLESS isn't ready for prime time yet */
/* #define NC_DISKLESS 0x0002 /\**< Create a diskless file. Mode flag for nc_create(). *\/ */
#define NC_DISKLESS 0x0002 /**< Create a diskless file. Mode flag for nc_create(). */
/** Share updates, limit cacheing.
Use this in mode flags for both nc_create() and nc_open(). */
@ -360,7 +359,9 @@ by the desired type. */
#define NC_ESTORAGE (-126) /**< Can't specify both contiguous and chunking. */
#define NC_EBADCHUNK (-127) /**< Bad chunksize. */
#define NC_ENOTBUILT (-128) /**< Attempt to use feature that was not turned on when netCDF was built. */
#define NC4_LAST_ERROR (-128)
#define NC_EDISKLESS (-129) /**< Error in using diskless access. */
#define NC4_LAST_ERROR (-129)
/* This is used in netCDF-4 files for dimensions without coordinate
* vars. */

View File

@ -33,7 +33,7 @@ RPATH=-Wl,-rpath,${LFLAG}
# Might want to specify a particular C compiler with flags
CC=cc
CFLAGS=-g -O0 -Wall -DHAVE_CONFIG_H
CFLAGS=-g -O2 -Wall -DHAVE_CONFIG_H
#CFLAGS=-DHAVE_CONFIG_H
GFLAGS=-g3 -O0

View File

@ -126,7 +126,7 @@ prefetchdata3(NCDAPCOMMON* nccomm)
nelems *= dim->dim.declsize;
}
if(SHOWFETCH) {
nclog(NCLOGDBG,"prefetch: %s=%d",var->ncfullname,nelems);
nclog(NCLOGDBG,"prefetch: %s=%lu",var->ncfullname,(unsigned long)nelems);
}
if(nelems <= nccomm->cdf.smallsizelimit) {
nclistpush(vars,(ncelem)var);
@ -213,18 +213,6 @@ buildcachenode34(NCDAPCOMMON* nccomm,
NCcachenode* cachenode = NULL;
char* ce = NULL;
#ifdef IGNORE
if(FLAGSET(nccomm->controls,NCF_CACHE)) {
/* If the cache flag is on, then cache
forces whole variable projections */
int i;
/* Remove the slicing (if any) */
for(i=0;i<nclistlength(constraint->projections);i++) {
DCEprojection* p = (DCEprojection*)nclistget(constraint->projections,i);
dcemakewholeprojection(p);
}
}
#endif
ce = buildconstraintstring3(constraint);
ocstat = dap_fetch(nccomm,conn,ce,OCDATADDS,&ocroot);

View File

@ -711,6 +711,12 @@ applyclientparams34(NCDAPCOMMON* nccomm)
}
}
/* test for the force-whole-var flag */
value = oc_clientparam_get(conn,"wholevar");
if(value != NULL) {
SETFLAG(nccomm->controls,NCF_WHOLEVAR);
}
return NC_NOERR;
}

View File

@ -13,7 +13,6 @@
static void completesegments3(NClist* fullpath, NClist* segments);
static NCerror qualifyprojectionnames3(DCEprojection* proj);
static NCerror qualifyprojectionsizes3(DCEprojection* proj);
static NCerror qualifyselectionnames3(DCEselection* sel);
static NCerror matchpartialname3(NClist* nodes, NClist* segments, CDFnode** nodep);
static int matchsuffix3(NClist* matchpath, NClist* segments);
static int iscontainer(CDFnode* node);
@ -83,6 +82,8 @@ mapconstraints3(DCEconstraint* constraint,
if(ncstat) goto done;
}
#ifdef IGNORE
Only care about projections
/* Convert the selection paths to leaves in the dds tree */
for(i=0;i<nclistlength(dceselections);i++) {
DCEselection* sel = (DCEselection*)nclistget(dceselections,i);
@ -104,6 +105,7 @@ mapconstraints3(DCEconstraint* constraint,
if(ncstat) goto done;
}
}
#endif
#ifdef DEBUG
fprintf(stderr,"mapconstraint.projections: %s\n",
@ -137,10 +139,12 @@ fprintf(stderr,"qualifyconstraints.before: %s\n",
ncstat = qualifyprojectionnames3(p);
ncstat = qualifyprojectionsizes3(p);
}
#ifdef IGNORE
for(i=0;i<nclistlength(constraint->selections);i++) {
DCEselection* s = (DCEselection*)nclistget(constraint->selections,i);
ncstat = qualifyselectionnames3(s);
}
#endif
}
#ifdef DEBUG
fprintf(stderr,"qualifyconstraints.after: %s\n",
@ -215,7 +219,7 @@ fprintf(stderr,"qualifyprojectionsizes.after: %s\n",
return NC_NOERR;
}
#ifdef IGNORE
/* convert all names in selections to be fully qualified */
static NCerror
qualifyselectionnames3(DCEselection* sel)
@ -244,6 +248,7 @@ fprintf(stderr,"qualify.sel: %s -> ",
nclistfree(fullpath);
return THROW(ncstat);
}
#endif
static void
completesegments3(NClist* fullpath, NClist* segments)

View File

@ -1,17 +1,16 @@
TOPDIR="/home/dmh/mach/major"
#http://esrl.noaa.gov/psd/thredds/dodsC/Datasets/noaa.oisst.v2/sst.wkmean.1990-present.nc"
PARMS=""; ARGS=""; CON="" ; CE=""; OCON=""
PARMS=""; ARGS=""; CON="" ; CE=""; OCON="" ; VAR=""
PARMS="[log]"
#PARMS="${PARMS}[netcdf3]"
#PARMS="${PARMS}[fetch=memory]"
#PARMS="${PARMS}[cache]"
PARMS="${PARMS}[cache]"
#PARMS="${PARMS}[prefetch]"
#PARMS="${PARMS}[nocache]"
#PARMS="${PARMS}[noprefetch]"
#PARMS="${PARMS}[show=fetch]"
#PARMS="${PARMS}[wholevar]"
PARMS="${PARMS}[show=fetch]"
F="http://www.esrl.noaa.gov/psd/thredds/dodsC/Datasets/ncep.reanalysis.dailyavgs/pressure/air.1948.nc"
VAR=air
F="file:///home/dmh/mach/minor/ncdap_test/testdata3/synth1"
PROG="./ncd"
#PROG="../ncdump/ncdump"
@ -65,7 +64,10 @@ F="http://dods.ndbc.noaa.gov/thredds/dodsC/data/stdmet/46029/46029h9999.nc"
CON="wind_dir[1:10][0:0][0:0]"
F="http://nomads.ncep.noaa.gov:9090/dods/gens/gens20111011/gep20_00z"
CON="ens,time,lat,lon,prmslmsl[0:1:0][0:1:64][0:1:10][0:1:10]"
F="http://esrl.noaa.gov/psd/thredds/dodsC/Datasets/noaa.oisst.v2/sst.wkmean.1990-present.nc"
F="http://motherlode.ucar.edu:8080/thredds/dodsC/station/metar/Surface_METAR_20111122_0000.nc"
CON="weather[0:10]"
F="http://nomad1.ncep.noaa.gov:9090/dods/reanalyses/reanalysis-1/6hr/pgb/pgb"
VAR=hgtprs
fi

View File

@ -51,33 +51,30 @@ There are some exceptions to the formation of the fetch constraint.
In all cases, the fetch constraint will use any URL selections,
but will use different fetch projections.
a. URL is unconstrainable (e.g. file://...):
fetchprojection = null => fetch whole dataset
fetchprojection = null => fetch whole dataset
b. The target variable (as specified in nc_get_vara())
is already in the cache => the whole variable is there (may change later)
fetchprojection = N.A. since variable is in the cache
c. Otherwise:
fetchprojection = unsliced vara variable => fetch whole variable
is already in the cache and is whole variable.
fetchprojection = N.A. since variable is in the cache
c. Vara is requesting part of a variable but NCF_WHOLEVAR flag is set.
fetchprojection = unsliced vara variable => fetch whole variable
d. Vara is requesting part of a variable and NCF_WHOLEVAR flag is not set.
fetchprojection = sliced vara variable => fetch part variable
2. At this point, whole target variable is available in the cache.
2. At this point, all or part of the target variable is available in the cache.
3. We build a projection to walk (guide) the use of the oc
data procedures in extract the required data from the cache.
In all cases:
walkprojection = merge(urlprojection,varaprojection)
#ifdef FUTURE
An eventual optimization involves caching a part of the
variable of interest using the merge of the
url constraints and the getvar constraint.
This means we need only extract the complete contents of the cache.
Notice that this will not necessarily be a direct memory to
memory copy because the dap encoding still needs to be
interpreted. For this case, we derive a walk projection
from the merged projection that will properly access
the cached data. This walk projection
shifts the merged projection so all slices
start at 0 and have a stride of 1.
#endif
data procedures in extract the required data from the cache.
For cases a,b,c:
walkprojection = merge(urlprojection,varaprojection)
For case d:
walkprojection = varaprojection without slicing.
This means we need only extract the complete contents of the cache.
Notice that this will not necessarily be a direct memory to
memory copy because the dap encoding still needs to be
interpreted. For this case, we derive a walk projection
from the vara projection that will properly access the cached data.
This walk projection shifts the merged projection so all slices
start at 0 and have a stride of 1.
*/
@ -112,8 +109,9 @@ nc3d_getvarx(int ncid, int varid,
DCEprojection* walkprojection = NULL;
int state;
#define FETCHWHOLE 1 /* fetch whole data set */
#define FETCHPART 2 /* fetch constrained variable */
#define CACHED 4 /* whole variable is already in the cache */
#define FETCHVAR 2 /* fetch whole variable */
#define FETCHPART 4 /* fetch constrained variable */
#define CACHED 8 /* whole variable is already in the cache */
ncstat = NC_check_id(ncid, (NC**)&drno);
if(ncstat != NC_NOERR) goto fail;
@ -235,7 +233,10 @@ fprintf(stderr,"var is in cache\n");
} else if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) {
state = FETCHWHOLE;
} else {/* load using constraints */
state = FETCHPART;
if(FLAGSET(dapcomm->controls,NCF_WHOLEVAR))
state = FETCHVAR;
else
state = FETCHPART;
}
ASSERT(state != 0);
@ -250,11 +251,11 @@ fprintf(stderr,"var is in cache\n");
walkprojection = NULL;
/* Create walkprojection as the merge of the url projections
and the vara projection; will change
when we do partial variable caching */
and the vara projection; may change in FETCHPART case below*/
ncstat = daprestrictprojection(dapcomm->oc.dapconstraint->projections,
varaprojection,&walkprojection);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
#ifdef DEBUG
fprintf(stderr,"getvarx: walkprojection: |%s|\n",dumpprojection(walkprojection));
#endif
@ -285,6 +286,40 @@ fprintf(stderr,"getvarx: FETCHWHOLE: fetchconstraint: %s\n",dumpconstraint(fetch
case CACHED: {
} break;
case FETCHVAR: { /* Fetch a complete single variable */
/* Create fetch projection as the merge of the url projections
and the vara projection */
ncstat = daprestrictprojection(dapcomm->oc.dapconstraint->projections,
varaprojection,&fetchprojection);
/* elide any sequence and string dimensions (dap servers do not allow such). */
ncstat = removepseudodims(fetchprojection);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
/* Convert to a whole variable projection */
dcemakewholeprojection(fetchprojection);
#ifdef DEBUG
fprintf(stderr,"getvarx: FETCHVAR: fetchprojection: |%s|\n",dumpprojection(fetchprojection));
#endif
/* Build the complete constraint to use in the fetch */
fetchconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT);
/* merged constraint just uses the url constraint selection */
fetchconstraint->selections = dceclonelist(dapcomm->oc.dapconstraint->selections);
/* and the created fetch projection */
fetchconstraint->projections = nclistnew();
nclistpush(fetchconstraint->projections,(ncelem)fetchprojection);
#ifdef DEBUG
fprintf(stderr,"getvarx: FETCHVAR: fetchconstraint: %s\n",dumpconstraint(fetchconstraint));
#endif
/* buildcachenode3 will create a new cachenode and
will also fetch the corresponding datadds.
*/
ncstat = buildcachenode34(dapcomm,fetchconstraint,vars,&cachenode,0);
fetchconstraint = NULL; /*buildcachenode34 takes control of fetchconstraint.*/
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
} break;
case FETCHPART: {
/* Create fetch projection as the merge of the url projections
and the vara projection */
@ -294,13 +329,10 @@ fprintf(stderr,"getvarx: FETCHWHOLE: fetchconstraint: %s\n",dumpconstraint(fetch
ncstat = removepseudodims(fetchprojection);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
#ifdef FUTURE
/* Shift the varaprojection for simple walk */
dcefree((DCEnode*)walkprojection) ; /* reclaim any existing walkprojection */
walkprojection = (DCEprojection*)dceclone((DCEnode*)varaprojection);
dapshiftprojection(walkprojection);
#else /*!FUTURE*/
dcemakewholeprojection(fetchprojection);
#endif /*FUTURE*/
#ifdef DEBUG
fprintf(stderr,"getvarx: FETCHPART: fetchprojection: |%s|\n",dumpprojection(fetchprojection));
@ -340,6 +372,7 @@ fprintf(stderr,"cache.datadds=%s\n",dumptree(cachenode->datadds));
/* Fix up varainfo to use the cache */
varainfo->cache = cachenode;
cachenode = NULL;
varainfo->varaprojection = walkprojection;
walkprojection = NULL;
@ -351,8 +384,9 @@ fprintf(stderr,"cache.datadds=%s\n",dumptree(cachenode->datadds));
/* Switch to datadds tree space*/
varainfo->target = xtarget;
ncstat = moveto(dapcomm,varainfo,cachenode->datadds,data);
ncstat = moveto(dapcomm,varainfo,varainfo->cache->datadds,data);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
goto ok;
fail:

View File

@ -75,6 +75,8 @@ typedef unsigned int NCFLAGS;
#define NCF_UNCONSTRAINABLE (0x0040) /* Not a constrainable URL */
#define NCF_SHOWFETCH (0x0080) /* show fetch calls */
#define NCF_INMEMORY (0x0100) /* cause oc to store data in memory */
#define NCF_WHOLEVAR (0x0200) /* retrieve only whole variables (as opposed to partial variable)
into cache */
/* Define all the default on flags */
#define DFALT_ON_FLAGS (NCF_PREFETCH)

View File

@ -281,8 +281,9 @@ fprintf(stderr,"constrained dds: %s\n",dumptree(dapcomm->cdf.ddsroot));
/* ignore all constraints */
dapcomm->oc.urltext = nc_uribuild(dapcomm->oc.url,NULL,NULL,0);
} else {
nc_urisetconstraints(dapcomm->oc.url,
buildconstraintstring3(dapcomm->oc.dapconstraint));
char* constraintstring = buildconstraintstring3(dapcomm->oc.dapconstraint);
nc_urisetconstraints(dapcomm->oc.url,constraintstring);
nullfree(constraintstring);
dapcomm->oc.urltext = nc_uribuild(dapcomm->oc.url,NULL,NULL,NC_URICONSTRAINTS);
}

View File

@ -245,6 +245,8 @@ nc_strerror(int ncerr1)
case NC_ENOTBUILT:
return "NetCDF: Attempt to use feature that was not turned on "
"when netCDF was built.";
case NC_EDISKLESS:
return "NetCDF: Error in using diskless access";
default:
return "Unknown Error";
}

View File

@ -1311,12 +1311,6 @@ NC_create(const char *path, int cmode, size_t initialsz,
if((isurl = NC_testurl(path)))
model = NC_urlmodel(path);
/* /\* Look to the incoming cmode for hints *\/ */
/* if(model == 0) { */
/* if(cmode & NC_DISKLESS) */
/* model = NC_DISPATCH_DISKLESS; */
/* } */
/* Look to the incoming cmode for hints */
if(model == 0) {
if(cmode & NC_NETCDF4 || cmode & NC_PNETCDF)
@ -1374,8 +1368,6 @@ NC_create(const char *path, int cmode, size_t initialsz,
#endif
if(model == (NC_DISPATCH_NC4))
dispatcher = NC4_dispatch_table;
/* else if(model == (NC_DISPATCH_DISKLESS)) */
/* dispatcher = NCD_dispatch_table; */
else
#endif /*USE_NETCDF4*/
#ifdef USE_DAP

View File

@ -18,13 +18,18 @@ libnetcdf3_la_SOURCES = v1hpg.c onstack.h \
nclistmgr.c putget.c attr.c nc3dispatch.c nc.c var.c dim.c ncx.c \
ncx.h lookup3.c pstdint.h
if USE_NEWIO
libnetcdf3_la_SOURCES += ncstdio.h ncstdio.h ncFile.c
else !USE_NEWIO
# Does the user want to use ffio, a replacement for posixio for Cray
# computers?
if USE_FFIO
libnetcdf3_la_SOURCES += ffio.c
else
else !USE_FFIO
libnetcdf3_la_SOURCES += posixio.c
endif
endif !USE_FFIO
endif !USE_NEWIO
noinst_LTLIBRARIES = libnetcdf3.la
# These files are cleaned on developer workstations (and then rebuilt

View File

@ -283,15 +283,23 @@ read_numrecs(NC *ncp)
#define NC_NUMRECS_OFFSET 4
#define NC_NUMRECS_EXTENT 4
#ifdef USE_NEWIO
if(!(status = ncstdio_seek(ncp->nciop,NC_NUMRECS_OFFSET))
return status;
status = ncstdio_read(ncp->nciop,NC_NUMRECS_EXTENT, (void*)&xp);
#else
status = ncp->nciop->get(ncp->nciop,
NC_NUMRECS_OFFSET, NC_NUMRECS_EXTENT, 0, (void **)&xp);
/* cast away const */
#endif
if(status != NC_NOERR)
return status;
status = ncx_get_size_t(&xp, &nrecs);
#ifndef USE_NEWIO
(void) ncp->nciop->rel(ncp->nciop, NC_NUMRECS_OFFSET, 0);
#endif
if(status == NC_NOERR)
{
@ -316,8 +324,14 @@ write_numrecs(NC *ncp)
assert(!NC_readonly(ncp));
assert(!NC_indef(ncp));
#ifdef USE_NEWIO
if(!(status = ncstdio_seek(ncp->nciop,NC_NUMRECS_OFFSET))
return status;
status = ncstdio_read(ncp->nciop,NC_NUMRECS_EXTENT, (void*)&xp);
#else
status = ncp->nciop->get(ncp->nciop,
NC_NUMRECS_OFFSET, NC_NUMRECS_EXTENT, RGN_WRITE, &xp);
#endif
if(status != NC_NOERR)
return status;
@ -326,8 +340,9 @@ write_numrecs(NC *ncp)
status = ncx_put_size_t(&xp, &nrecs);
}
#ifndef USE_NEWIO
(void) ncp->nciop->rel(ncp->nciop, NC_NUMRECS_OFFSET, RGN_MODIFIED);
#endif
if(status == NC_NOERR)
fClr(ncp->flags, NC_NDIRTY);
@ -504,6 +519,7 @@ fill_added(NC *gnu, NC *old)
}
#ifndef USE_NEWIO
/*
* Move the records "out".
* Fill as needed.
@ -545,10 +561,9 @@ move_recs_r(NC *gnu, NC *old)
continue; /* nothing to do */
assert(gnu_off > old_off);
status = gnu->nciop->move(gnu->nciop, gnu_off, old_off,
old_varp->len, 0);
if(status != NC_NOERR)
return status;
@ -560,7 +575,6 @@ move_recs_r(NC *gnu, NC *old)
return NC_NOERR;
}
/*
* Move the "non record" variables "out".
* Fill as needed.
@ -608,7 +622,7 @@ move_vars_r(NC *gnu, NC *old)
return NC_NOERR;
}
#endif /*!NEWIO*/
/*
* Given a valid ncp, return NC_EVARSIZE if any variable has a bad len
@ -783,7 +797,11 @@ NC_endef(NC *ncp,
fClr(ncp->flags, NC_CREAT | NC_INDEF);
#ifdef USE_NEWIO
return ncstdio_sync(ncp->nciop);
#else
return ncp->nciop->sync(ncp->nciop);
#endif
}
#ifdef LOCKNUMREC
@ -918,10 +936,14 @@ NC3_create(const char *path, int ioflags,
assert(ncp->xsz == ncx_len_NC(ncp,sizeof_off_t));
#ifdef USE_NEWIO
status = ncFile_create(path,ioflags,&ncp->nciop);
#else
status = ncio_create(path, ioflags,
initialsz,
0, ncp->xsz, &ncp->chunk,
&ncp->nciop, &xp);
#endif
if(status != NC_NOERR)
{
/* translate error status */
@ -953,15 +975,23 @@ NC3_create(const char *path, int ioflags,
if(chunksizehintp != NULL)
*chunksizehintp = ncp->chunk;
#ifdef USE_NEWIO
ncstdio_uid(ncp->nciop,&ncp->int_ncid);
#else
ncp->int_ncid = ncp->nciop->fd;
#endif
if(ncpp) *ncpp = ncp;
return NC_NOERR;
unwind_ioc:
#ifdef USE_NEWIO
ncstdio_close(ncdp->nciop,1); /* delete */
#else
(void) ncio_close(ncp->nciop, 1); /* N.B.: unlink */
ncp->nciop = NULL;
#endif
/*FALLTHRU*/
unwind_alloc:
free_NC(ncp);
@ -1022,9 +1052,13 @@ NC3_open(const char * path, int ioflags,
return NC_EINVAL;
#endif
#ifdef USE_NEWIO
status = ncFile_open(path,ioflags,&ncp->nciop);
#else
status = ncio_open(path, ioflags,
0, 0, &ncp->chunk,
&ncp->nciop, 0);
#endif
if(status)
goto unwind_alloc;
@ -1052,15 +1086,23 @@ NC3_open(const char * path, int ioflags,
*chunksizehintp = ncp->chunk;
#ifdef USE_NEWIO
ncstdio_uid(ncp->nciop,&ncp->int_ncid);
#else
ncp->int_ncid = ncp->nciop->fd;
#endif
if(ncpp) *ncpp = ncp;
return NC_NOERR;
unwind_ioc:
#ifdef USE_NEWIO
(void)ncstdio_close(ncp->nciop,0);
#else
(void) ncio_close(ncp->nciop, 0);
ncp->nciop = NULL;
#endif
/*FALLTHRU*/
unwind_alloc:
free_NC(ncp);
@ -1109,7 +1151,11 @@ NC3_close(int ncid)
{
status = NC_sync(ncp);
/* flush buffers before any filesize comparisons */
#ifdef USE_NEWIO
(void)ncstdio_sync(ncp->nciop);
#else
(void) ncp->nciop->sync(ncp->nciop);
#endif
}
/*
@ -1120,21 +1166,31 @@ NC3_close(int ncid)
if (status == ENOERR) {
off_t filesize; /* current size of open file */
off_t calcsize; /* calculated file size, from header */
#ifdef USE_NEWIO
#else
status = ncio_filesize(ncp->nciop, &filesize);
#endif
if(status != ENOERR)
return status;
status = NC_calcsize(ncp, &calcsize);
if(status != NC_NOERR)
return status;
if(filesize < calcsize && !NC_readonly(ncp)) {
#ifdef USE_NEWIO
#else
status = ncio_pad_length(ncp->nciop, calcsize);
#endif
if(status != ENOERR)
return status;
}
}
#ifdef USE_NEWIO
(void*)ncstdio_close(ncp->nciop,0);
#else
(void) ncio_close(ncp->nciop, 0);
ncp->nciop = NULL;
#endif
del_from_NCList(ncp);
@ -1178,8 +1234,12 @@ NC3_abort(int ncid)
}
#ifdef USE_NEWIO
(void)ncstdio_close(ncp->nciop,doUnlink);
#else
(void) ncio_close(ncp->nciop, doUnlink);
ncp->nciop = NULL;
#endif
del_from_NCList(ncp);
@ -1289,20 +1349,13 @@ NC3_sync(int ncid)
if(status != NC_NOERR)
return status;
#ifdef USE_NEWIO
status = ncstdio_sync(ncp->nciop);
#else
status = ncp->nciop->sync(ncp->nciop);
#endif
if(status != NC_NOERR)
return status;
#ifdef USE_FSYNC
/* may improve concurrent access, but slows performance if
* called frequently */
#ifndef WIN32
status = fsync(ncp->nciop->fd);
#else
status = _commit(ncp->nciop->fd);
#endif /* WIN32 */
#endif /* USE_FSYNC */
return status;
}
@ -1519,9 +1572,14 @@ nc_delete_mp(const char * path, int basepe)
if(basepe != 0)
return NC_EINVAL;
#endif
#ifdef USE_NEWIO
status = ncFile_open(path,NC_NOWRITE,&ncp->nciop);
#else
status = ncio_open(path, NC_NOWRITE,
0, 0, &ncp->chunk,
&ncp->nciop, 0);
#endif
if(status)
goto unwind_alloc;
@ -1532,15 +1590,24 @@ nc_delete_mp(const char * path, int basepe)
{
/* Not a netcdf file, don't delete */
/* ??? is this the right semantic? what if it was just too big? */
#ifdef USE_NEWIO
status = ncstdio_close(ncp->nciop,0);
#else
(void) ncio_close(ncp->nciop, 0);
ncp->nciop = NULL;
#endif
}
else
{
#ifdef USE_NEWIO
status = ncstdio_close(ncp->nciop,1);
#else
/* ncio_close does the unlink */
status = ncio_close(ncp->nciop, 1); /* ncio_close does the unlink */
ncp->nciop = NULL;
#endif
}
ncp->nciop = NULL;
unwind_alloc:
free_NC(ncp);
return status;

220
libsrc/ncFile.c Normal file
View File

@ -0,0 +1,220 @@
/*
* Copyright 2012, University Corporation for Atmospheric Research
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
/*
Implement the ncstdio.h interface using unix stdio.h
*/
/* Forward */
static int NCFile_read(ncstdio*,void*,const size_t,size_t*);
static int NCFile_write(ncstdio*,const void*,const size_t,size_t*);
static int NCFile_free(ncstdio*);
static int NCFile_close(ncstdio*,int);
static int NCFile_flush(ncstdio*)
static int NCFile_seek(ncstdio*,off_t);
static int NCFile_sync(ncstdio*,off_t);
static int NCFile_uid(ncstdio*,int*);
/* Define the stdio.h base operators */
struct NCFile_ops NCFile_ops = {
NCFile_read,
NCFile_write,
NCFile_free,
NCFile_close,
NCFile_flush,
NCFile_seek,
NCFile_sync,
NCFile_uid
};
/* In order to implement the close with delete, we
need the file path.
*/
struct ncFileState {
char* path;
File* file;
};
static struct ncFileState
getState(ncstdio* iop)
{
if(iop != NULL) {
if(iop->state != NULL) {
return (struct ncFileState*)iop->state;
}
}
return NULL;
}
int
ncFile_create(const char *path, int ioflags, ncstdio** filepp)
{
ncstdio* filep;
File* f;
struct ncFileState* state;
f = fopen(path,"w+");
if(f == NULL)
return errno;
filep = (ncstdio*)calloc(sizeof(ncstdio),1);
if(filep == NULL) {fclose(f); return NC_ENOMEM;}
state = (ncstdio*)calloc(sizeof(ncFileState),1);
if(state == NULL) {fclose(f); free(filep); return NC_ENOMEM;}
filep->ops = &NCFILE_ops;
filep->ioflags = ioflags;
filep->state = (void*)state;
state->path = strdup(path);
state->file = f;
if(filepp) *filepp = filep;
return NC_NOERR;
}
int
ncFile_open(const char *path, int ioflags, ncstdio** filepp)
{
ncstdio* filep;
File* f;
if(fIsSet(ioflags,NC_NOCLOBBER))
f = fopen(path,"r");
else
f = fopen(path,"w+");
if(f == NULL)
return errno;
filep = (ncstdio*)calloc(sizeof(ncstdio),1);
if(filep == NULL) {fclose(f); return NC_ENOMEM;}
state = (ncstdio*)calloc(sizeof(ncFileState),1);
if(state == NULL) {fclose(f); free(filep); return NC_ENOMEM;}
filep->ops = &NCFILE_ops;
filep->ioflags = ioflags;
filep->state = (void*)state;
state->path = strdup(path);
state->file = f;
if(filepp) *filepp = filep;
return NC_NOERR;
}
static int
NCFile_close(ncstdio* filep, int delfile)
{
struct ncFileState* state;
if(filep == NULL) return NC_EINVAL;
state = (struct ncFileState*)filep->state;
if(state == NULL || state->file == NULL) return NC_NOERR;
fclose(state->file);
state->file = NULL;
if(delfile)
unlink(state->path);
return NC_NOERR;
}
static int
NCFile_free(ncstdio* filep)
{
struct ncFileState* state;
if(filep == NULL) return NC_NOERR;
state = (struct ncFileState*)filep->state;
if(state != NULL) {
if(state->file != NULL) return NC_EINVAL;
if(state->path != NULL)
free(state->path);
free(state);
}
free(filep);
return NC_NOERR;
}
static int
NCFile_flush(ncstdio* filep);
{
File* state;
if(filep == NULL) return NC_EINVAL;
state = (struct ncFileState*)filep->state;
if(state == NULL) return NC_EINVAL;
if(state->file == NULL) return NC_EINVAL;
fflush(state->file);
return NC_NOERR;
}
static int
NCFile_sync(ncstdio* filep);
{
File* state;
#ifdef USE_FSYNC
int fd;
#endif
if(filep == NULL) return NC_EINVAL;
state = (struct ncFileState*)filep->state;
if(state == NULL) return NC_EINVAL;
if(state->file == NULL) return NC_EINVAL;
#ifdef HAVE_FSYNC
#ifdef USE_FSYNC
fd = fileno(state->file);
#ifndef WIN32
fsync(fd);
#else
_commit(fd);
#endif /* WIN32 */
#endif
#endif
return NC_NOERR;
}
static int
NCFile_seek(ncstdio* filep, off_t pos);
{
struct ncFileState* state;
if(filep == NULL) return NC_EINVAL;
state = (struct ncFileState*)filep->state;
if(state == NULL) return NC_EINVAL;
if(state->file == NULL) return NC_EINVAL;
if(!fseek(state->file,pos)) return (errno > 0 ?errno : EINVAL);
return NC_NOERR;
}
static int
NCFile_read(ncstdio* filep, void* memory, const size_t size, size_t* actualp);
{
struct ncFileState* state;
size_t actual;
if(filep == NULL) return NC_EINVAL;
state = (struct ncFileState*)filep->state;
if(state == NULL || state->file == NULL) return NC_EINVAL;
actual = fread(memory,1,size,state->file);
if(actualp) *actualp = actual;
return (actual < size ? NC_EIO : NC_NOERR);
}
static int
NCFile_write(ncstdio* filep, const void* memory, const size_t size, size_t* actual);
{
struct ncFileState* state;
size_t actual;
if(filep == NULL) return NC_EINVAL;
state = (struct ncFileState*)filep->state;
if(state == NULL || state->file == NULL) return NC_EINVAL;
actual = fwrite(memory,1,size,state->file);
if(actualp) *actualp = actual;
return (actual < size ? NC_EIO : NC_NOERR);
}
static int
NCFile_uid(ncstdio* filep, int* idp)
{
struct ncFileState* state;
if(filep == NULL) return NC_EINVAL;
state = (struct ncFileState*)filep->state;
if(state == NULL || state->file == NULL) return NC_EINVAL;
if(idp) *idp = fileno(state->file);
return NC_NOERR;
}

66
libsrc/ncstdio.c Normal file
View File

@ -0,0 +1,66 @@
/*
* Copyright 2012, University Corporation for Atmospheric Research
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
*/
#include <stdlib.h>
#include <stdio.h>
#include "ncstdio.h"
/* Wrappers for ncstdio dispatch methods */
int
ncstdio_uid(ncstdio* iop, int* idp)
{
if(iop == NULL) return NC_EINVAL;
return iop->ops.uid(iop,idp);
}
int
ncstdio_sync(ncstdio* iop)
{
if(iop == NULL) return NC_EINVAL;
return iop->ops.sync(iop);
}
int
ncstdio_flush(ncstdio* iop)
{
if(iop == NULL) return NC_EINVAL;
return iop->ops.flush(iop);
}
int
ncstdio_free(ncstdio* iop)
{
if(iop == NULL) return NC_NOERR;
return iop->ops.free(iop);
}
int
ncstdio_close(ncstdio* iop)
{
if(iop == NULL) return NC_EINVAL;
return iop->ops.close(iop);
}
int
ncstdio_seek(ncstdio* iop, off_t pos)
{
if(iop == NULL) return NC_EINVAL;
return iop->ops.seek(iop,pos);
}
int
ncstdio_read(ncstdio* iop, void* memory, const size_t size, size_t* actual)
{
if(iop == NULL) return NC_EINVAL;
return iop->ops.read(iop,memory,size,actual);
}
int
ncstdio_write(ncstdio* iop, const void* memory, const size_t size, size_t* actual)
{
if(iop == NULL) return NC_EINVAL;
return iop->ops.write(iop,memory,size,actual);
}

60
libsrc/ncstdio.h Normal file
View File

@ -0,0 +1,60 @@
/*
* Copyright 2012, University Corporation for Atmospheric Research
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
*/
#ifndef _NCSTDIO_H_
#define _NCSTDIO_H_
typedef struct ncstdio ncstdio; /* forward reference */
/*
* netcdf i/o abstraction
*/
struct ncstdio {
int ioflags; /* make visible for fIsSet macro access*/
/* Internal state of the stdio dispatcher */
void* state;
/* dispatch functions; never called directly by any higher-level code */
struct ncstdio_ops {
int (*read)(ncstdio*,void*,const size_t,size_t*);
int (*write)(ncstdio*,const void*,const size_t,size_t*);
int (*free)(ncstdio*);
int (*close)(ncstdio*,int);
int (*flush)(ncstdio*)
int (*seek)(ncstdio*,off_t);
int (*sync)(ncstdio*);
int (*uid)(ncstdio*,int*);
} ops;
};
extern int
ncstdio_close(ncstdio* ncstdiop, int deletefile);
extern int
ncstdio_flush(ncstdio* ncstdiop);
extern int
ncstdio_seek(ncstdio* ncstdiop, off_t pos);
extern int
ncstdio_sync(ncstdio* ncstdiop);
extern int
ncstdio_read(ncstdio* ncstdiop, void* memory, const size_t size, size_t* actual);
extern int
ncstdio_write(ncstdio* ncstdiop, const void* memory, const size_t size, size_t* actual);
extern int
ncstdio_uid(ncstdio* ncstdiop,int*);
/* export all known ncstdio implementation create/open procedures */
extern int ncFile_create(const char *path, int ioflags, ncstdio** filepp);
extern int ncFile_open(const char *path, int ioflags, ncstdio** filepp);
#ifdef USE_DISKLESS
extern int ncMemory_create(const char *path, int ioflags, ncstdio** filepp);
extern int ncMemory_open(const char *path, int ioflags, ncstdio** filepp);
#endif
#endif /* _NCSTDIO_H_* /

View File

@ -214,9 +214,11 @@ nc4_create_file(const char *path, int cmode, MPI_Comm comm, MPI_Info info,
LOG((3, "nc4_create_file: path %s mode 0x%x", path, cmode));
assert(nc && path);
/* If this file already exists, and NC_NOCLOBBER is specified,
return an error. */
if ((cmode & NC_NOCLOBBER) && (fp = fopen(path, "r")))
if (!(cmode & NC_DISKLESS) && (cmode & NC_NOCLOBBER)
&& (fp = fopen(path, "r")))
{
fclose(fp);
return NC_EEXIST;
@ -242,6 +244,7 @@ nc4_create_file(const char *path, int cmode, MPI_Comm comm, MPI_Info info,
if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG))
BAIL(NC_EHDFERR);
#endif /* EXTRA_TESTS */
#ifdef USE_PARALLEL
/* If this is a parallel file create, set up the file creation
property list. */
@ -262,6 +265,10 @@ nc4_create_file(const char *path, int cmode, MPI_Comm comm, MPI_Info info,
}
}
#else /* only set cache for non-parallel... */
if(cmode & NC_DISKLESS) {
if (H5Pset_fapl_core(fapl_id, 4096, 0))
BAIL(NC_EDISKLESS);
}
if (H5Pset_cache(fapl_id, 0, nc4_chunk_cache_nelems, nc4_chunk_cache_size,
nc4_chunk_cache_preemption) < 0)
BAIL(NC_EHDFERR);
@ -371,9 +378,13 @@ NC4_create(const char* path, int cmode, size_t initialsz, int basepe,
/* Check the cmode for validity. */
if (cmode & ~(NC_NOCLOBBER | NC_64BIT_OFFSET
| NC_NETCDF4 | NC_CLASSIC_MODEL
| NC_SHARE | NC_MPIIO | NC_MPIPOSIX | NC_LOCK | NC_PNETCDF)
| NC_SHARE | NC_MPIIO | NC_MPIPOSIX | NC_LOCK | NC_PNETCDF
| NC_DISKLESS
)
|| (cmode & NC_MPIIO && cmode & NC_MPIPOSIX)
|| (cmode & NC_64BIT_OFFSET && cmode & NC_NETCDF4))
|| (cmode & NC_64BIT_OFFSET && cmode & NC_NETCDF4)
|| (cmode & (NC_MPIIO | NC_MPIPOSIX) && cmode & NC_DISKLESS)
)
return NC_EINVAL;
/* Allocate the storage for this file info struct, and fill it with

View File

@ -506,7 +506,7 @@ FILE_VERSION_FILTER =
# file name after the option, if omitted DoxygenLayout.xml will be used as the name
# of the layout file.
LAYOUT_FILE = @top_srcdir@/man4/DoxygenLayout.xml
LAYOUT_FILE = @abs_top_srcdir@/man4/DoxygenLayout.xml
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
@ -568,7 +568,48 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = @NETCDF_DOC_CODE_FILES@ @NETCDF_DOC_ONLY_FILES@
INPUT = \
@abs_top_srcdir@/man4/mainpage.doc \
@abs_top_srcdir@/man4/tutorial.doc \
@abs_top_srcdir@/man4/install.doc \
@abs_top_srcdir@/man4/dispatch.doc \
@abs_top_srcdir@/man4/guide.doc \
@abs_top_srcdir@/man4/types.doc \
@abs_top_srcdir@/man4/notes.doc \
@abs_top_srcdir@/man4/cdl.doc \
@abs_top_srcdir@/man4/architecture.doc \
@abs_top_srcdir@/man4/internal.doc \
@abs_top_srcdir@/COPYRIGHT \
@abs_top_srcdir@/include/netcdf.h \
@abs_top_srcdir@/examples/C/simple_xy_wr.c \
@abs_top_srcdir@/examples/C/simple_xy_rd.c \
@abs_top_srcdir@/examples/C/sfc_pres_temp_wr.c \
@abs_top_srcdir@/examples/C/sfc_pres_temp_rd.c \
@abs_top_srcdir@/examples/C/pres_temp_4D_wr.c \
@abs_top_srcdir@/examples/C/pres_temp_4D_rd.c \
@abs_top_srcdir@/examples/C/simple_nc4_wr.c \
@abs_top_srcdir@/examples/C/simple_nc4_rd.c \
@abs_top_srcdir@/examples/C/simple_xy_nc4_wr.c \
@abs_top_srcdir@/examples/C/simple_xy_nc4_rd.c \
@abs_top_srcdir@/libdispatch/dfile.c \
@abs_top_srcdir@/libdispatch/ddim.c \
@abs_top_srcdir@/libdispatch/dattget.c \
@abs_top_srcdir@/libdispatch/dattinq.c \
@abs_top_srcdir@/libdispatch/dattput.c \
@abs_top_srcdir@/libdispatch/datt.c \
@abs_top_srcdir@/libdispatch/dvar.c \
@abs_top_srcdir@/libdispatch/dvarinq.c \
@abs_top_srcdir@/libdispatch/dvarput.c \
@abs_top_srcdir@/libdispatch/dvarget.c \
@abs_top_srcdir@/libdispatch/derror.c \
@abs_top_srcdir@/libdispatch/dcompound.c \
@abs_top_srcdir@/libdispatch/dv2i.c \
@abs_top_srcdir@/libdispatch/dvlen.c \
@abs_top_srcdir@/libdispatch/denum.c \
@abs_top_srcdir@/libdispatch/dopaque.c \
@abs_top_srcdir@/libdispatch/dtype.c \
@abs_top_srcdir@/libsrc4/nc4file.c \
@abs_top_srcdir@/ncdump/ncdump.c
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
@ -591,7 +632,7 @@ FILE_PATTERNS =
# should be searched for input files as well. Possible values are YES and NO.
# If left blank NO is used.
RECURSIVE = NO
RECURSIVE = YES
# The EXCLUDE tag can be used to specify files and/or directories that should
# excluded from the INPUT source files. This way you can easily exclude a
@ -625,7 +666,7 @@ EXCLUDE_SYMBOLS =
# directories that contain example code fragments that are included (see
# the \include command).
EXAMPLE_PATH = ../examples/C
EXAMPLE_PATH = @abs_top_srcdir@/examples/C
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
@ -645,7 +686,19 @@ EXAMPLE_RECURSIVE = NO
# directories that contain image that are included in the documentation (see
# the \image command).
IMAGE_PATH = images
#IMAGE_PATH = @abs_top_srcdir@/man4/images
IMAGE_PATH = \
@abs_top_srcdir@/man4/images/chunking2.png \
@abs_top_srcdir@/man4/images/compatibility3.png \
@abs_top_srcdir@/man4/images/compression.png \
@abs_top_srcdir@/man4/images/groups.png \
@abs_top_srcdir@/man4/images/nc4-model.png \
@abs_top_srcdir@/man4/images/ncatts.png \
@abs_top_srcdir@/man4/images/nc-classic-uml.png \
@abs_top_srcdir@/man4/images/nccoords.png \
@abs_top_srcdir@/man4/images/ncfile.png \
@abs_top_srcdir@/man4/images/netcdf_architecture.png \
@abs_top_srcdir@/man4/images/pnetcdf.png
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
@ -786,7 +839,7 @@ HTML_HEADER =
# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
HTML_FOOTER = @top_srcdir@/man4/footer.html
HTML_FOOTER = @abs_top_srcdir@/man4/footer.html
# If the HTML_TIMESTAMP tag is set to YES then the generated HTML
# documentation will contain the timesstamp.

View File

@ -2,9 +2,12 @@
# Copyright 2005-2011, see the COPYRIGHT file for more information.
# This file builds the netcdf documentation.
# These files will be included with the dist.
EXTRA_DIST = netcdf.m4 DoxygenLayout.xml Doxyfile.in \
@NETCDF_DOC_ONLY_FILES@ footer.html
EXTRA_DIST = netcdf.m4 DoxygenLayout.xml Doxyfile.in footer.html \
mainpage.doc tutorial.doc install.doc dispatch.doc \
guide.doc types.doc notes.doc cdl.doc \
architecture.doc internal.doc
# Turn off parallel builds in this directory.
.NOTPARALLEL:
@ -23,10 +26,18 @@ if BUILD_DOCS
# $(directory)/man_page_2.3: doxyfile.stamp
# Timestamp to prevent rebuilds.
doxyfile.stamp:
doxyfile.stamp:
$(DOXYGEN) Doxyfile
echo Timestamp > doxyfile.stamp
# Note: in order to work with distcheck,
# the Doxyfile needs to be preprocessed
# to insert actual location of $(srcdir)
#BUILT_SOURCES = Doxyfile.tmp
#Doxyfile.tmp: Doxyfile
# sed -e 's|$$[({]rootdir[})]|$(abs_top_srcdir)|g' <Doxyfile > ./Doxyfile.tmp
CLEANFILES = doxyfile.stamp html latex man
all-local: doxyfile.stamp

View File

@ -1,3 +1,3 @@
EXTRA_DIST = aqua.jpg chunking2.png compatibility3.png compression.png \
groups.png nc4-model.png ncatts.png nc-classic-uml.png nccoords.png \
ncfile.png pnetcdf.png terra.jpg
ncfile.png pnetcdf.png terra.jpg netcdf_architecture.png

View File

@ -1023,10 +1023,10 @@ main(int argc, char **argv)
argc -= optind;
argv += optind;
/* If no file arguments left, print usage message. */
/* If no file arguments left, report and exit */
if (argc < 1)
{
usage();
printf("no file specified\n");
return 0;
}

View File

@ -128,10 +128,10 @@ main(int argc, char **argv)
argc -= optind;
argv += optind;
/* If no file arguments left, print usage message. */
/* If no file arguments left, report and exit */
if (argc < 1)
{
usage();
printf("no file specified\n");
return 0;
}

View File

@ -75,9 +75,9 @@ variables:
file Name of netCDF file\n"
static void
usage(void)
usage(char* msg)
{
fprintf(stderr, "tst_ar4 -v -h -t -c CACHE_SIZE file\n%s", USAGE);
fprintf(stderr, "%s\nusage: tst_ar4 -v -h -t -c CACHE_SIZE file\n%s", msg,USAGE);
}
#define NDIMS3 3
@ -129,17 +129,17 @@ main(int argc, char **argv)
sscanf(optarg, "%d", &cache);
break;
case '?':
usage();
usage("unknown option");
return 1;
}
argc -= optind;
argv += optind;
/* If no file arguments left, print usage message. */
/* If no file arguments left, report and exit */
if (argc < 1)
{
usage();
printf("no file specified\n");
return 0;
}

View File

@ -244,10 +244,10 @@ main(int argc, char **argv)
argc -= optind;
argv += optind;
/* If no file arguments left, print usage message. */
/* If no file arguments left, report and exit */
if (argc < 1)
{
usage();
printf("no file specified\n");
return 0;
}

View File

@ -28,8 +28,9 @@ endif
test_cvt3_SOURCES = test_cvt.c
test_vara_SOURCES = test_vara.c
check_PROGRAMS += t_dap3a test_cvt3 test_vara
TESTS += t_dap3a test_cvt3 test_vara
test_partvar_SOURCES = test_partvar.c
check_PROGRAMS += t_dap3a test_cvt3 test_vara test_partvar
TESTS += t_dap3a test_cvt3 test_vara test_partvar
test_varm3_SOURCES = test_varm3.c
TESTS += test_varm3
check_PROGRAMS += test_varm3

1630
ncdap_test/test_partvar.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -98,7 +98,7 @@ tst_iter.sh
BUILT_SOURCES = ctest.c ctest64.c
if EXTRA_TESTS
ctest.c:
$(top_builddir)/ncgen/ncgen -lc -o ctest0.nc $(top_srcdir)/ncgen/c0.cdl > $(srcdir)/ctest.c
$(top_builddir)/ncgen/ncgen -lc -o ctest0.nc $(top_srcdir)/ncgen/c0.cdl >$(srcdir)/ctest.c
ctest64.c:
$(top_builddir)/ncgen/ncgen -v2 -lc -o ctest0_64.nc $(top_srcdir)/ncgen/c0.cdl > $(srcdir)/ctest64.c
@ -108,7 +108,7 @@ ctest.c:
ctest64.c:
cp ref_ctest64.c ctest64.c
endif # CROSS_COMPILING
endif
# NCGEN4 additions
SUBDIRS=cdl4 expected4

View File

@ -1,12 +1,17 @@
netcdf y {
netcdf ref_tst_unlim2 {
dimensions:
Dr = UNLIMITED ; // (2 currently)
D1 = 1 ;
D2 = 2 ;
D3 = 3 ;
U=unlimited;
D2 = 2 ;
U1 = UNLIMITED ; // (1 currently)
U2 = UNLIMITED ; // (2 currently)
UU3 = UNLIMITED ; // (4 currently)
UUU2 = UNLIMITED ; // (2 currently)
UUU3 = UNLIMITED ; // (6 currently)
variables:
char cuu(Dr,D2,U);
char cuu(U1,D2,UU3);
char cuuu(U2,UUU2,UUU3);
data:
cuu = {{"a","def"}}, {{"xy"}};
cuu = {"a","def"},{"xy"} ;
cuuu = {{"1", "two"}}, {{"three"},{"four","xy"}} ;
}

View File

@ -85,7 +85,13 @@ SPECIALTESTS3="ref_tst_special_atts3"
SPECIALTESTS="ref_tst_special_atts ${SPECIALTESTS3}"
XFAILTESTS="ref_const_test ref_tst_unlim2 ref_tst_chardata"
XFAILTESTS=""
# Fails because ncdump does not output multiple unlim char types correctly
XFAILTESTS="ref_tst_unlim2 $XFAILTESTS"
# Fails because ?
XFAILTESTS="ref_const_test $XFAILTESTS"
# Fails because ?
XFAILTESTS="ref_tst_chardata $XFAILTESTS"
# Following are generally not run
# Because of the size of their output

View File

@ -160,6 +160,9 @@ extern Constant fillconstant;
void gen_charattr(Datalist*, Bytebuffer*);
void gen_charvlen(Datalist*, Bytebuffer*);
void gen_chararray(struct Dimset*, Datalist*, Bytebuffer*, Datalist* fillsrc);
#ifndef CHARBUG
void gen_leafchararray(struct Dimset*,int,Datalist*,Bytebuffer* databuf, Datalist* fillsrc);
#endif
/* Mnemonic */
#define UNKNOWN ((size_t)0)

View File

@ -1,3 +1,5 @@
# test: ../ncdump/cdl4/ref_const_test.cdl
# test: ../ncdump/cdl4/ref_tst_chardata.cdl
K="-k3"
F="t"
#B="-B12"

View File

@ -78,6 +78,8 @@ gen_chararray(Dimset* dimset, Datalist* data, Bytebuffer* databuf, Datalist* fil
expectedsize = (xproduct * unitsize);
gen_chararrayr(dimset,0,lastunlim,databuf,data,fillchar,unitsize,expectedsize);
}
@ -88,16 +90,17 @@ gen_chararrayr(Dimset* dimset, int dimindex, int lastunlimited,
int unitsize, int expectedsize)
{
int i;
size_t dimsize = dimset->dimsyms[dimindex]->dim.declsize;
if(dimindex < lastunlimited) {
/* keep recursing */
for(i=0;i<data->length;i++) {
for(i=0;i<dimsize;i++) {
Constant* c = datalistith(data,i);
ASSERT(islistconst(c));
gen_chararrayr(dimset,dimindex+1,lastunlimited,databuf,
c->value.compoundv,fillchar,unitsize,expectedsize);
}
} else {/* we are at a list of simple constants */
} else {/* we should be at a list of simple constants */
for(i=0;i<data->length;i++) {
Constant* c = datalistith(data,i);
ASSERT(!islistconst(c));
@ -203,3 +206,72 @@ getfillchar(Datalist* fillsrc)
if(fillchar == 0) fillchar = NC_FILL_CHAR; /* default */
return fillchar;
}
#ifndef CHARBUG
void
gen_leafchararray(Dimset* dimset, int lastunlim, Datalist* data,
Bytebuffer* databuf, Datalist* fillsrc)
{
int i;
size_t expectedsize,xproduct,unitsize;
int ndims = dimset->ndims;
int fillchar = getfillchar(fillsrc);
ASSERT(bbLength(databuf) == 0);
/* Assume dimindex is the last unlimited (or 0 if their are
no unlimiteds => we should be at a list of simple constants
*/
/* Compute crossproduct upto the last dimension,
starting at the last unlimited
*/
xproduct = crossproduct(dimset,lastunlim,ndims-1);
/* Compute the required size (after padding) of each string constant */
/* expected size is the size of concat of the string constants
after padding
*/
if(ndims == 0) {
unitsize = 1;
expectedsize = (xproduct * unitsize);
} else
if(lastunlim == ndims-1) {/* last dimension is unlimited */
unitsize = 1;
expectedsize = (xproduct*dimset->dimsyms[lastunlim]->dim.declsize);
} else
{ /* last dim is not unlimited */
unitsize = dimset->dimsyms[ndims-1]->dim.declsize;
expectedsize = (xproduct * unitsize);
}
for(i=0;i<data->length;i++) {
Constant* c = datalistith(data,i);
ASSERT(!islistconst(c));
if(isstringable(c->nctype)) {
int j;
size_t constsize;
constsize = gen_charconstant(c,databuf,fillchar);
if(constsize % unitsize > 0) {
size_t padsize = unitsize - (constsize % unitsize);
for(j=0;j<padsize;j++) bbAppend(databuf,fillchar);
}
} else {
semwarn(constline(c),"Encountered non-string and non-char constant in datalist; ignored");
}
}
/* If |databuf| > expectedsize, complain: exception is zero length */
if(bbLength(databuf) == 0 && expectedsize == 1) {
/* this is okay */
} else if(bbLength(databuf) > expectedsize) {
semwarn(data->data[0].lineno,"character data list too long");
} else {
size_t bufsize = bbLength(databuf);
/* Pad to size dimproduct size */
if(bufsize % expectedsize > 0) {
size_t padsize = expectedsize - (bufsize % expectedsize);
for(i=0;i<padsize;i++) bbAppend(databuf,fillchar);
}
}
}
#endif /*!CHARBUG*/

View File

@ -8,8 +8,6 @@
#include "odom.h"
#include "offsets.h"
#undef ITERBUG
/**************************************************/
/* Code for generating data lists*/
/**************************************************/
@ -115,17 +113,28 @@ generate_array(Symbol* vsym,
ASSERT(rank > 0);
/* Start by doing the two easy cases */
/* Start by doing easy cases */
if(typecode == NC_CHAR) { /* case 1: character typed variable, rank > 0 */
#ifdef CHARBUG
if(typecode == NC_CHAR) { /* case: character typed variable, rank > 0 */
Bytebuffer* charbuf = bbNew();
odom = newodometer(dimset,NULL,NULL);
gen_chararray(dimset,vsym->data,charbuf,filler);
generator->charconstant(generator,code,charbuf);
bbFree(charbuf);
odom = newodometer(dimset,NULL,NULL);
writer(generator,vsym,code,odom->rank,odom->start,odom->count);
} else
#else /*!CHARBUG*/
/* Case: char var && dim 1..n are not unlimited */
if(findunlimited(dimset,1) == rank && typecode == NC_CHAR) {
Bytebuffer* charbuf = bbNew();
gen_leafchararray(dimset,0,vsym->data,charbuf,filler);
generator->charconstant(generator,code,charbuf);
bbFree(charbuf);
odom = newodometer(dimset,NULL,NULL);
writer(generator,vsym,code,odom->rank,odom->start,odom->count);
} else
#endif
/* Case 2: dim 1..n are not unlimited */
if(findunlimited(dimset,1) == rank) {
size_t offset = 0; /* where are we in the data list */
@ -164,7 +173,11 @@ generate_array(Symbol* vsym,
{ /* Hard case: multiple unlimited dimensions */
/* Setup iterator and odometer */
#ifdef CHARBUG
nc_get_iter(vsym,nciterbuffersize,&iter);
#else
nc_get_iter(vsym,NC_MAX_UINT,&iter); /* effectively infinite */
#endif
odom = newodometer(dimset,NULL,NULL);
for(;;) {/* iterate in nelem chunks */
/* get nelems count and modify odometer */
@ -199,15 +212,24 @@ generate_arrayr(Symbol* vsym,
Dimset* dimset = &vsym->typ.dimset;
int rank = dimset->ndims;
int lastunlimited;
int typecode = basetype->typ.typecode;
lastunlimited = findlastunlimited(dimset);
if(lastunlimited == rank) lastunlimited = 0;
ASSERT(rank > 0);
ASSERT(dimindex >= 0 && dimindex < rank);
ASSERT(basetype->typ.typecode != NC_CHAR);
#ifdef CHARBUG
ASSERT(typecode != NC_CHAR);
#else /*!CHARBUG*/
if(dimindex == lastunlimited && typecode == NC_CHAR) {
Bytebuffer* charbuf = bbNew();
gen_leafchararray(dimset,dimindex,list,charbuf,filler);
generator->charconstant(generator,code,charbuf);
bbFree(charbuf);
} else
#endif /*!CHARBUG*/
if(dimindex == lastunlimited) {
int uid,i;
Odometer* slabodom;
@ -255,7 +277,10 @@ generate_arrayr(Symbol* vsym,
if(nofill_flag && con == NULL)
break;
#endif
if(!islistconst(con))
if(con == NULL || con->nctype == NC_FILL) {
generate_arrayr(vsym,code,filler,odom,nextunlimited,NULL,generator);
} else if(!islistconst(con))
semwarn(constline(con),"Expected {...} representing unlimited list");
else {
Datalist* sublist = con->value.compoundv;

View File

@ -7,7 +7,7 @@
#include "includes.h"
#include <ctype.h> /* for isprint() */
int derror_count;
int error_count;
#ifndef NO_STDARG
#define vastart(argv,fmt) va_start(argv,fmt)
@ -31,7 +31,7 @@ vderror(fmt,va_alist) const char* fmt; va_dcl
(void) vfprintf(stderr,fmt,argv) ;
(void) fputc('\n',stderr) ;
(void) fflush(stderr); /* to ensure log files are current */
derror_count++;
error_count++;
}
#ifndef NO_STDARG
@ -90,7 +90,7 @@ semerror(lno,fmt,va_alist) const int lno; const char* fmt; va_dcl
vastart(argv,fmt);
(void)fprintf(stderr,"%s: %s line %d: ", progname, cdlname, lno);
vderror(fmt,argv);
exit(1);
exit(1); /* immediately fatal */
}
/* Capture potential version errors */

View File

@ -8,7 +8,7 @@
#ifndef GENERR_H
#define GENERR_H
extern int derror_count;
extern int error_count;
#ifndef NO_STDARG
#define vastart(argv,fmt) va_start(argv,fmt)

View File

@ -49,4 +49,7 @@
extern int specialconstants;
#undef ITERBUG
#undef CHARBUG
#endif /* NCGEN_INCLUDES_H */

View File

@ -279,7 +279,8 @@ main(
if(languages == 0) {
binary_flag = 1; /* default */
if(k_flag == 0)
/* Treat -k or -o as an implicit -lb assuming no other -l flags */
if(k_flag == 0 && netcdf_name == NULL)
syntax_only = 1;
}
@ -344,7 +345,8 @@ main(
parse_init();
ncgin = fp;
if(debug >= 2) {ncgdebug=1;}
if(ncgparse() != 0) return 1;
if(ncgparse() != 0)
return 1;
/* Compute the k_flag (1st pass) using rules in the man page (ncgen.1).*/
@ -374,9 +376,9 @@ main(
return 0;
}
if(specials_flag && k_flag == 0)
if(specials_flag > 0 && k_flag == 0)
#ifdef USE_NETCDF4
k_flag = 4;
k_flag = 3;
#else
k_flag = 1;
#endif
@ -396,7 +398,7 @@ main(
}
processsemantics();
if(!syntax_only)
if(!syntax_only && error_count == 0)
define_netcdf();
return 0;
@ -413,4 +415,5 @@ init_netcdf(void) /* initialize global counts, flags */
codebuffer = bbNew();
stmt = bbNew();
error_count = 0; /* Track # of errors */
}

View File

@ -60,10 +60,12 @@ matching the netCDF specification.
The source code is written to
standard output; equivalent to -lf77.
.IP "\fB-o\fP \fRnetcdf_file\fP"
Name for the binary netCDF file created. If this option is specified, it implies
the "\fB-b\fP" option. (This option is necessary because netCDF files
Name of the file to pass to calls to "nc_create()".
If this option is specified it implies
(in the absense of any explicit -l flag) the "\fB-b\fP" option.
This option is necessary because netCDF files
cannot be written directly to standard output, since standard output is not
seekable.)
seekable.
.IP "\fB-k \fRfile_format\fP"
The -k flag specifies the format of the file to be created and, by inference,
the data model accepted by ncgen (i.e. netcdf-3 (classic) versus
@ -106,7 +108,7 @@ The choice of output format is determined by three flags.
.IP "\fB_Format attribute (see below).\fP"
.IP "\fBOccurrence of netcdf-4 constructs in the input CDL.\fP"
The term "netCDF-4 constructs" means
construct from the enhanced data model,
constructs from the enhanced data model,
not just special performance-related attributes such as
_ChunkSizes, _DeflateLevel, _Endianness, etc.
.LP
@ -157,7 +159,7 @@ netCDF function invocations necessary to create an equivalent binary netCDF
file named `\fBx.nc\fP':
.RS
.HP
ncgen -c -o x.nc foo.cdl
ncgen -lc foo.cdl >x.c
.RE
.LP
.SH USAGE
@ -797,6 +799,36 @@ and the shorter will be padded to produce this.
.in +5
datalist: var={"1","t","w","o","\\0"}, {"t","h","r","e","e"};
.in -5
.LP
Consider an even more complicated case.
.in +5
.nf
variables: char var(u,u2,u3);
datalist: var={{"1", "two"}}, {{"three"},{"four","xy"}};
.fi
.in -5
In this case u again will have the effective length of two.
The u2 dimensions will have a size = max(1,2) = 2;
Within each instance of u2, the rules above will apply, leading to this.
.in +5
.nf
datalist: var={{"1","t","w","o"}}, {{"t","h","r","e","e"},{"f","o","u","r","x","y"}};
.fi
.in -5
The effective size of u3 will be the max of the two instance lengths
(six in this case) and the shorter ones will be padded to produce this.
.in +5
.nf
datalist: var={{"1","t","w","o","\0","\0"}}, {{"t","h","r","e","e","\0"},{"f","o","u","r","x","y"}};
.fi
.in -5
Note however that the first instance of u2 is less than the max length
of u2, so we need to add a filler for another instance of u2, producing this.
.in +5
.nf
datalist: var={{"1","t","w","o","\0","\0"},{"\0","\0","\0","\0","\0","\0"}}, {{"t","h","r","e","e","\0"},{"f","o","u","r","x","y"}};
.fi
.in -5
.SH BUGS
.LP

View File

@ -207,7 +207,7 @@ Constant constant;
ncdesc: NETCDF
DATASETID
rootgroup
{if (derror_count > 0) exit(6);}
{if (error_count > 0) YYABORT;}
;
rootgroup: '{'
@ -901,7 +901,6 @@ void
parse_init(void)
{
int i;
derror_count=0;
opaqueid = 0;
arrayuid = 0;
symlist = NULL;
@ -1176,7 +1175,8 @@ makespecial(int tag, Symbol* vsym, Symbol* tsym, void* data, int isconst)
char* sdata = NULL;
int idata = -1;
specials_flag = 1;
specials_flag += (tag == _FILLVALUE_FLAG ? 0 : 1);
if(isconst) {
con = (Constant*)data;

View File

@ -1800,7 +1800,7 @@ yyreduce:
/* Line 1806 of yacc.c */
#line 210 "ncgen.y"
{if (derror_count > 0) exit(6);}
{if (error_count > 0) YYABORT;}
break;
case 7:
@ -3209,7 +3209,6 @@ void
parse_init(void)
{
int i;
derror_count=0;
opaqueid = 0;
arrayuid = 0;
symlist = NULL;
@ -3484,7 +3483,8 @@ makespecial(int tag, Symbol* vsym, Symbol* tsym, void* data, int isconst)
char* sdata = NULL;
int idata = -1;
specials_flag = 1;
specials_flag += (tag == _FILLVALUE_FLAG ? 0 : 1);
if(isconst) {
con = (Constant*)data;

View File

@ -856,23 +856,26 @@ computeunlimitedsizes(Dimset* dimset, int dimindex, Datalist* data, int ischar)
xproduct = crossproduct(dimset,dimindex+1,nextunlim);
if(!lastunlim) {
/*!lastunlim => data is list of sublists, recurse on each sublist*/
for(i=0;i<data->length;i++) {
Constant* con = data->data+i;
ASSERT(con->nctype == NC_COMPOUND);
computeunlimitedsizes(dimset,nextunlim,con->value.compoundv,ischar);
}
/* Compute candiate size of this unlimited */
length = data->length;
unlimsize = length / xproduct;
if(length % xproduct != 0)
unlimsize++; /* => fill requires at some point */
#ifdef DEBUG2
fprintf(stderr,"unlimsize: dim=%s declsize=%d xproduct=%d newsize=%d\n",
thisunlim->name,thisunlim->dim.declsize,xproduct,unlimsize);
fprintf(stderr,"unlimsize: dim=%s declsize=%lu xproduct=%lu newsize=%lu\n",
thisunlim->name,
(unsigned long)thisunlim->dim.declsize,
(unsigned long)xproduct,
(unsigned long)unlimsize);
#endif
if(thisunlim->dim.declsize < unlimsize) /* want max length of the unlimited*/
thisunlim->dim.declsize = unlimsize;
/*!lastunlim => data is list of sublists, recurse on each sublist*/
for(i=0;i<data->length;i++) {
Constant* con = data->data+i;
ASSERT(con->nctype == NC_COMPOUND);
computeunlimitedsizes(dimset,nextunlim,con->value.compoundv,ischar);
}
} else {//lastunlim
if(ischar) {
/* Char case requires special computations;
@ -887,8 +890,11 @@ thisunlim->name,thisunlim->dim.declsize,xproduct,unlimsize);
case NC_STRING:
length += con->value.stringv.len;
break;
case NC_COMPOUND:
semwarn(datalistline(data),"Expected character constant, found {...}");
break;
default:
semwarn(datalistline(data),"Illegal character constant");
semwarn(datalistline(data),"Illegal character constant: %d",con->nctype);
}
}
} else { /* Data list should be a list of simple non-char constants */
@ -898,8 +904,11 @@ thisunlim->name,thisunlim->dim.declsize,xproduct,unlimsize);
if(length % xproduct != 0)
unlimsize++; /* => fill requires at some point */
#ifdef DEBUG2
fprintf(stderr,"unlimsize: dim=%s declsize=%d xproduct=%d newsize=%d\n",
thisunlim->name,thisunlim->dim.declsize,xproduct,unlimsize);
fprintf(stderr,"unlimsize: dim=%s declsize=%lu xproduct=%lu newsize=%lu\n",
thisunlim->name,
(unsigned long)thisunlim->dim.declsize,
(unsigned long)xproduct,
(unsigned long)unlimsize);
#endif
if(thisunlim->dim.declsize < unlimsize) /* want max length of the unlimited*/
thisunlim->dim.declsize = unlimsize;

View File

@ -25,6 +25,7 @@ ocset_curl_flags(OCstate* state)
CURLcode cstat = CURLE_OK;
CURL* curl = state->curl;
struct OCcurlflags* flags = &state->curlflags;
#ifdef CURLOPT_ENCODING
if (flags->compress) {
cstat = curl_easy_setopt(curl, CURLOPT_ENCODING,"deflate, gzip");
@ -65,6 +66,8 @@ ocset_curl_flags(OCstate* state)
cstat = curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 10L);
OCDBG1(1,"CURLOPT_FOLLOWLOCATION=%ld",1L);
cstat = curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, state->error.curlerrorbuf);
OCDBG1(1,"CURLOPT_ERRORBUFFER",0);
return OC_NOERR;
fail:

View File

@ -226,7 +226,7 @@ int
occurlopen(CURL** curlp)
{
int stat = OC_NOERR;
CURLcode cstat;
CURLcode cstat = CURLE_OK;
CURL* curl;
/* initialize curl*/
curl = curl_easy_init();

View File

@ -8,7 +8,7 @@
#if 0
#define OCDEBUG
#define DAPDEBUG 3
#define DAPDEBUG 1
#endif
#ifdef OCDEBUG

View File

@ -75,6 +75,7 @@ typedef struct OCstate
char* code;
char* message;
long httpcode;
char curlerrorbuf[CURL_ERROR_SIZE]; /* to get curl error message */
} error;
/* Store .rc file info */
struct OCcurlflags {

View File

@ -28,7 +28,7 @@ static int readfiletofile(char* path, char* suffix, FILE* stream, unsigned long*
int
readDDS(OCstate* state, OCtree* tree)
{
int stat;
int stat = OC_NOERR;
long lastmodified = -1;
@ -71,7 +71,7 @@ char* ocdxdextension[] ={
static int
readpacket(CURL* curl,OCURI* url,OCbytes* packet,OCdxd dxd,long* lastmodified)
{
int stat;
int stat = OC_NOERR;
int fileprotocol = 0;
char* suffix = ocdxdextension[dxd];
char* fetchurl = NULL;
@ -102,7 +102,7 @@ readpacket(CURL* curl,OCURI* url,OCbytes* packet,OCdxd dxd,long* lastmodified)
int
readDATADDS(OCstate* state, OCtree* tree, OCflags flags)
{
int stat;
int stat = OC_NOERR;
long lastmod = -1;
if((flags & OCINMEMORY) != 0) {
@ -145,7 +145,7 @@ readDATADDS(OCstate* state, OCtree* tree, OCflags flags)
static int
readfiletofile(char* path, char* suffix, FILE* stream, unsigned long* sizep)
{
int stat;
int stat = OC_NOERR;
OCbytes* packet = ocbytesnew();
size_t len;
/* check for leading file:/// */
@ -168,7 +168,7 @@ unwind:
static int
readfile(char* path, char* suffix, OCbytes* packet)
{
int stat;
int stat = OC_NOERR;
char buf[1024];
char filename[1024];
int count,size,fd;