mirror of
https://github.com/Unidata/netcdf-c.git
synced 2025-01-18 15:55:12 +08:00
- 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:
parent
b77a5faa83
commit
99eef24bc2
@ -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)
|
||||
|
||||
|
@ -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
14
cf
@ -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"
|
||||
|
40
configure.ac
40
configure.ac
@ -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()
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
14
libdap2/env
14
libdap2/env
@ -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
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
101
libsrc/nc.c
101
libsrc/nc.c
@ -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
220
libsrc/ncFile.c
Normal 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
66
libsrc/ncstdio.c
Normal 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
60
libsrc/ncstdio.h
Normal 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_* /
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
1630
ncdap_test/test_partvar.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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"}} ;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -1,3 +1,5 @@
|
||||
# test: ../ncdump/cdl4/ref_const_test.cdl
|
||||
# test: ../ncdump/cdl4/ref_tst_chardata.cdl
|
||||
K="-k3"
|
||||
F="t"
|
||||
#B="-B12"
|
||||
|
@ -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*/
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -49,4 +49,7 @@
|
||||
|
||||
extern int specialconstants;
|
||||
|
||||
#undef ITERBUG
|
||||
#undef CHARBUG
|
||||
|
||||
#endif /* NCGEN_INCLUDES_H */
|
||||
|
13
ncgen/main.c
13
ncgen/main.c
@ -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 */
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#if 0
|
||||
#define OCDEBUG
|
||||
#define DAPDEBUG 3
|
||||
#define DAPDEBUG 1
|
||||
#endif
|
||||
|
||||
#ifdef OCDEBUG
|
||||
|
@ -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 {
|
||||
|
10
oc/read.c
10
oc/read.c
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user