Add -g option to ncdump and test it

This commit is contained in:
Russ Rew 2011-09-21 23:10:03 +00:00
parent 1e02fd4f1d
commit 97c954a859
15 changed files with 342 additions and 150 deletions

View File

@ -3439,7 +3439,7 @@ This example is from test program libsrc4/tst_grps.c.
@section Find a Group by its Fully-qualified Name: nc_inq_grp_full_ncid
@findex nc_inq_grp_parent
Given a fully qualified group name an an ncid, find the ncid of the
Given a fully qualified group name and an ncid, find the ncid of the
group id.
@heading Usage

View File

@ -2741,7 +2741,7 @@ C Check the parent ncid.
@section Find a Group by Name: NF_INQ_GRP_NCID
@findex NF_INQ_GRP_PARENT
Given a group name an an ncid, find the ncid of the group id.
Given a group name and an ncid, find the ncid of the group id.
@heading Usage
@ -2807,7 +2807,7 @@ C Go to a child group and find the id of our type.
@section Find a Group by its Fully-qualified Name: NF_INQ_GRP_FULL_NCID
@findex NF_INQ_GRP_PARENT
Given a fully qualified group name an an ncid, find the ncid of the
Given a fully qualified group name and an ncid, find the ncid of the
group id.
@heading Usage

View File

@ -2248,7 +2248,7 @@ An error was reported by the HDF5 layer.
@section Find a Group by Name: NF90_INQ_GRP_NCID
@findex NF90_INQ_GRP_PARENT
Given a group name an an ncid, find the ncid of the group id.
Given a group name and an ncid, find the ncid of the group id.
@heading Usage
@ -2323,7 +2323,7 @@ This example is from test program nf_test/f90tst_grps.f90.
@section Find a Group by its Fully-qualified Name: NF90_INQ_GRP_FULL_NCID
@findex NF90_INQ_GRP_PARENT
Given a fully qualified group name an an ncid, find the ncid of the
Given a fully qualified group name and an ncid, find the ncid of the
group id.
@heading Usage

View File

@ -40,7 +40,8 @@ tst_chunking
TESTS += tst_create_files tst_group_data tst_enum_data tst_opaque_data \
tst_string_data tst_vlen_data tst_comp tst_comp2 tst_nans \
tst_special_atts tst_netcdf4.sh tst_h_rdc0 tst_unicode tst_fillbug \
tst_fillbug.sh tst_netcdf4_4.sh tst_compress tst_nccopy4.sh
tst_fillbug.sh tst_netcdf4_4.sh tst_compress tst_nccopy4.sh \
tst_grp_spec.sh
if EXTRA_TESTS
TESTS += run_back_comp_tests.sh
@ -65,7 +66,7 @@ tst_string_data.cdl tst_fillbug.cdl tst_opaque_data.cdl \
tst_compounds4.cdl tst_utf8.cdl tst_compounds3.cdl \
tst_special_atts.cdl tst_nans.cdl tst_format_att_64.cdl \
tst_vlen_data.cdl tst_solar_1.cdl tst_format_att.cdl tst_inflated.nc \
tst_inflated4.nc tst_deflated.nc tst_chunking.nc tmp*.nc
tmp_subset.cdl tst_inflated4.nc tst_deflated.nc tst_chunking.nc tmp*.nc
# These files all have to be included with the distribution.
EXTRA_DIST = run_tests.sh tst_64bit.sh tst_output.sh test0.cdl \
@ -82,7 +83,8 @@ ref_tst_compounds3.nc ref_tst_compounds3.cdl ref_tst_compounds4.nc \
ref_tst_compounds4.cdl ref_tst_group_data_v23.cdl tst_mslp.cdl \
ref_tst_format_att.cdl ref_tst_format_att_64.cdl tst_nccopy3.sh \
tst_nccopy4.sh ref_nc_test_netcdf4_4_0.nc run_back_comp_tests.sh \
ref_nc_test_netcdf4.cdl ref_tst_special_atts3.cdl tst_brecs.cdl
ref_nc_test_netcdf4.cdl ref_tst_special_atts3.cdl tst_brecs.cdl \
ref_tst_grp_spec0.cdl ref_tst_grp_spec.cdl tst_grp_spec.sh
# Can't run ncgen to generate ctest.c and ctest64.c on cross-compiles.
BUILT_SOURCES = ctest.c ctest64.c

View File

@ -22,8 +22,8 @@
#include <netcdf.h>
#include "utils.h"
#include "nccomps.h"
#include "ncdump.h"
#include "dumplib.h"
#include "ncdump.h"
#include "isnan.h"
#include "nctime0.h"
@ -103,7 +103,7 @@ init_epsilons(void)
static char* has_c_format_att(int ncid, int varid);
static vnode_t* newvnode(void);
static idnode_t* newidnode(void);
int float_precision_specified = 0; /* -p option specified float precision */
int double_precision_specified = 0; /* -p option specified double precision */
@ -419,10 +419,10 @@ get_fmt(
return get_default_fmt(typeid);
}
static vnode_t*
newvnode(void)
static idnode_t*
newidnode(void)
{
vnode_t *newvp = (vnode_t*) emalloc(sizeof(vnode_t));
idnode_t *newvp = (idnode_t*) emalloc(sizeof(idnode_t));
return newvp;
}
@ -430,10 +430,10 @@ newvnode(void)
/*
* Get a new, empty variable list.
*/
vnode_t*
newvlist(void)
idnode_t*
newidlist(void)
{
vnode_t *vp = newvnode();
idnode_t *vp = newidnode();
vp -> next = 0;
vp -> id = -1; /* bad id */
@ -443,9 +443,9 @@ newvlist(void)
void
varadd(vnode_t* vlist, int varid)
idadd(idnode_t* vlist, int varid)
{
vnode_t *newvp = newvnode();
idnode_t *newvp = newidnode();
newvp -> next = vlist -> next;
newvp -> id = varid;
@ -454,20 +454,34 @@ varadd(vnode_t* vlist, int varid)
/*
* return 1 if variable identified by varid is member of variable
* list vlist points to.
* return true if id is member of list that vlist points to.
*/
int
varmember(const vnode_t* vlist, int varid)
boolean
idmember(const idnode_t* idlist, int id)
{
vnode_t *vp = vlist -> next;
idnode_t *vp = idlist -> next;
for (; vp ; vp = vp->next)
if (vp->id == varid)
return 1;
return 0;
if (vp->id == id)
return true;
return false;
}
/*
* return true if group identified by grpid is member of group
* list specified on command line by -g.
*/
boolean
group_wanted(int grpid)
{
int igrp;
/* If -g not specified, all groups are wanted */
if(formatting_specs.nlgrps == 0)
return true;
/* if -g specified, look for match in group id list */
return idmember(formatting_specs.grpids, grpid);
}
/* Return primitive type name */
static const char *
@ -1495,9 +1509,6 @@ nc_inq_gvarid(int grpid, const char *varname, int *varidp) {
*/
#ifdef USE_NETCDF4
#ifdef UNUSED
const char *vp = varname;
#endif
char *vargroup;
char *relname;
char *groupname;
@ -1723,9 +1734,6 @@ init_types(int ncid) {
* recursively on each of them. */
{
int g, numgrps, *ncids;
#ifdef UNUSED
int format;
#endif
/* See how many groups there are. */
NC_CHECK( nc_inq_grps(ncid, &numgrps, NULL) );

View File

@ -3,6 +3,8 @@
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
* $Header: /upc/share/CVS/netcdf-3/ncdump/dumplib.h,v 1.28 2009/08/13 21:06:13 russ Exp $
*********************************************************************/
#ifndef _DUMPLIB_H_
#define _DUMPLIB_H_
#include "config.h"
@ -53,22 +55,25 @@ extern void set_formats ( int flt_digs, int dbl_digs );
/* Determine print format to use for each value for this variable. */
const char * get_fmt ( int ncid, int varid, nc_type typeid );
/* structure for list of variables specified with -v option */
struct vnode
/* structure for list of ids, such as varids or grpids specified with -v or -g option */
struct idnode
{
struct vnode* next;
struct idnode* next;
int id;
};
typedef struct vnode vnode_t;
typedef struct idnode idnode_t;
/* Get new variable list */
extern vnode_t* newvlist ( void );
/* Get new id list */
extern idnode_t* newidlist ( void );
/* Add a variable id to variable list */
extern void varadd ( vnode_t* vlist, int varid );
/* Add an id to id list */
extern void idadd ( idnode_t* idlist, int id );
/* Test if a variable id is in variable list */
extern int varmember ( const vnode_t* vlist, int varid );
extern boolean idmember ( const idnode_t* idlist, int id );
/* Test if a group id is in group list */
extern boolean group_wanted ( int grpid );
/* Add type info to type list */
extern void typeadd ( nctype_t *typep );
@ -77,7 +82,7 @@ extern void typeadd ( nctype_t *typep );
extern nctype_t *get_typeinfo ( int typeid );
/* From type id, get type name */
extern void get_type_name(int ncid, nc_type type, char *name);
extern void get_type_name(int ncid, nc_type type, char *name);
/* set tostring member function */
extern void set_tostring_func ( ncvar_t *varp);
@ -143,3 +148,5 @@ int nctime_val_tostring(const ncvar_t *varp, safebuf_t *sfbf, const void *valp);
#ifdef __cplusplus
}
#endif
#endif /*_DUMPLIB_H_ */

View File

@ -23,8 +23,8 @@ Research/Unidata. See \ref copyright file for more info. */
#include "utils.h"
#include "nccomps.h"
#include "nctime0.h" /* new iso time and calendar stuff */
#include "ncdump.h"
#include "dumplib.h"
#include "ncdump.h"
#include "vardata.h"
#include "indent.h"
#include "isnan.h"
@ -46,9 +46,13 @@ fspec_t formatting_specs = /* defaults, overridden by command-line options */
false, /* use 'T' separator between date and time values as strings? */
false, /* output special attributes, eg chunking? */
LANG_C, /* language conventions for indices */
0, /* if -v specified, number of variables */
false, /* for DAP URLs, client-side cache used */
0 /* if -v specified, list of variable names */
0, /* if -v specified, number of variables in list */
0, /* if -v specified, list of variable names */
0, /* if -g specified, number of groups names in list */
0, /* if -g specified, list of group names */
0, /* if -g specified, list of matching grpids */
0 /* kind of netCDF file */
};
static void
@ -68,11 +72,12 @@ usage(void)
[-s] Output special (virtual) attributes\n\
[-t] Output time data as date-time strings\n\
[-i] Output time data as date-time strings with ISO-8601 'T' separator\n\
[-g grp1[,...]] Data and metadata for group(s) <grp1>,... only\
[-w] Without client-side caching of variables for DAP URLs\n\
file Name of netCDF file\n"
(void) fprintf(stderr,
"%s [-c|-h] [-v ...] [[-b|-f] [c|f]] [-l len] [-n name] [-p n[,n]] [-k] [-x] [-s] [-t|-i] [-w] file\n%s",
"%s [-c|-h] [-v ...] [[-b|-f] [c|f]] [-l len] [-n name] [-p n[,n]] [-k] [-x] [-s] [-t|-i] [-g ...] [-w] file\n%s",
progname,
USAGE);
@ -222,21 +227,6 @@ kind_string(int kind)
}
}
/*
* Emit kind of netCDF file
*/
static void
do_nckind(int ncid, const char *path)
{
int nc_kind;
/*nc_set_log_level(3);*/
NC_CHECK( nc_inq_format(ncid, &nc_kind) );
printf ("%s\n", kind_string(nc_kind));
NC_CHECK( nc_close(ncid) );
}
/*
* Emit initial line of output for NcML
@ -1255,13 +1245,12 @@ get_fill_info(int ncid, int varid, ncvar_t *vp) {
}
/* Recursively dump the contents of a group. (Recall that only
* netcdf-4 format files can have groups. On all other formats, there
* is just a root group, so recursion will not take place.)
/* Recursively dump the contents of a group. (Only netcdf-4 format
* files can have groups, so recursion will not take place for classic
* format files.)
*
* ncid: id of open file (first call) or group (subsequent recursive calls)
* path: file path name (first call)
* specp: formatting spec
*/
static void
do_ncdump_rec(int ncid, const char *path)
@ -1277,7 +1266,7 @@ do_ncdump_rec(int ncid, const char *path)
int id; /* dimension number per variable */
int ia; /* attribute number */
int iv; /* variable number */
vnode_t* vlist = 0; /* list for vars specified with -v option */
idnode_t* vlist = 0; /* list for vars specified with -v option */
char type_name[NC_MAX_NAME + 1];
int kind; /* strings output differently for nc4 files */
char dim_name[NC_MAX_NAME + 1];
@ -1304,10 +1293,10 @@ do_ncdump_rec(int ncid, const char *path)
* "/grp1/grp2/varname" if they are in groups.
*/
if (formatting_specs.nlvars > 0) {
vlist = newvlist(); /* list for vars specified with -v option */
vlist = newidlist(); /* list for vars specified with -v option */
for (iv=0; iv < formatting_specs.nlvars; iv++) {
if(nc_inq_gvarid(ncid, formatting_specs.lvars[iv], &varid) == NC_NOERR)
varadd(vlist, varid);
idadd(vlist, varid);
}
}
@ -1530,8 +1519,10 @@ do_ncdump_rec(int ncid, const char *path)
pr_att_global_format(ncid, kind);
}
/* output variable data */
if (! formatting_specs.header_only) {
/* output variable data, unless "-h" option specified header only
* or this group is not in list of groups specified by "-g"
* option */
if (! formatting_specs.header_only && group_wanted(ncid) ) {
if (nvars > 0) {
indent_out();
printf ("data:\n");
@ -1539,7 +1530,7 @@ do_ncdump_rec(int ncid, const char *path)
for (varid = 0; varid < nvars; varid++) {
int no_data;
/* if var list specified, test for membership */
if (formatting_specs.nlvars > 0 && ! varmember(vlist, varid))
if (formatting_specs.nlvars > 0 && ! idmember(vlist, varid))
continue;
NC_CHECK( nc_inq_varndims(ncid, varid, &var.ndims) );
if(var.dims != NULL) free(var.dims);
@ -1587,8 +1578,6 @@ do_ncdump_rec(int ncid, const char *path)
set_tostring_func(&var);
if (vardata(&var, vdims, ncid, varid) == -1) {
error("can't output data for variable %s", var.name);
NC_CHECK(
nc_close(ncid) );
goto done;
}
}
@ -1666,7 +1655,6 @@ do_ncdump(int ncid, const char *path)
do_ncdump_rec(ncid, path);
indent_out();
printf ("}\n");
NC_CHECK( nc_close(ncid) );
}
@ -1683,17 +1671,17 @@ do_ncdumpx(int ncid, const char *path)
ncvar_t var; /* variable */
int ia; /* attribute number */
int iv; /* variable number */
vnode_t* vlist = 0; /* list for vars specified with -v option */
idnode_t* vlist = 0; /* list for vars specified with -v option */
/*
* If any vars were specified with -v option, get list of associated
* variable ids
*/
if (formatting_specs.nlvars > 0) {
vlist = newvlist(); /* list for vars specified with -v option */
vlist = newidlist(); /* list for vars specified with -v option */
for (iv=0; iv < formatting_specs.nlvars; iv++) {
NC_CHECK( nc_inq_varid(ncid, formatting_specs.lvars[iv], &varid) );
varadd(vlist, varid);
idadd(vlist, varid);
}
}
@ -1742,7 +1730,7 @@ do_ncdumpx(int ncid, const char *path)
/* header-only specified */
(formatting_specs.header_only) ||
/* list of variables specified and this variable not in list */
(formatting_specs.nlvars > 0 && !varmember(vlist, varid)) ||
(formatting_specs.nlvars > 0 && !idmember(vlist, varid)) ||
/* coordinate vars only and this is not a coordinate variable */
(formatting_specs.coord_vals && !iscoordvar(ncid, varid)) ||
/* this is a record variable, but no records have been written */
@ -1764,8 +1752,6 @@ do_ncdumpx(int ncid, const char *path)
}
printf ("</netcdf>\n");
NC_CHECK(
nc_close(ncid) );
if (vlist)
free(vlist);
if(dims)
@ -1784,24 +1770,16 @@ make_lvars(char *optarg)
while (*cp++)
if (*cp == ',')
nvars++;
formatting_specs.nlvars = nvars;
formatting_specs.lvars = (char **) emalloc(nvars * sizeof(char*));
cpp = formatting_specs.lvars;
/* copy variable names into list */
for (cp = strtok(optarg, ",");
cp != NULL;
cp = strtok((char *) NULL, ",")) {
size_t bufsiz = strlen(cp) + 1;
*cpp = (char *) emalloc(bufsiz);
strncpy(*cpp, cp, bufsiz);
for (cp = strtok(optarg, ","); cp != NULL; cp = strtok((char *) NULL, ",")) {
*cpp = strdup(cp);
cpp++;
}
formatting_specs.nlvars = nvars;
}
static void
make_lgrps(char *optarg)
{
@ -1809,26 +1787,20 @@ make_lgrps(char *optarg)
int ngrps = 1;
char ** cpp;
/* compute number of variable names in comma-delimited list */
formatting_specs.nlgrps = 1;
/* compute number of group names in comma-delimited list */
while (*cp++)
if (*cp == ',')
ngrps++;
formatting_specs.nlgrps = ngrps;
formatting_specs.lgrps = (char **) emalloc(ngrps * sizeof(char*));
cpp = formatting_specs.lgrps;
/* copy variable names into list */
for (cp = strtok(optarg, ",");
cp != NULL;
cp = strtok((char *) NULL, ",")) {
size_t bufsiz = strlen(cp) + 1;
*cpp = (char *) emalloc(bufsiz);
strncpy(*cpp, cp, bufsiz);
/* copy group names into list */
for (cp = strtok(optarg, ","); cp != NULL; cp = strtok((char *) NULL, ",")) {
*cpp = strdup(cp);
cpp++;
}
formatting_specs.nlgrps = ngrps;
/* make empty list of grpids, to be filled in after input file opened */
formatting_specs.grpids = newidlist();
}
@ -1966,63 +1938,90 @@ missing_vars(int ncid) {
return 0;
}
/* Determine whether a group named grpname exists in any group in an
* open netCDF file with id ncid. If so, return the count of how many
* matching groups were found, else return a count of 0. */
size_t
nc_inq_grpname_count(int ncid, char *grpname) {
/*
count = 0;
status = nc_inq_ncid(ncid, grpname, &grpid);
if (status == NC_NOERR)
count++;
for each subgroup gid {
count += nc_inq_grpname_count(gid, grpname);
}
return count;
*/
/* Determine whether a group named formatting_specs.lgrps[igrp] exists
* in a netCDF file or group with id ncid. If so, return the count of
* how many matching groups were found, else return a count of 0. If
* the name begins with "/", it is interpreted as an absolute group
* name, in which case only 0 or 1 is returned. Otherwise, interpret
* it as a relative name, and the total number of occurrences within
* the file/group identified by ncid is returned.
*
* Also has side effect of updating the ngrpids and the associate
* grpids array that represent the group list specified by the -g
* option. TODO: put this in its own function instead.
*/
static size_t
nc_inq_grpname_count(int ncid, int igrp) {
size_t count = 0;
#ifdef USE_NETCDF4
int numgrps;
int *ncids;
int g;
int grpid;
int status;
char *grpname=formatting_specs.lgrps[igrp];
/* permit empty string to also designate root group */
if(grpname[0] == '\0' || STREQ(grpname,"/")) {
count = 1;
idadd(formatting_specs.grpids, ncid);
return count;
}
#ifdef USE_NETCDF4
/* Handle absolute group names */
if(grpname[0] == '/') {
int grpid;
status = nc_inq_grp_full_ncid(ncid, grpname, &grpid);
if(status == NC_NOERR) {
count = 1;
idadd(formatting_specs.grpids, grpid);
} else if(status == NC_ENOGRP) {
count = 0;
} else {
error("when looking up group %s: %s ", grpname, nc_strerror(status));
}
return count;
}
/* look in this group */
int status = nc_inq_ncid(ncid, grpname, &grpid);
if (status == NC_NOERR)
status = nc_inq_grp_ncid(ncid, grpname, &grpid);
if (status == NC_NOERR) {
count++;
idadd(formatting_specs.grpids, grpid);
}
/* if this group has subgroups, call recursively on each of them */
NC_CHECK( nc_inq_grps(ncid, &numgrps, NULL) );
/* Allocate memory to hold the list of group ids. */
ncids = emalloc((numgrps + 1) * sizeof(int));
/* Get the list of group ids. */
NC_CHECK( nc_inq_grps(ncid, NULL, ncids) );
/* Call this function for each group. */
for (g = 0; g < numgrps; g++) {
count += nc_inq_grpname_count(ncids[g], grpname);
if(numgrps > 0) {
/* Allocate memory to hold the list of group ids. */
ncids = emalloc(numgrps * sizeof(int));
/* Get the list of group ids. */
NC_CHECK( nc_inq_grps(ncid, NULL, ncids) );
/* Call this function recursively for each group. */
for (g = 0; g < numgrps; g++) {
count += nc_inq_grpname_count(ncids[g], igrp);
}
free(ncids);
}
free(ncids);
#endif /* USE_NETCDF4 */
return count;
}
/* Check if any group names specified with "-g grp1,...,grpn" are
* missing. Returns 0 if no missing groups detected, otherwise
* exits. */
* missing. Returns total number of matching groups if no missing
* groups detected, otherwise exits. */
static int
missing_grps(int ncid) {
grp_matches(int ncid) {
int ig;
size_t total = 0;
for (ig=0; ig < formatting_specs.nlgrps; ig++) {
if(nc_inq_grpname_count(ncid, formatting_specs.lgrps[ig]) == 0) {
size_t count = nc_inq_grpname_count(ncid, ig);
if(count == 0) {
error("%s: No such group", formatting_specs.lgrps[ig]);
return 0;
}
total += count;
}
return 0;
return total;
}
#define DAP_CLIENT_CACHE_DIRECTIVE "[cache]"
@ -2266,7 +2265,7 @@ main(int argc, char *argv[])
#endif
}
while ((c = getopt(argc, argv, "b:cd:f:hijkl:n:p:stv:xw")) != EOF)
while ((c = getopt(argc, argv, "b:cd:f:g:hijkl:n:p:stv:xw")) != EOF)
switch(c) {
case 'h': /* dump header only, no data */
formatting_specs.header_only = true;
@ -2396,23 +2395,31 @@ main(int argc, char *argv[])
if (nc_status != NC_NOERR) {
error("%s: %s", path, nc_strerror(nc_status));
}
NC_CHECK( nc_inq_format(ncid, &formatting_specs.nc_kind) );
if (kind_out) {
do_nckind(ncid, path);
printf ("%s\n", kind_string(formatting_specs.nc_kind));
} else {
/* Initialize list of types. */
init_types(ncid);
/* Check if any vars in -v don't exist */
if(missing_vars(ncid))
return EXIT_FAILURE;
/* Check if any grps in -g don't exist */
if(missing_grps(ncid))
return EXIT_FAILURE;
if(formatting_specs.nlgrps > 0) {
if(formatting_specs.nc_kind != NC_FORMAT_NETCDF4) {
error("Group list (-g ...) only permitted for netCDF-4 file");
return EXIT_FAILURE;
}
/* Check if any grps in -g don't exist */
if(grp_matches(ncid) == 0)
return EXIT_FAILURE;
}
if (xml_out) {
do_ncdumpx(ncid, path);
} else {
do_ncdump(ncid, path);
}
}
NC_CHECK( nc_close(ncid) );
}
free(path);
}

View File

@ -50,12 +50,12 @@ typedef struct { /* specification for how to format dump */
* column major) or LANG_F (Fortran,
* 1-based, row major) */
int nlvars; /* Number of variables specified with -v
* option on command line */
boolean with_cache; /* For DAP URLs, get data with client-side
* caching when each variable is first accessed */
int nlvars; /* Number of variables specified with -v
* option on command line */
char** lvars; /* list of variable names specified with -v
* option on command line */
@ -64,6 +64,13 @@ typedef struct { /* specification for how to format dump */
char** lgrps; /* list of group names specified with -g
* option on command line */
idnode_t* grpids; /* list of grpids matching list specified with -g option */
int nc_kind; /* kind of netCDF file named on
* command line, 1 (classic), 2
* (64-bit offset), 3 (netCDF-4), 4
* (netCDF-4 classic model) */
} fspec_t;
#endif /*_NCDUMP_H_ */

View File

@ -8,6 +8,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netcdf.h>
#include "utils.h"
#include "nciter.h"

View File

@ -23,11 +23,11 @@
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include <netcdf.h>
#include "utils.h"
#include "nccomps.h"
#include "dumplib.h" /* for sbuf_... prototypes */
#include "ncdump.h" /* for fspec_t def */
#include "vardata.h"
#include "nctime0.h"

View File

@ -0,0 +1,64 @@
netcdf tmp_subset {
dimensions:
dim = UNLIMITED ; // (1 currently)
variables:
float var(dim) ;
group: g1 {
dimensions:
dim = 1 ;
variables:
float var(dim) ;
data:
var = 1 ;
group: g2 {
dimensions:
dim = 2 ;
variables:
float var(dim) ;
} // group g2
group: g3 {
dimensions:
dim = 3 ;
variables:
float var(dim) ;
} // group g3
} // group g1
group: g4 {
dimensions:
dim = 4 ;
variables:
float var(dim) ;
data:
var = 1, 2, 3, 4 ;
group: g5 {
dimensions:
dim = 5 ;
variables:
float var(dim) ;
group: g6 {
dimensions:
dim = 6 ;
variables:
float var(dim) ;
} // group g6
group: g1 {
dimensions:
dim = 1 ;
variables:
float var(dim) ;
data:
var = 451 ;
} // group g1
} // group g5
} // group g4
}

View File

@ -0,0 +1,79 @@
netcdf ref_tst_grp_spec0 {
dimensions:
dim = UNLIMITED ; // (1 currently)
variables:
float var(dim) ;
data:
var = 0 ;
group: g1 {
dimensions:
dim = 1 ;
variables:
float var(dim) ;
data:
var = 1 ;
group: g2 {
dimensions:
dim = 2 ;
variables:
float var(dim) ;
data:
var = 1, 2 ;
} // group g2
group: g3 {
dimensions:
dim = 3 ;
variables:
float var(dim) ;
data:
var = 1, 2, 3 ;
} // group g3
} // group g1
group: g4 {
dimensions:
dim = 4 ;
variables:
float var(dim) ;
data:
var = 1, 2, 3, 4 ;
group: g5 {
dimensions:
dim = 5 ;
variables:
float var(dim) ;
data:
var = 1, 2, 3, 4, 5 ;
group: g6 {
dimensions:
dim = 6 ;
variables:
float var(dim) ;
data:
var = 1, 2, 3, 4, 5, 6 ;
} // group g6
group: g1 {
dimensions:
dim = 1 ;
variables:
float var(dim) ;
data:
var = 451 ;
} // group g1
} // group g5
} // group g4
}

18
ncdump/tst_grp_spec.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/sh
# This shell script tests ncdump -g option for specifying groups for
# which data is to be output.
# $Id$
set -e
echo ""
echo "*** Testing ncdump -g output for specifying group subsets"
echo "*** creating netcdf file tst_grp_spec.nc from ref_tst_grp_spec0.cdl..."
../ncgen/ncgen -k3 -o tmp_all.nc -b $srcdir/ref_tst_grp_spec0.cdl
echo "*** creating tmp_subset.cdl from tmp_all.nc with ncdump -g ..."
./ncdump -g g1,g4 -n tmp_subset tmp_all.nc > tmp_subset.cdl
echo "*** comparing tmp_subset.cdl with ref_tst_grp_spec.cdl..."
diff tmp_subset.cdl $srcdir/ref_tst_grp_spec.cdl
echo
echo "*** All ncdump test output for -g option passed!"
exit 0

View File

@ -5,7 +5,6 @@
*********************************************************************/
#include "config.h"
#include <netcdf.h>
#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)

View File

@ -13,8 +13,8 @@
#include <netcdf.h>
#include "utils.h"
#include "nccomps.h"
#include "ncdump.h"
#include "dumplib.h"
#include "ncdump.h"
#include "indent.h"
#include "vardata.h"