You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
207 lines
4.8 KiB
207 lines
4.8 KiB
2 years ago
|
#ifdef HAVE_CONFIG_H
|
||
|
#include <config.h>
|
||
|
#endif
|
||
|
#include <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
#include <assert.h>
|
||
|
|
||
|
#ifdef HAVE_GETOPT_H
|
||
|
#include <getopt.h>
|
||
|
#endif
|
||
|
|
||
|
#if defined(_WIN32) && ! defined(__MINGW32__)
|
||
|
#include "XGetopt.h"
|
||
|
#endif
|
||
|
|
||
|
#include <netcdf.h>
|
||
|
|
||
|
#define CHECK(err) {if(err) report(err,__LINE__);}
|
||
|
|
||
|
/* Command line options */
|
||
|
struct Options {
|
||
|
int debug;
|
||
|
enum What {NONE=0, DIM=1, TYPE=2} what;
|
||
|
char file[4096];
|
||
|
char var[NC_MAX_NAME+1];
|
||
|
char object[NC_MAX_NAME+1];
|
||
|
} options;
|
||
|
|
||
|
/**************************************************/
|
||
|
|
||
|
|
||
|
static void
|
||
|
report(int err, int lineno)
|
||
|
{
|
||
|
fprintf(stderr,"Error: %d: %s\n", lineno, nc_strerror(err));
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
usage(void)
|
||
|
{
|
||
|
fprintf(stderr,"usage: printfqn [-D] [-V] -t|-d -v <varname> -f <filename> \n");
|
||
|
exit(0);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
get_id_parent(int ncid, int id, int* parentp, enum What what)
|
||
|
{
|
||
|
int stat = NC_NOERR;
|
||
|
int i;
|
||
|
int nids;
|
||
|
int ids[4096];
|
||
|
|
||
|
/* Does this group have the id we are searching for? */
|
||
|
if(what == TYPE) {
|
||
|
if((stat=nc_inq_typeids(ncid,&nids,ids))) goto done;
|
||
|
} else if(what == DIM) {
|
||
|
if((stat=nc_inq_dimids(ncid,&nids,ids,0))) goto done;
|
||
|
} else
|
||
|
abort();
|
||
|
assert(nids < 4096);
|
||
|
|
||
|
/* Search for this id */
|
||
|
for(i=0;i<nids;i++) {
|
||
|
if(ids[i] == id) {
|
||
|
if(parentp) *parentp = ncid;
|
||
|
goto done;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Else Search subgroups. */
|
||
|
if((stat=nc_inq_grps(ncid,&nids,ids))) goto done;
|
||
|
assert(nids < 4096);
|
||
|
|
||
|
/* Recurse on each subgroup */
|
||
|
for(i=0;i<nids;i++) {
|
||
|
switch (stat = get_id_parent(ids[i],id,parentp,what)) {
|
||
|
case NC_ENOTFOUND: break; /* not found; keep looking */
|
||
|
case NC_NOERR: goto done; /* found it */
|
||
|
default: goto done; /* some other error */
|
||
|
}
|
||
|
}
|
||
|
stat = NC_ENOTFOUND; /* Not found */
|
||
|
|
||
|
done:
|
||
|
return stat;
|
||
|
|
||
|
}
|
||
|
|
||
|
int
|
||
|
get_variable_info(int ncid, const char* name, int* gidp, int* vidp, int* tidp, int* ndimsp, int* dimids)
|
||
|
{
|
||
|
int stat = NC_NOERR;
|
||
|
int i;
|
||
|
int nids;
|
||
|
int ids[4096];
|
||
|
char varname[NC_MAX_NAME];
|
||
|
|
||
|
/* Assume only one occurrence of the variable in dataset */
|
||
|
|
||
|
/* Does this group have the variable we are searching for? */
|
||
|
if((stat=nc_inq_varids(ncid,&nids,ids))) goto done;
|
||
|
assert(nids < 4096);
|
||
|
|
||
|
/* Search for this variable name */
|
||
|
for(i=0;i<nids;i++) {
|
||
|
if((stat = nc_inq_varname(ncid,ids[i],varname))) goto done;
|
||
|
if(strcmp(name,varname)==0) {
|
||
|
if(gidp) *gidp = ncid;
|
||
|
if(vidp) *vidp = ids[i];
|
||
|
if((stat = nc_inq_vartype(ncid,ids[i],tidp))) goto done;
|
||
|
if((stat = nc_inq_varndims(ncid,ids[i],ndimsp))) goto done;
|
||
|
if((stat = nc_inq_vardimid(ncid,ids[i],dimids))) goto done;
|
||
|
goto done;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Else Search subgroups. */
|
||
|
if((stat=nc_inq_grps(ncid,&nids,ids))) goto done;
|
||
|
assert(nids < 4096);
|
||
|
|
||
|
/* Recurse on each subgroup */
|
||
|
for(i=0;i<nids;i++) {
|
||
|
switch (stat = get_variable_info(ids[i],name,gidp,vidp,tidp,ndimsp,dimids)) {
|
||
|
case NC_ENOTVAR: break; /* not found; keep looking */
|
||
|
case NC_NOERR: goto done; /* found it */
|
||
|
default: goto done; /* some other error */
|
||
|
}
|
||
|
}
|
||
|
stat = NC_ENOTVAR; /* Not found */
|
||
|
|
||
|
done:
|
||
|
return stat;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
main(int argc, char** argv)
|
||
|
{
|
||
|
int ncid, varid, gid, tid;
|
||
|
size_t fqnlen, namelen;
|
||
|
char fqn[4096];
|
||
|
char name[NC_MAX_NAME];
|
||
|
int ndims;
|
||
|
int dimids[NC_MAX_VAR_DIMS];
|
||
|
int c;
|
||
|
|
||
|
memset((void*)&options,0,sizeof(options));
|
||
|
|
||
|
while ((c = getopt(argc, argv, "DVdtv:f:")) != EOF) {
|
||
|
switch(c) {
|
||
|
case 'D':
|
||
|
options.debug = 1;
|
||
|
break;
|
||
|
case 'V':
|
||
|
usage();
|
||
|
break;
|
||
|
case 'd':
|
||
|
options.what = DIM;
|
||
|
break;
|
||
|
case 't':
|
||
|
options.what = TYPE;
|
||
|
break;
|
||
|
case 'v':
|
||
|
strcpy(options.var,optarg);
|
||
|
break;
|
||
|
case 'f':
|
||
|
strcpy(options.file,optarg);
|
||
|
break;
|
||
|
case ':':
|
||
|
fprintf(stderr,"option has no argument: %c\n",c);
|
||
|
usage();
|
||
|
case '?':
|
||
|
fprintf(stderr,"unknown option\n");
|
||
|
usage();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CHECK(nc_open(options.file,NC_NETCDF4,&ncid));
|
||
|
|
||
|
/* Locate the parent group for the variable */
|
||
|
CHECK(get_variable_info(ncid,options.var,&gid,&varid,&tid,&ndims,dimids));
|
||
|
|
||
|
if(options.what == TYPE) {
|
||
|
/* Get the simple type name from the variable */
|
||
|
CHECK(nc_inq_type(ncid,tid,name,&namelen));
|
||
|
/* Get the containing group id for the type (might not be same as ncid) */
|
||
|
CHECK(get_id_parent(ncid,tid,&gid,TYPE));
|
||
|
} else if(options.what == DIM) {
|
||
|
/* get name of dimids[0] from the variable */
|
||
|
CHECK(nc_inq_dimname(ncid,dimids[0],name));
|
||
|
/* Get the containing group id for the type */
|
||
|
CHECK(get_id_parent(ncid,dimids[0],&gid,DIM));
|
||
|
}
|
||
|
|
||
|
/* Get the FQN name for the containing group of the id */
|
||
|
CHECK(nc_inq_grpname_full(gid,&fqnlen,fqn));
|
||
|
assert(fqnlen < sizeof(fqn));
|
||
|
|
||
|
if(strcmp(fqn,"/")==0) fqn[0] = '\0';
|
||
|
|
||
|
/* report result with no newline */
|
||
|
printf("%s/%s",fqn,name);
|
||
|
|
||
|
return 0;
|
||
|
}
|