mirror of
https://github.com/Unidata/netcdf-c.git
synced 2025-03-01 17:06:03 +08:00
Fixed bug NCF-310 (ncdump char vars with multiple unlimited dims).
Added associated tests and entry in RELEASE_NOTES.
This commit is contained in:
parent
091a4f3c0c
commit
720e4ea82c
@ -9,6 +9,8 @@ This file contains a high-level description of this package's evolution. Release
|
||||
|
||||
### 4.3.3-rc1 Released TBD
|
||||
|
||||
* Fixed ncdump bug for char variables with multiple unlimited dimensions and added an associated test. Now the output CDL properly disambiguates dimension groupings, so that ncgen can generate the original file from the CDL. [NCF-310](https://bugtracking.unidata.ucar.edu/browse/NCF-310)
|
||||
|
||||
* Converted the [Manually-maintained FAQ page](http://www.unidata.ucar.edu/software/netcdf/docs/faq.html) into markdown and added it to the `docs/` directory. This way the html version will be generated when the rest of the documentation is built, the FAQ will be under version control, and it will be in a more visible location, hopefully making it easier to maintain.
|
||||
|
||||
* Bumped minimum required version of `cmake` to `2.8.12`. This was necessitated by the adoption of the new `CMAKE_MACOSX_RPATH` property, for use on OSX.
|
||||
|
114
ncdump/ref_tst_mud4_chars.cdl
Normal file
114
ncdump/ref_tst_mud4_chars.cdl
Normal file
@ -0,0 +1,114 @@
|
||||
netcdf tst_mud4_chars {
|
||||
dimensions:
|
||||
F1 = 1 ;
|
||||
F2 = 2 ;
|
||||
F3 = 3 ;
|
||||
F5 = 5 ;
|
||||
U1 = UNLIMITED ; // (1 currently)
|
||||
U2 = UNLIMITED ; // (2 currently)
|
||||
U3 = UNLIMITED ; // (3 currently)
|
||||
U5 = UNLIMITED ; // (5 currently)
|
||||
variables:
|
||||
char ff(F2, F3) ;
|
||||
char uf(U2, F3) ;
|
||||
char fu(F2, U3) ;
|
||||
char uu(U2, U3) ;
|
||||
char ufff(U1, F2, F3, F5) ;
|
||||
char uffu(U1, F2, F3, U5) ;
|
||||
char ufuf(U1, F2, U3, F5) ;
|
||||
char ufuu(U1, F2, U3, U5) ;
|
||||
char uuff(U1, U2, F3, F5) ;
|
||||
char uufu(U1, U2, F3, U5) ;
|
||||
char uuuf(U1, U2, U3, F5) ;
|
||||
char uuuu(U1, U2, U3, U5) ;
|
||||
char ffff(F1, F2, F3, F5) ;
|
||||
data:
|
||||
|
||||
ff =
|
||||
"abc",
|
||||
"def" ;
|
||||
|
||||
uf =
|
||||
"abc",
|
||||
"def" ;
|
||||
|
||||
fu =
|
||||
{"efg"},
|
||||
{"hij"} ;
|
||||
|
||||
uu =
|
||||
{"efg"},
|
||||
{"hij"} ;
|
||||
|
||||
ufff =
|
||||
"efghi",
|
||||
"jklmJ",
|
||||
"KLMNO",
|
||||
"PQRST",
|
||||
"UVWXY",
|
||||
"Zabcd" ;
|
||||
|
||||
uffu =
|
||||
{"efghi"},
|
||||
{"jklmJ"},
|
||||
{"KLMNO"},
|
||||
{"PQRST"},
|
||||
{"UVWXY"},
|
||||
{"Zabcd"} ;
|
||||
|
||||
ufuf =
|
||||
{"efghi",
|
||||
"jklmJ",
|
||||
"KLMNO"},
|
||||
{"PQRST",
|
||||
"UVWXY",
|
||||
"Zabcd"} ;
|
||||
|
||||
ufuu =
|
||||
{{"efghi"},
|
||||
{"jklmJ"},
|
||||
{"KLMNO"}},
|
||||
{{"PQRST"},
|
||||
{"UVWXY"},
|
||||
{"Zabcd"}} ;
|
||||
|
||||
uuff =
|
||||
{"efghi",
|
||||
"jklmJ",
|
||||
"KLMNO",
|
||||
"PQRST",
|
||||
"UVWXY",
|
||||
"Zabcd"} ;
|
||||
|
||||
uufu =
|
||||
{{"efghi"},
|
||||
{"jklmJ"},
|
||||
{"KLMNO"},
|
||||
{"PQRST"},
|
||||
{"UVWXY"},
|
||||
{"Zabcd"}} ;
|
||||
|
||||
uuuf =
|
||||
{{"efghi",
|
||||
"jklmJ",
|
||||
"KLMNO"},
|
||||
{"PQRST",
|
||||
"UVWXY",
|
||||
"Zabcd"}} ;
|
||||
|
||||
uuuu =
|
||||
{{{"efghi"},
|
||||
{"jklmJ"},
|
||||
{"KLMNO"}},
|
||||
{{"PQRST"},
|
||||
{"UVWXY"},
|
||||
{"Zabcd"}}} ;
|
||||
|
||||
ffff =
|
||||
"efghi",
|
||||
"jklmJ",
|
||||
"KLMNO",
|
||||
"PQRST",
|
||||
"UVWXY",
|
||||
"Zabcd" ;
|
||||
}
|
@ -22,5 +22,15 @@ diff -b tst_mud4.cdl $srcdir/ref_tst_mud4.cdl
|
||||
# echo "*** comparing annotation from ncdump -bc tst_mud4.nc with expected output..."
|
||||
./ncdump -bc tst_mud4.nc > tst_mud4-bc.cdl
|
||||
diff -b tst_mud4-bc.cdl $srcdir/ref_tst_mud4-bc.cdl
|
||||
# Now test with char arrays instead of ints
|
||||
echo "*** creating netcdf file tst_mud4_chars.nc from ref_tst_mud4_chars.cdl ..."
|
||||
../ncgen/ncgen -k3 -b -o tst_mud4_chars.nc $srcdir/ref_tst_mud4_chars.cdl
|
||||
echo "*** creating tst_mud4_chars.cdl from tst_mud4_chars.nc ..."
|
||||
./ncdump tst_mud4_chars.nc > tst_mud4_chars.cdl
|
||||
# echo "*** comparing tst_mud4_chars.cdl with ref_tst_mud4_chars.cdl..."
|
||||
diff -b tst_mud4_chars.cdl $srcdir/ref_tst_mud4_chars.cdl
|
||||
# echo "*** comparing annotation from ncdump -bc tst_mud4_chars.nc with expected output..."
|
||||
# ./ncdump -bc tst_mud4_chars.nc > tst_mud4_chars-bc.cdl
|
||||
# diff -b tst_mud4_chars-bc.cdl $srcdir/ref_tst_mud4_chars-bc.cdl
|
||||
echo "*** All ncdump test output for multiple unlimited dimensions passed!"
|
||||
exit 0
|
||||
|
@ -323,9 +323,6 @@ static void
|
||||
pr_tvals(
|
||||
const ncvar_t *vp, /* variable */
|
||||
size_t len, /* number of values to print */
|
||||
bool_t lastrow, /* true if this is the last row for this
|
||||
* variable, so terminate with ";" instead
|
||||
* of "," */
|
||||
const char *vals, /* pointer to block of values */
|
||||
const size_t *cor /* corner coordinates */
|
||||
)
|
||||
@ -377,13 +374,10 @@ pr_tvals(
|
||||
}
|
||||
}
|
||||
printf("\"");
|
||||
/* if (fsp && formatting_specs.full_data_cmnts) { */
|
||||
if (formatting_specs.full_data_cmnts) {
|
||||
lastdelim (0, lastrow);
|
||||
annotate (vp, (size_t *)cor, 0L);
|
||||
} else {
|
||||
lastdelim2 (0, lastrow);
|
||||
}
|
||||
/* if (formatting_specs.full_data_cmnts) { */
|
||||
/* lastdelim (0, lastrow); */
|
||||
/* annotate (vp, (size_t *)cor, 0L); */
|
||||
/* } */
|
||||
}
|
||||
|
||||
|
||||
@ -428,8 +422,6 @@ print_rows(
|
||||
int ncid, /* netcdf id */
|
||||
int varid, /* variable id */
|
||||
const ncvar_t *vp, /* variable */
|
||||
size_t ncols, /* number of values in a row */
|
||||
int rank, /* number of elements in following 3 arrays */
|
||||
size_t vdims[], /* variable dimension sizes */
|
||||
size_t cor[], /* corner coordinates */
|
||||
size_t edg[], /* edges of hypercube */
|
||||
@ -437,6 +429,8 @@ print_rows(
|
||||
int marks_pending /* number of pending closing "}" record markers */
|
||||
)
|
||||
{
|
||||
int rank = vp->ndims;
|
||||
size_t ncols = rank > 0 ? vdims[rank - 1] : 1; /* number of values in a row */
|
||||
int d0 = 0;
|
||||
size_t inc = 1;
|
||||
int i;
|
||||
@ -461,11 +455,11 @@ print_rows(
|
||||
local_cor[level] = 0;
|
||||
local_edg[level] = 1;
|
||||
for(i = 0; i < d0 - 1; i++) {
|
||||
print_rows(level + 1, ncid, varid, vp, ncols, rank, vdims,
|
||||
print_rows(level + 1, ncid, varid, vp, vdims,
|
||||
local_cor, local_edg, vals, 0);
|
||||
local_cor[level] += 1;
|
||||
}
|
||||
print_rows(level + 1, ncid, varid, vp, ncols, rank, vdims,
|
||||
print_rows(level + 1, ncid, varid, vp, vdims,
|
||||
local_cor, local_edg, vals, marks_pending);
|
||||
free(local_edg);
|
||||
free(local_cor);
|
||||
@ -473,22 +467,28 @@ print_rows(
|
||||
char *valp = vals;
|
||||
bool_t lastrow;
|
||||
int j;
|
||||
if(formatting_specs.brief_data_cmnts && rank > 1) {
|
||||
if(formatting_specs.brief_data_cmnts && rank > 1 && ncols > 0) {
|
||||
annotate_brief(vp, cor, vdims);
|
||||
}
|
||||
NC_CHECK(nc_get_vara(ncid, varid, cor, edg, (void *)valp));
|
||||
for(i=0; i < d0 - 1; i++) {
|
||||
print_any_val(sb, vp, (void *)valp);
|
||||
valp += vp->tinfo->size; /* next value according to type */
|
||||
if (formatting_specs.full_data_cmnts) {
|
||||
printf("%s, ", sb->buf);
|
||||
annotate (vp, cor, i);
|
||||
} else {
|
||||
sbuf_cat(sb, ", ");
|
||||
lput(sbuf_str(sb));
|
||||
|
||||
/* Test if we should treat array of chars as strings along last dimension */
|
||||
if(vp->type == NC_CHAR && (vp->fmt == 0 || STREQ(vp->fmt,"%s") || STREQ(vp->fmt,""))) {
|
||||
pr_tvals(vp, ncols, vals, cor);
|
||||
} else { /* for non-text variables */
|
||||
for(i=0; i < d0 - 1; i++) {
|
||||
print_any_val(sb, vp, (void *)valp);
|
||||
valp += vp->tinfo->size; /* next value according to type */
|
||||
if (formatting_specs.full_data_cmnts) {
|
||||
printf("%s, ", sb->buf);
|
||||
annotate (vp, cor, i);
|
||||
} else {
|
||||
sbuf_cat(sb, ", ");
|
||||
lput(sbuf_str(sb));
|
||||
}
|
||||
}
|
||||
print_any_val(sb, vp, (void *)valp);
|
||||
}
|
||||
print_any_val(sb, vp, (void *)valp);
|
||||
/* determine if this is the last row */
|
||||
lastrow = true;
|
||||
for(j = 0; j < rank - 1; j++) {
|
||||
@ -503,7 +503,7 @@ print_rows(
|
||||
}
|
||||
printf("%s", sbuf_str(sb));
|
||||
lastdelim (0, lastrow);
|
||||
annotate (vp, cor, i);
|
||||
annotate (vp, cor, 0L);
|
||||
} else {
|
||||
for (j = 0; j < marks_pending; j++) {
|
||||
sbuf_cat(sb, "}");
|
||||
@ -516,7 +516,6 @@ print_rows(
|
||||
return NC_NOERR;
|
||||
}
|
||||
|
||||
|
||||
/* Output the data for a single variable, in CDL syntax. */
|
||||
int
|
||||
vardata(
|
||||
@ -532,7 +531,6 @@ vardata(
|
||||
void *vals;
|
||||
|
||||
int id;
|
||||
int ir;
|
||||
size_t nels;
|
||||
size_t ncols;
|
||||
size_t nrows;
|
||||
@ -578,28 +576,9 @@ vardata(
|
||||
nrows = nels/ncols; /* number of "rows" */
|
||||
vals = emalloc(ncols * vp->tinfo->size);
|
||||
|
||||
/* Test if we should treat array of chars as a string */
|
||||
if(vp->type == NC_CHAR && (vp->fmt == 0 || STREQ(vp->fmt,"%s") || STREQ(vp->fmt,""))) {
|
||||
for (ir = 0; ir < nrows; ir++) {
|
||||
if (vrank > 0) {
|
||||
if (formatting_specs.brief_data_cmnts != false && vrank > 1 && ncols > 0) {
|
||||
annotate_brief(vp, cor, vdims);
|
||||
}
|
||||
}
|
||||
NC_CHECK(nc_get_vara(ncid, varid, cor, edg, vals));
|
||||
pr_tvals(vp, ncols, (ir == nrows-1), (char *) vals, cor);
|
||||
if (ir < nrows-1)
|
||||
if (!upcorner(vdims, vp->ndims, cor, add))
|
||||
error("vardata: odometer overflowed!");
|
||||
set_indent(2);
|
||||
}
|
||||
} else {
|
||||
int level = 0;
|
||||
int rank = vp->ndims;
|
||||
int marks_pending = 0;
|
||||
NC_CHECK(print_rows(level, ncid, varid, vp, ncols, rank, vdims, cor, edg,
|
||||
vals, marks_pending));
|
||||
}
|
||||
int level = 0;
|
||||
int marks_pending = 0;
|
||||
NC_CHECK(print_rows(level, ncid, varid, vp, vdims, cor, edg, vals, marks_pending));
|
||||
free(vals);
|
||||
free(cor);
|
||||
free(edg);
|
||||
@ -775,7 +754,7 @@ vardatax(
|
||||
vals = emalloc(ncols * vp->tinfo->size);
|
||||
|
||||
for (ir = 0; ir < nrows; ir++) {
|
||||
size_t corsav;
|
||||
size_t corsav = 0;
|
||||
bool_t lastrow;
|
||||
|
||||
if (vrank > 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user