mirror of
https://github.com/Unidata/netcdf-c.git
synced 2025-01-18 15:55:12 +08:00
Corrected a potential resource leak. Coverity ID: 1302447
This commit is contained in:
parent
95cbe52b37
commit
f8e2d21663
140
ncdump/ncdump.c
140
ncdump/ncdump.c
@ -100,15 +100,15 @@ usage(void)
|
||||
"%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);
|
||||
|
||||
|
||||
(void) fprintf(stderr,
|
||||
"netcdf library version %s\n",
|
||||
nc_inq_libvers());
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* convert pathname of netcdf file into name for cdl unit, by taking
|
||||
/*
|
||||
* convert pathname of netcdf file into name for cdl unit, by taking
|
||||
* last component of path and stripping off any extension.
|
||||
* DMH: add code to handle OPeNDAP url.
|
||||
* DMH: I think this also works for UTF8.
|
||||
@ -122,10 +122,10 @@ name_path(const char *path)
|
||||
|
||||
#ifdef vms
|
||||
#define FILE_DELIMITER ']'
|
||||
#endif
|
||||
#endif
|
||||
#if defined(WIN32) || defined(msdos)
|
||||
#define FILE_DELIMITER '\\'
|
||||
#endif
|
||||
#endif
|
||||
#ifndef FILE_DELIMITER /* default to unix */
|
||||
#define FILE_DELIMITER '/'
|
||||
#endif
|
||||
@ -210,7 +210,7 @@ static void
|
||||
tztrim(char *ss)
|
||||
{
|
||||
char *cp, *ep;
|
||||
|
||||
|
||||
cp = ss;
|
||||
if (*cp == '-')
|
||||
cp++;
|
||||
@ -265,7 +265,7 @@ kind_string_extended(int kind, int mode)
|
||||
break;
|
||||
case NC_FORMAT_NC_HDF5:
|
||||
snprintf(text,sizeof(text),"%s mode=%08x", "HDF5",mode);
|
||||
break;
|
||||
break;
|
||||
case NC_FORMAT_NC_HDF4:
|
||||
snprintf(text,sizeof(text),"%s mode=%08x", "HDF4",mode);
|
||||
break;
|
||||
@ -346,23 +346,31 @@ done:
|
||||
fflush(stderr);
|
||||
#endif
|
||||
}
|
||||
if(status != NC_NOERR && mem != NULL)
|
||||
free(mem);
|
||||
else {
|
||||
if(sizep) *sizep = size;
|
||||
if(memp) *memp = mem;
|
||||
if(status != NC_NOERR && mem != NULL) {
|
||||
free(mem);
|
||||
mem = NULL;
|
||||
} else {
|
||||
if(sizep) *sizep = size;
|
||||
if(memp) {
|
||||
*memp = mem;
|
||||
} else if(mem) {
|
||||
free(mem);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
/*
|
||||
* Emit initial line of output for NcML
|
||||
*/
|
||||
static void
|
||||
static void
|
||||
pr_initx(int ncid, const char *path)
|
||||
{
|
||||
printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<netcdf xmlns=\"http://www.unidata.ucar.edu/namespaces/netcdf/ncml-2.2\" location=\"%s\">\n",
|
||||
printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<netcdf xmlns=\"http://www.unidata.ucar.edu/namespaces/netcdf/ncml-2.2\" location=\"%s\">\n",
|
||||
path);
|
||||
}
|
||||
|
||||
@ -395,7 +403,7 @@ pr_att_string(
|
||||
case '\f':
|
||||
printf ("\\f");
|
||||
break;
|
||||
case '\n':
|
||||
case '\n':
|
||||
/* Only generate linebreaks after embedded newlines for
|
||||
* classic, 64-bit offset, or classic model files. For
|
||||
* netCDF-4 files, don't generate linebreaks, because that
|
||||
@ -495,7 +503,7 @@ pr_attx_string(
|
||||
* Print list of attribute values, for attributes of primitive types.
|
||||
* Attribute values must be printed with explicit type tags for
|
||||
* netCDF-3 primitive types, because CDL doesn't require explicit
|
||||
* syntax to declare such attribute types.
|
||||
* syntax to declare such attribute types.
|
||||
*/
|
||||
static void
|
||||
pr_att_valgs(
|
||||
@ -707,7 +715,7 @@ pr_att_valsx(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Print a variable attribute
|
||||
*/
|
||||
static void
|
||||
@ -720,7 +728,7 @@ pr_att(
|
||||
)
|
||||
{
|
||||
ncatt_t att; /* attribute */
|
||||
|
||||
|
||||
NC_CHECK( nc_inq_attname(ncid, varid, ia, att.name) );
|
||||
NC_CHECK( nc_inq_att(ncid, varid, att.name, &att.type, &att.len) );
|
||||
att.tinfo = get_typeinfo(att.type);
|
||||
@ -788,7 +796,7 @@ pr_att(
|
||||
int class, i;
|
||||
void *data;
|
||||
|
||||
NC_CHECK( nc_inq_user_type(ncid, att.type, type_name, &type_size,
|
||||
NC_CHECK( nc_inq_user_type(ncid, att.type, type_name, &type_size,
|
||||
&base_nc_type, &nfields, &class));
|
||||
switch(class)
|
||||
{
|
||||
@ -862,7 +870,7 @@ pr_att(
|
||||
default:
|
||||
error("enum must have an integer base type: %d", base_nc_type);
|
||||
}
|
||||
NC_CHECK( nc_inq_enum_ident(ncid, att.type, value,
|
||||
NC_CHECK( nc_inq_enum_ident(ncid, att.type, value,
|
||||
enum_name));
|
||||
/* printf("%s%s", enum_name, i < att.len-1 ? ", " : ""); */
|
||||
print_name(enum_name);
|
||||
@ -899,7 +907,7 @@ pr_att_name(
|
||||
print_name(attname);
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Print special _Format global attribute, a virtual attribute not
|
||||
* actually stored in the file.
|
||||
*/
|
||||
@ -917,7 +925,7 @@ pr_att_global_format(
|
||||
|
||||
|
||||
#ifdef USE_NETCDF4
|
||||
/*
|
||||
/*
|
||||
* Print special reserved variable attributes, such as _Chunking,
|
||||
* _DeflateLevel, ... These are virtual, not real, attributes
|
||||
* generated from the result of inquire calls. They are of primitive
|
||||
@ -1026,7 +1034,7 @@ pr_att_specials(
|
||||
#endif /* USE_NETCDF4 */
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
* Print a variable attribute for NcML
|
||||
*/
|
||||
static void
|
||||
@ -1076,7 +1084,7 @@ pr_attx(
|
||||
attvalslen = 20*att.len; /* max 20 chars for each value and blank separator */
|
||||
attvals = (char *) emalloc(attvalslen + 1);
|
||||
pr_att_valsx(att.type, att.len, att.vals, attvals, attvalslen);
|
||||
free(att.vals);
|
||||
free(att.vals);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1087,8 +1095,8 @@ pr_attx(
|
||||
#endif /* USE_NETCDF4 */
|
||||
) {
|
||||
/* TODO: XML-ish escapes for special chars in names */
|
||||
printf ("%s <attribute name=\"%s\" value=",
|
||||
varid != NC_GLOBAL ? " " : "",
|
||||
printf ("%s <attribute name=\"%s\" value=",
|
||||
varid != NC_GLOBAL ? " " : "",
|
||||
att.name);
|
||||
/* print attvals as a string with XML escapes */
|
||||
pr_attx_string(attvalslen, attvals);
|
||||
@ -1096,9 +1104,9 @@ pr_attx(
|
||||
char att_type_name[NC_MAX_NAME + 1];
|
||||
get_type_name(ncid, att.type, att_type_name);
|
||||
/* TODO: print full type name with group prefix, when needed */
|
||||
printf ("%s <attribute name=\"%s\" type=\"%s\" value=\"",
|
||||
varid != NC_GLOBAL ? " " : "",
|
||||
att.name,
|
||||
printf ("%s <attribute name=\"%s\" type=\"%s\" value=\"",
|
||||
varid != NC_GLOBAL ? " " : "",
|
||||
att.name,
|
||||
att_type_name);
|
||||
printf("%s\"",attvals);
|
||||
}
|
||||
@ -1157,10 +1165,10 @@ print_enum_type(int ncid, nc_type typeid) {
|
||||
char *esc_mn;
|
||||
int res;
|
||||
|
||||
NC_CHECK( nc_inq_user_type(ncid, typeid, type_name, &type_size, &base_nc_type,
|
||||
NC_CHECK( nc_inq_user_type(ncid, typeid, type_name, &type_size, &base_nc_type,
|
||||
&type_nfields, &type_class) );
|
||||
|
||||
get_type_name(ncid, base_nc_type, base_type_name);
|
||||
get_type_name(ncid, base_nc_type, base_type_name);
|
||||
indent_out();
|
||||
esc_btn = escaped_name(base_type_name);
|
||||
esc_tn = escaped_name(type_name);
|
||||
@ -1206,7 +1214,7 @@ print_enum_type(int ncid, nc_type typeid) {
|
||||
break;
|
||||
}
|
||||
esc_mn = escaped_name(memname);
|
||||
res = snprintf(safe_buf, SAFE_BUF_LEN, "%s = %lld%s", esc_mn,
|
||||
res = snprintf(safe_buf, SAFE_BUF_LEN, "%s = %lld%s", esc_mn,
|
||||
memval, delim);
|
||||
assert(res < SAFE_BUF_LEN);
|
||||
free(esc_mn);
|
||||
@ -1218,14 +1226,14 @@ print_enum_type(int ncid, nc_type typeid) {
|
||||
/* Print a user-defined type declaration */
|
||||
static void
|
||||
print_ud_type(int ncid, nc_type typeid) {
|
||||
|
||||
|
||||
char type_name[NC_MAX_NAME + 1];
|
||||
char base_type_name[NC_MAX_NAME + 1];
|
||||
size_t type_nfields, type_size;
|
||||
nc_type base_nc_type;
|
||||
int f, type_class;
|
||||
|
||||
NC_CHECK( nc_inq_user_type(ncid, typeid, type_name, &type_size, &base_nc_type,
|
||||
|
||||
NC_CHECK( nc_inq_user_type(ncid, typeid, type_name, &type_size, &base_nc_type,
|
||||
&type_nfields, &type_class) );
|
||||
switch(type_class) {
|
||||
case NC_VLEN:
|
||||
@ -1257,7 +1265,7 @@ print_ud_type(int ncid, nc_type typeid) {
|
||||
nc_type field_type;
|
||||
int field_ndims;
|
||||
int d;
|
||||
|
||||
|
||||
indent_out();
|
||||
/* printf("compound %s {\n", type_name); */
|
||||
printf("compound ");
|
||||
@ -1265,8 +1273,8 @@ print_ud_type(int ncid, nc_type typeid) {
|
||||
printf(" {\n");
|
||||
for (f = 0; f < type_nfields; f++)
|
||||
{
|
||||
NC_CHECK( nc_inq_compound_field(ncid, typeid, f, field_name,
|
||||
&field_offset, &field_type,
|
||||
NC_CHECK( nc_inq_compound_field(ncid, typeid, f, field_name,
|
||||
&field_offset, &field_type,
|
||||
&field_ndims, NULL) );
|
||||
/* TODO: don't bother if field_type_name not needed here */
|
||||
get_type_name(ncid, field_type, field_type_name);
|
||||
@ -1278,8 +1286,8 @@ print_ud_type(int ncid, nc_type typeid) {
|
||||
print_name(field_name);
|
||||
if (field_ndims > 0) {
|
||||
int *field_dim_sizes = (int *) emalloc((field_ndims + 1) * sizeof(int));
|
||||
NC_CHECK( nc_inq_compound_field(ncid, typeid, f, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NC_CHECK( nc_inq_compound_field(ncid, typeid, f, NULL,
|
||||
NULL, NULL, NULL,
|
||||
field_dim_sizes) );
|
||||
printf("(");
|
||||
for (d = 0; d < field_ndims-1; d++)
|
||||
@ -1307,9 +1315,9 @@ get_fill_info(int ncid, int varid, ncvar_t *vp) {
|
||||
ncatt_t att; /* attribute */
|
||||
int nc_status; /* return from netcdf calls */
|
||||
void *fillvalp = NULL;
|
||||
|
||||
|
||||
vp->has_fillval = 1; /* by default, but turn off for bytes */
|
||||
|
||||
|
||||
/* get _FillValue attribute */
|
||||
nc_status = nc_inq_att(ncid,varid,_FillValue,&att.type,&att.len);
|
||||
fillvalp = emalloc(vp->tinfo->size + 1);
|
||||
@ -1378,7 +1386,7 @@ get_fill_info(int ncid, int varid, ncvar_t *vp) {
|
||||
* 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)
|
||||
* ncid: id of open file (first call) or group (subsequent recursive calls)
|
||||
* path: file path name (first call)
|
||||
*/
|
||||
static void
|
||||
@ -1470,7 +1478,7 @@ do_ncdump_rec(int ncid, const char *path)
|
||||
/* Find the number of dimids defined in this group. */
|
||||
NC_CHECK( nc_inq_ndims(ncid, &ndims_grp) );
|
||||
dimids_grp = (int *)emalloc((ndims_grp + 1) * sizeof(int));
|
||||
|
||||
|
||||
/* Find the dimension ids in this group. */
|
||||
NC_CHECK( nc_inq_dimids(ncid, 0, dimids_grp, 0) );
|
||||
|
||||
@ -1478,7 +1486,7 @@ do_ncdump_rec(int ncid, const char *path)
|
||||
NC_CHECK( nc_inq_unlimdims(ncid, &nunlim, NULL) );
|
||||
unlimids = (int *)emalloc((nunlim + 1) * sizeof(int));
|
||||
NC_CHECK( nc_inq_unlimdims(ncid, &nunlim, unlimids) );
|
||||
|
||||
|
||||
/* For each dimension defined in this group, get and print out info. */
|
||||
for (d_grp = 0; d_grp < ndims_grp; d_grp++)
|
||||
{
|
||||
@ -1491,7 +1499,7 @@ do_ncdump_rec(int ncid, const char *path)
|
||||
if(dimid == unlimids[uld]) {
|
||||
is_unlimited = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
stat = nc_inq_dim(ncid, dimid, dims[d_grp].name, &dims[d_grp].size);
|
||||
if (stat == NC_EDIMSIZE && SIZEOF_SIZE_T < 8) {
|
||||
@ -1505,14 +1513,14 @@ do_ncdump_rec(int ncid, const char *path)
|
||||
printf (" = ");
|
||||
if(SIZEOF_SIZE_T >= 8) {
|
||||
if (is_unlimited) {
|
||||
printf ("UNLIMITED ; // (%lu currently)\n",
|
||||
printf ("UNLIMITED ; // (%lu currently)\n",
|
||||
(unsigned long)dims[d_grp].size);
|
||||
} else {
|
||||
printf ("%lu ;\n", (unsigned long)dims[d_grp].size);
|
||||
}
|
||||
} else { /* 32-bit platform */
|
||||
if (is_unlimited) {
|
||||
printf ("UNLIMITED ; // (%u currently)\n",
|
||||
printf ("UNLIMITED ; // (%u currently)\n",
|
||||
(unsigned int)dims[d_grp].size);
|
||||
} else {
|
||||
printf ("%u ;\n", (unsigned int)dims[d_grp].size);
|
||||
@ -1531,7 +1539,7 @@ do_ncdump_rec(int ncid, const char *path)
|
||||
print_name(dims[dimid].name);
|
||||
printf (" = ");
|
||||
if (dimid == xdimid) {
|
||||
printf ("UNLIMITED ; // (%u currently)\n",
|
||||
printf ("UNLIMITED ; // (%u currently)\n",
|
||||
(unsigned int)dims[dimid].size);
|
||||
} else {
|
||||
printf ("%u ;\n", (unsigned int)dims[dimid].size);
|
||||
@ -1549,11 +1557,11 @@ do_ncdump_rec(int ncid, const char *path)
|
||||
* 64-bit offset files. So we need to know the output file type
|
||||
* to know how to print strings with embedded newlines. */
|
||||
NC_CHECK( nc_inq_format(ncid, &kind) );
|
||||
|
||||
|
||||
/* For each var, get and print out info. */
|
||||
|
||||
memset((void*)&var,0,sizeof(var));
|
||||
|
||||
|
||||
for (varid = 0; varid < nvars; varid++) {
|
||||
NC_CHECK( nc_inq_varndims(ncid, varid, &var.ndims) );
|
||||
if(var.dims != NULL) free(var.dims);
|
||||
@ -1651,7 +1659,7 @@ do_ncdump_rec(int ncid, const char *path)
|
||||
/* 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 &&
|
||||
if (! formatting_specs.header_only &&
|
||||
group_wanted(ncid, formatting_specs.nlgrps, formatting_specs.grpids) ) {
|
||||
if (nvars > 0) {
|
||||
indent_out();
|
||||
@ -1727,13 +1735,13 @@ do_ncdump_rec(int ncid, const char *path)
|
||||
|
||||
/* See how many groups there are. */
|
||||
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++)
|
||||
{
|
||||
@ -1753,7 +1761,7 @@ do_ncdump_rec(int ncid, const char *path)
|
||||
printf ("\n");
|
||||
indent_less();
|
||||
}
|
||||
|
||||
|
||||
free(ncids);
|
||||
}
|
||||
#endif /* USE_NETCDF4 */
|
||||
@ -1829,10 +1837,10 @@ do_ncdumpx(int ncid, const char *path)
|
||||
for (dimid = 0; dimid < ndims; dimid++) {
|
||||
NC_CHECK( nc_inq_dim(ncid, dimid, dims[dimid].name, &dims[dimid].size) );
|
||||
if (dimid == xdimid)
|
||||
printf(" <dimension name=\"%s\" length=\"%d\" isUnlimited=\"true\" />\n",
|
||||
printf(" <dimension name=\"%s\" length=\"%d\" isUnlimited=\"true\" />\n",
|
||||
dims[dimid].name, (int)dims[dimid].size);
|
||||
else
|
||||
printf (" <dimension name=\"%s\" length=\"%d\" />\n",
|
||||
printf (" <dimension name=\"%s\" length=\"%d\" />\n",
|
||||
dims[dimid].name, (int)dims[dimid].size);
|
||||
}
|
||||
|
||||
@ -1880,7 +1888,7 @@ do_ncdumpx(int ncid, const char *path)
|
||||
}
|
||||
printf (" </variable>\n");
|
||||
}
|
||||
|
||||
|
||||
printf ("</netcdf>\n");
|
||||
if (vlist)
|
||||
freeidlist(vlist);
|
||||
@ -2057,7 +2065,7 @@ main(int argc, char *argv[])
|
||||
break;
|
||||
case 'g': /* group names */
|
||||
/* make list of names of groups specified */
|
||||
make_lgrps (optarg, &formatting_specs.nlgrps, &formatting_specs.lgrps,
|
||||
make_lgrps (optarg, &formatting_specs.nlgrps, &formatting_specs.lgrps,
|
||||
&formatting_specs.grpids);
|
||||
break;
|
||||
case 'd': /* specify precision for floats (deprecated, undocumented) */
|
||||
@ -2097,7 +2105,7 @@ main(int argc, char *argv[])
|
||||
case 'm':
|
||||
formatting_specs.xopt_inmemory = 1;
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
error("invalid value for -X option: %s", optarg);
|
||||
break;
|
||||
}
|
||||
@ -2108,7 +2116,7 @@ main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
set_max_len(max_len);
|
||||
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
@ -2123,11 +2131,11 @@ main(int argc, char *argv[])
|
||||
|
||||
init_epsilons();
|
||||
|
||||
{
|
||||
{
|
||||
char *path = strdup(argv[i]);
|
||||
if(!path)
|
||||
error("out of memory copying argument %s", argv[i]);
|
||||
if (!nameopt)
|
||||
if (!nameopt)
|
||||
formatting_specs.name = name_path(path);
|
||||
if (argc > 0) {
|
||||
int ncid, nc_status;
|
||||
@ -2151,7 +2159,7 @@ main(int argc, char *argv[])
|
||||
nc_status = fileopen(path,&mem,&size);
|
||||
if(nc_status == NC_NOERR)
|
||||
nc_status = nc_open_mem(path,NC_DISKLESS|NC_INMEMORY,size,mem,&ncid);
|
||||
} else
|
||||
} else
|
||||
#endif
|
||||
nc_status = nc_open(path, NC_NOWRITE, &ncid);
|
||||
if (nc_status != NC_NOERR) {
|
||||
|
Loading…
Reference in New Issue
Block a user