/other/netcdf_write_matrix/src/ncdump/vardata.c
C | 1287 lines | 1181 code | 36 blank | 70 comment | 79 complexity | 98740fec7982f869b9bd74906f0aa679 MD5 | raw file
Possible License(s): AGPL-1.0
- /*********************************************************************
- * Copyright 1993, UCAR/Unidata
- * See netcdf/COPYRIGHT file for copying and redistribution conditions.
- * $Header: /upc/share/CVS/netcdf-3/ncdump/vardata.c,v 1.12 2005/07/22 23:01:39 russ Exp $
- *********************************************************************/
- #include <stdio.h>
- #include <ctype.h>
- #include <stdlib.h>
- #include <string.h>
- #ifndef NO_FLOAT_H
- #include <float.h> /* for FLT_EPSILON, DBL_EPSILON */
- #endif /* NO_FLOAT_H */
- #include <netcdf.h>
- #include "ncdump.h"
- #include "dumplib.h"
- #include "vardata.h"
- static float float_epsilon(void);
- static double double_epsilon(void);
- static void init_epsilons(void);
- static void printbval(char* sout, const char* fmt, const ncvar_t* varp,
- signed char val);
- static void printsval(char* sout, const char* fmt, const ncvar_t* varp,
- short val);
- static void printival(char* sout, const char* fmt, const ncvar_t* varp,
- int val);
- static void printfval(char* sout, const char* fmt, const ncvar_t* varp,
- float val);
- static void printdval(char* sout, const char* fmt, const ncvar_t* varp,
- double val);
- static void lastdelim(boolean more, boolean lastrow);
- static void annotate(const ncvar_t* vp, const fspec_t* fsp,
- const size_t* cor, long iel);
- static void pr_tvals(const ncvar_t *vp, size_t len, const char *fmt,
- boolean more, boolean lastrow, const char *vals,
- const fspec_t* fsp, const size_t *cor);
- static void pr_bvals(const ncvar_t *vp, size_t len, const char *fmt,
- boolean more, boolean lastrow, const signed char *vals,
- const fspec_t* fsp, const size_t *cor);
- static void pr_svals(const ncvar_t *vp, size_t len, const char *fmt,
- boolean more, boolean lastrow, const short *vals,
- const fspec_t* fsp, const size_t *cor);
- static void pr_ivals(const ncvar_t *vp, size_t len, const char *fmt,
- boolean more, boolean lastrow, const int *vals,
- const fspec_t* fsp, const size_t *cor);
- static void pr_fvals(const ncvar_t *vp, size_t len, const char *fmt,
- boolean more, boolean lastrow, const float *vals,
- const fspec_t* fsp, const size_t *cor);
- static void pr_dvals(const ncvar_t *vp, size_t len, const char *fmt,
- boolean more, boolean lastrow, const double *vals,
- const fspec_t* fsp, const size_t *cor);
- static int upcorner(const size_t* dims, int ndims, size_t* odom,
- const size_t* add);
- static void lastdelim2 (boolean more, boolean lastrow);
- #define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
- static float float_eps;
- static double double_eps;
- static float
- float_epsilon(void)
- {
- float float_eps;
- #ifndef NO_FLOAT_H
- float_eps = FLT_EPSILON;
- #else /* NO_FLOAT_H */
- {
- float etop, ebot, eps;
- float one = 1.0;
- float two = 2.0;
- etop = 1.0;
- ebot = 0.0;
- eps = ebot + (etop - ebot)/two;
- while (eps != ebot && eps != etop) {
- float epsp1;
- epsp1 = one + eps;
- if (epsp1 > one)
- etop = eps;
- else
- ebot = eps;
- eps = ebot + (etop - ebot)/two;
- }
- float_eps = two * etop;
- }
- #endif /* NO_FLOAT_H */
- return float_eps;
- }
- static double
- double_epsilon(void)
- {
- double double_eps;
- #ifndef NO_FLOAT_H
- double_eps = DBL_EPSILON;
- #else /* NO_FLOAT_H */
- {
- double etop, ebot, eps;
- double one = 1.0;
- double two = 2.0;
- etop = 1.0;
- ebot = 0.0;
- eps = ebot + (etop - ebot)/two;
- while (eps != ebot && eps != etop) {
- double epsp1;
- epsp1 = one + eps;
- if (epsp1 > one)
- etop = eps;
- else
- ebot = eps;
- eps = ebot + (etop - ebot)/two;
- }
- double_eps = two * etop;
- }
- #endif /* NO_FLOAT_H */
- return double_eps;
- }
- static void
- init_epsilons(void)
- {
- float_eps = float_epsilon();
- double_eps = double_epsilon();
- }
- /*
- * Output a value of a byte variable, except if there is a fill value for
- * the variable and the value is the fill value, print the fill-value string
- * instead.
- */
- static void
- printbval(
- char *sout, /* string where output goes */
- const char *fmt, /* printf format used for value */
- const ncvar_t *varp, /* variable */
- signed char val /* value */
- )
- {
- if (varp->has_fillval) {
- double fillval = varp->fillval;
- if(fillval == val) {
- (void) sprintf(sout, FILL_STRING);
- return;
- }
- }
- (void) sprintf(sout, fmt, val);
- }
- /*
- * Output a value of a short variable, except if there is a fill value for
- * the variable and the value is the fill value, print the fill-value string
- * instead.
- */
- static void
- printsval(
- char *sout, /* string where output goes */
- const char *fmt, /* printf format used for value */
- const ncvar_t *varp, /* variable */
- short val /* value */
- )
- {
- if (varp->has_fillval) {
- double fillval = varp->fillval;
- if(fillval == val) {
- (void) sprintf(sout, FILL_STRING);
- return;
- }
- }
- (void) sprintf(sout, fmt, val);
- }
- /*
- * Output a value of an int variable, except if there is a fill value for
- * the variable and the value is the fill value, print the fill-value string
- * instead.
- */
- static void
- printival(
- char *sout, /* string where output goes */
- const char *fmt, /* printf format used for value */
- const ncvar_t *varp, /* variable */
- int val /* value */
- )
- {
- if (varp->has_fillval) {
- int fillval = (int)varp->fillval;
- if(fillval == val) {
- (void) sprintf(sout, FILL_STRING);
- return;
- }
- }
- (void) sprintf(sout, fmt, val);
- }
- #define absval(x) ( (x) < 0 ? -(x) : (x) )
- /*
- * Output a value of a float variable, except if there is a fill value for
- * the variable and the value is the fill value, print the fill-value string
- * instead. Floating-point fill values need only be within machine epsilon of
- * defined fill value.
- */
- static void
- printfval(
- char *sout, /* string where output goes */
- const char *fmt, /* printf format used for value */
- const ncvar_t *varp, /* variable */
- float val /* value */
- )
- {
- if(varp->has_fillval) {
- double fillval = varp->fillval;
- if((val > 0) == (fillval > 0) && /* prevents potential overflow */
- (absval(val - fillval) <= absval(float_eps * fillval))) {
- (void) sprintf(sout, FILL_STRING);
- return;
- }
- }
- (void) sprintf(sout, fmt, val);
- }
- /*
- * Output a value of a double variable, except if there is a fill value for
- * the variable and the value is the fill value, print the fill-value string
- * instead. Floating-point fill values need only be within machine epsilon of
- * defined fill value.
- */
- static void
- printdval(
- char *sout, /* string where output goes */
- const char *fmt, /* printf format used for value */
- const ncvar_t *varp, /* variable */
- double val /* value */
- )
- {
- if(varp->has_fillval) {
- double fillval = varp->fillval;
- if((val > 0) == (fillval > 0) && /* prevents potential overflow */
- (absval(val - fillval) <= absval(double_eps * fillval))) {
- (void) sprintf(sout, FILL_STRING);
- return;
- }
- }
- (void) sprintf(sout, fmt, val);
- }
- /*
- * print last delimiter in each line before annotation (, or ;)
- */
- static void
- lastdelim (boolean more, boolean lastrow)
- {
- if (more) {
- Printf(", ");
- } else {
- if(lastrow) {
- Printf(";");
- } else {
- Printf(",");
- }
- }
- }
- /*
- * print last delimiter in each line before annotation (, or ;)
- */
- static void
- lastdelim2 (boolean more, boolean lastrow)
- {
- if (more) {
- lput(", ");
- } else {
- if(lastrow) {
- lput(" ;");
- lput("\n");
- } else {
- lput(",\n");
- lput(" ");
- }
- }
- }
- /*
- * Annotates a value in data section with var name and indices in comment
- */
- static void
- annotate(
- const ncvar_t *vp, /* variable */
- const fspec_t* fsp, /* formatting specs */
- const size_t *cor, /* corner coordinates */
- long iel /* which element in current row */
- )
- {
- int vrank = vp->ndims;
- int id;
-
- /* print indices according to data_lang */
- (void) printf(" // %s(", vp->name);
- switch (fsp->data_lang) {
- case LANG_C:
- /* C variable indices */
- for (id = 0; id < vrank-1; id++)
- Printf("%lu,", (unsigned long) cor[id]);
- Printf("%lu", (unsigned long) cor[id] + iel);
- break;
- case LANG_F:
- /* Fortran variable indices */
- Printf("%lu", (unsigned long) cor[vrank-1] + iel + 1);
- for (id = vrank-2; id >=0 ; id--) {
- Printf(",%lu", 1 + (unsigned long) cor[id]);
- }
- break;
- }
- Printf(")\n ");
- }
- /*
- * Print a number of char variable values, where the optional comments
- * for each value identify the variable, and each dimension index.
- */
- static void
- pr_tvals(
- const ncvar_t *vp, /* variable */
- size_t len, /* number of values to print */
- const char *fmt, /* printf format used for each value. If
- * nc_type is NC_CHAR and this is NULL,
- * character arrays will be printed as
- * strings enclosed in quotes. */
- boolean more, /* true if more data for this row will
- * follow, so add trailing comma */
- boolean 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 fspec_t* fsp, /* formatting specs */
- const size_t *cor /* corner coordinates */
- )
- {
- long iel;
- const char *sp;
- unsigned char uc;
- char sout[100]; /* temporary string for each encoded output */
- if (fmt == 0 || STREQ(fmt,"%s") || STREQ(fmt,"")) { /* as string */
- Printf("\"");
- /* adjust len so trailing nulls don't get printed */
- sp = vals + len;
- while (len != 0 && *--sp == '\0')
- len--;
- for (iel = 0; iel < len; iel++)
- switch (uc = *vals++ & 0377) {
- case '\b':
- Printf("\\b");
- break;
- case '\f':
- Printf("\\f");
- break;
- case '\n': /* generate linebreaks after new-lines */
- Printf("\\n\",\n \"");
- break;
- case '\r':
- Printf("\\r");
- break;
- case '\t':
- Printf("\\t");
- break;
- case '\v':
- Printf("\\v");
- break;
- case '\\':
- Printf("\\\\");
- break;
- case '\'':
- Printf("\\\'");
- break;
- case '\"':
- Printf("\\\"");
- break;
- default:
- if (isprint(uc))
- Printf("%c",uc);
- else
- Printf("\\%.3o",uc);
- break;
- }
- Printf("\"");
- if (fsp->full_data_cmnts) {
- lastdelim (more, lastrow);
- annotate (vp, fsp, (size_t *)cor, 0L);
- }
- } else { /* use format from C_format attribute */
- for (iel = 0; iel < len-1; iel++) {
- if (fsp->full_data_cmnts) {
- Printf(fmt, *vals++);
- Printf(", ");
- annotate (vp, fsp, (size_t *)cor, iel);
- } else {
- (void) sprintf(sout, fmt, *vals++);
- (void) strcat(sout, ", ");
- lput(sout);
- }
- }
- if (fsp->full_data_cmnts) {
- Printf(fmt, *vals++);
- lastdelim (more, lastrow);
- annotate (vp, fsp, (size_t *)cor, iel);
- } else {
- (void) sprintf(sout, fmt, *vals++);
- lput(sout);
- }
- }
- if (!fsp->full_data_cmnts) {
- lastdelim2 (more, lastrow);
- }
- }
- /*
- * Print a number of byte variable values, where the optional comments
- * for each value identify the variable, and each dimension index.
- */
- static void
- pr_bvals(
- const ncvar_t *vp, /* variable */
- size_t len, /* number of values to print */
- const char *fmt, /* printf format used for each value. If
- * nc_type is NC_CHAR and this is NULL,
- * character arrays will be printed as
- * strings enclosed in quotes. */
- boolean more, /* true if more data for this row will
- * follow, so add trailing comma */
- boolean lastrow, /* true if this is the last row for this
- * variable, so terminate with ";" instead
- * of "," */
- const signed char *vals, /* pointer to block of values */
- const fspec_t* fsp, /* formatting specs */
- const size_t *cor /* corner coordinates */
- )
- {
- long iel;
- char sout[100]; /* temporary string for each encoded output */
- for (iel = 0; iel < len-1; iel++) {
- printbval(sout, fmt, vp, *vals++);
- if (fsp->full_data_cmnts) {
- Printf(sout);
- Printf(",");
- annotate (vp, fsp, cor, iel);
- } else {
- (void) strcat(sout, ", ");
- lput(sout);
- }
- }
- printbval(sout, fmt, vp, *vals++);
- if (fsp->full_data_cmnts) {
- Printf(sout);
- lastdelim (more, lastrow);
- annotate (vp, fsp, cor, iel);
- } else {
- lput(sout);
- lastdelim2 (more, lastrow);
- }
- }
- /*
- * Print a number of short variable values, where the optional comments
- * for each value identify the variable, and each dimension index.
- */
- static void
- pr_svals(
- const ncvar_t *vp, /* variable */
- size_t len, /* number of values to print */
- const char *fmt, /* printf format used for each value. If
- * nc_type is NC_CHAR and this is NULL,
- * character arrays will be printed as
- * strings enclosed in quotes. */
- boolean more, /* true if more data for this row will
- * follow, so add trailing comma */
- boolean lastrow, /* true if this is the last row for this
- * variable, so terminate with ";" instead
- * of "," */
- const short *vals, /* pointer to block of values */
- const fspec_t* fsp, /* formatting specs */
- const size_t *cor /* corner coordinates */
- )
- {
- long iel;
- char sout[100]; /* temporary string for each encoded output */
- for (iel = 0; iel < len-1; iel++) {
- printsval(sout, fmt, vp, *vals++);
- if (fsp->full_data_cmnts) {
- Printf(sout);
- Printf(",");
- annotate (vp, fsp, cor, iel);
- } else {
- (void) strcat(sout, ", ");
- lput(sout);
- }
- }
- printsval(sout, fmt, vp, *vals++);
- if (fsp->full_data_cmnts) {
- Printf(sout);
- lastdelim (more, lastrow);
- annotate (vp, fsp, cor, iel);
- } else {
- lput(sout);
- lastdelim2 (more, lastrow);
- }
- }
- /*
- * Print a number of int variable values, where the optional comments
- * for each value identify the variable, and each dimension index.
- */
- static void
- pr_ivals(
- const ncvar_t *vp, /* variable */
- size_t len, /* number of values to print */
- const char *fmt, /* printf format used for each value. If
- * nc_type is NC_CHAR and this is NULL,
- * character arrays will be printed as
- * strings enclosed in quotes. */
- boolean more, /* true if more data for this row will
- * follow, so add trailing comma */
- boolean lastrow, /* true if this is the last row for this
- * variable, so terminate with ";" instead
- * of "," */
- const int *vals, /* pointer to block of values */
- const fspec_t* fsp, /* formatting specs */
- const size_t *cor /* corner coordinates */
- )
- {
- long iel;
- char sout[100]; /* temporary string for each encoded output */
- for (iel = 0; iel < len-1; iel++) {
- printival(sout, fmt, vp, *vals++);
- if (fsp->full_data_cmnts) {
- Printf(sout);
- Printf(",");
- annotate (vp, fsp, cor, iel);
- } else {
- (void) strcat(sout, ", ");
- lput(sout);
- }
- }
- printival(sout, fmt, vp, *vals++);
- if (fsp->full_data_cmnts) {
- Printf(sout);
- lastdelim (more, lastrow);
- annotate (vp, fsp, cor, iel);
- } else {
- lput(sout);
- lastdelim2 (more, lastrow);
- }
- }
- /*
- * Print a number of float variable values, where the optional comments
- * for each value identify the variable, and each dimension index.
- */
- static void
- pr_fvals(
- const ncvar_t *vp, /* variable */
- size_t len, /* number of values to print */
- const char *fmt, /* printf format used for each value. If
- * nc_type is NC_CHAR and this is NULL,
- * character arrays will be printed as
- * strings enclosed in quotes. */
- boolean more, /* true if more data for this row will
- * follow, so add trailing comma */
- boolean lastrow, /* true if this is the last row for this
- * variable, so terminate with ";" instead
- * of "," */
- const float *vals, /* pointer to block of values */
- const fspec_t* fsp, /* formatting specs */
- const size_t *cor /* corner coordinates */
- )
- {
- long iel;
- char sout[100]; /* temporary string for each encoded output */
- for (iel = 0; iel < len-1; iel++) {
- printfval(sout, fmt, vp, *vals++);
- if (fsp->full_data_cmnts) {
- Printf(sout);
- Printf(",");
- annotate (vp, fsp, cor, iel);
- } else {
- (void) strcat(sout, ", ");
- lput(sout);
- }
- }
- printfval(sout, fmt, vp, *vals++);
- if (fsp->full_data_cmnts) {
- Printf(sout);
- lastdelim (more, lastrow);
- annotate (vp, fsp, cor, iel);
- } else {
- lput(sout);
- lastdelim2 (more, lastrow);
- }
- }
- /*
- * Print a number of double variable values, where the optional comments
- * for each value identify the variable, and each dimension index.
- */
- static void
- pr_dvals(
- const ncvar_t *vp, /* variable */
- size_t len, /* number of values to print */
- const char *fmt, /* printf format used for each value. If
- * nc_type is NC_CHAR and this is NULL,
- * character arrays will be printed as
- * strings enclosed in quotes. */
- boolean more, /* true if more data for this row will
- * follow, so add trailing comma */
- boolean lastrow, /* true if this is the last row for this
- * variable, so terminate with ";" instead
- * of "," */
- const double *vals, /* pointer to block of values */
- const fspec_t* fsp, /* formatting specs */
- const size_t *cor /* corner coordinates */
- )
- {
- long iel;
- char sout[100]; /* temporary string for each encoded output */
- for (iel = 0; iel < len-1; iel++) {
- printdval(sout, fmt, vp, *vals++);
- if (fsp->full_data_cmnts) {
- Printf(sout);
- Printf(",");
- annotate (vp, fsp, cor, iel);
- } else {
- (void) strcat(sout, ", ");
- lput(sout);
- }
- }
- printdval(sout, fmt, vp, *vals++);
- if (fsp->full_data_cmnts) {
- Printf(sout);
- lastdelim (more, lastrow);
- annotate (vp, fsp, cor, iel);
- } else {
- lput(sout);
- lastdelim2 (more, lastrow);
- }
- }
- /*
- * Updates a vector of ints, odometer style. Returns 0 if odometer
- * overflowed, else 1.
- */
- static int
- upcorner(
- const size_t *dims, /* The "odometer" limits for each dimension */
- int ndims, /* Number of dimensions */
- size_t* odom, /* The "odometer" vector to be updated */
- const size_t* add /* A vector to "add" to odom on each update */
- )
- {
- int id;
- int ret = 1;
- for (id = ndims-1; id > 0; id--) {
- odom[id] += add[id];
- if(odom[id] >= dims[id]) {
- odom[id-1]++;
- odom[id] -= dims[id];
- }
- }
- odom[0] += add[0];
- if (odom[0] >= dims[0])
- ret = 0;
- return ret;
- }
- /* Output the data for a single variable, in CDL syntax. */
- int
- vardata(
- const ncvar_t *vp, /* variable */
- size_t vdims[], /* variable dimension sizes */
- int ncid, /* netcdf id */
- int varid, /* variable id */
- const fspec_t* fsp /* formatting specs */
- )
- {
- size_t cor[NC_MAX_DIMS]; /* corner coordinates */
- size_t edg[NC_MAX_DIMS]; /* edges of hypercube */
- size_t add[NC_MAX_DIMS]; /* "odometer" increment to next "row" */
- #define VALBUFSIZ 1000
- double vals[VALBUFSIZ] ; /* aligned buffer */
- int gulp = VALBUFSIZ;
- int id;
- int ir;
- size_t nels;
- size_t ncols;
- size_t nrows;
- int vrank = vp->ndims;
- static int initeps = 0;
- /* printf format used to print each value */
- const char *fmt = get_fmt(ncid, varid, vp->type);
- if (!initeps) { /* make sure epsilons get initialized */
- init_epsilons();
- initeps = 1;
- }
- nels = 1;
- for (id = 0; id < vrank; id++) {
- cor[id] = 0;
- edg[id] = 1;
- nels *= vdims[id]; /* total number of values for variable */
- }
- if (vrank <= 1) {
- Printf("\n %s = ", vp->name);
- set_indent ((int)strlen(vp->name) + 4);
- } else {
- Printf("\n %s =\n ", vp->name);
- set_indent (2);
- }
- if (vrank < 1) {
- ncols = 1;
- } else {
- ncols = vdims[vrank-1]; /* size of "row" along last dimension */
- edg[vrank-1] = vdims[vrank-1];
- for (id = 0; id < vrank; id++)
- add[id] = 0;
- if (vrank > 1)
- add[vrank-2] = 1;
- }
- nrows = nels/ncols; /* number of "rows" */
-
- for (ir = 0; ir < nrows; ir++) {
- /*
- * rather than just printing a whole row at once (which might exceed
- * the capacity of MSDOS platforms, for example), we break each row
- * into smaller chunks, if necessary.
- */
- size_t corsav;
- int left = (int)ncols;
- boolean lastrow;
- if (vrank > 0) {
- corsav = cor[vrank-1];
- if (fsp->brief_data_cmnts != false
- && vrank > 1
- && left > 0) { /* print brief comment with indices range */
- Printf("// %s(",vp->name);
- switch (fsp->data_lang) {
- case LANG_C:
- /* print brief comment with C variable indices */
- for (id = 0; id < vrank-1; id++)
- Printf("%lu,", (unsigned long)cor[id]);
- if (vdims[vrank-1] == 1)
- Printf("0");
- else
- Printf(" 0-%lu", (unsigned long)vdims[vrank-1]-1);
- break;
- case LANG_F:
- /* print brief comment with Fortran variable indices */
- if (vdims[vrank-1] == 1)
- Printf("1");
- else
- Printf("1-%lu ", (unsigned long)vdims[vrank-1]);
- for (id = vrank-2; id >=0 ; id--) {
- Printf(",%lu", (unsigned long)(1 + cor[id]));
- }
- break;
- }
- Printf(")\n ");
- set_indent(4);
- }
- }
- lastrow = (boolean)(ir == nrows-1);
- while (left > 0) {
- size_t toget = left < gulp ? left : gulp;
- if (vrank > 0)
- edg[vrank-1] = toget;
- switch(vp->type) {
- case NC_CHAR:
- NC_CHECK(
- nc_get_vara_text(ncid, varid, cor, edg, (char *)vals) );
- pr_tvals(vp, toget, fmt, left > toget, lastrow,
- (char *) vals, fsp, cor);
- break;
- case NC_BYTE:
- NC_CHECK(
- nc_get_vara_schar(ncid, varid, cor, edg, (signed char *)vals) );
- pr_bvals(vp, toget, fmt, left > toget, lastrow,
- (signed char *) vals, fsp, cor);
- break;
- case NC_SHORT:
- NC_CHECK(
- nc_get_vara_short(ncid, varid, cor, edg, (short *)vals) );
- pr_svals(vp, toget, fmt, left > toget, lastrow,
- (short *) vals, fsp, cor);
- break;
- case NC_INT:
- NC_CHECK(
- nc_get_vara_int(ncid, varid, cor, edg, (int *)vals) );
- pr_ivals(vp, toget, fmt, left > toget, lastrow,
- (int *) vals, fsp, cor);
- break;
- case NC_FLOAT:
- NC_CHECK(
- nc_get_vara_float(ncid, varid, cor, edg, (float *)vals) );
- pr_fvals(vp, toget, fmt, left > toget, lastrow,
- (float *) vals, fsp, cor);
- break;
- case NC_DOUBLE:
- NC_CHECK(
- nc_get_vara_double(ncid, varid, cor, edg, (double *)vals) );
- pr_dvals(vp, toget, fmt, left > toget, lastrow,
- (double *) vals, fsp, cor);
- break;
- default:
- error("vardata: bad type");
- }
- left -= toget;
- if (vrank > 0)
- cor[vrank-1] += toget;
- }
- if (vrank > 0)
- cor[vrank-1] = corsav;
- if (ir < nrows-1)
- if (!upcorner(vdims,vp->ndims,cor,add))
- error("vardata: odometer overflowed!");
- set_indent(2);
- }
- return 0;
- }
- /*
- * print last delimiter in each line before annotation (, or ;)
- */
- static void
- lastdelim2x (boolean more, boolean lastrow)
- {
- if (more) {
- lput(" ");
- } else {
- if(lastrow) {
- lput("\n ");
- } else {
- lput("\n ");
- }
- }
- }
- /*
- * Print a number of char variable values.
- */
- static void
- pr_tvalsx(
- size_t len, /* number of values to print */
- const char *fmt, /* printf format used for each value. If
- * nc_type is NC_CHAR and this is NULL,
- * character arrays will be printed as
- * strings enclosed in quotes. */
- boolean more, /* true if more data for this row will
- * follow, so add trailing comma */
- boolean 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 fspec_t *fsp /* formatting specs */
- )
- {
- long iel;
- const char *sp;
- unsigned char uc;
- char sout[100]; /* temporary string for each encoded output */
- if (fmt == 0 || STREQ(fmt,"%s") || STREQ(fmt,"")) { /* as string */
- Printf("\"");
- /* adjust len so trailing nulls don't get printed */
- sp = vals + len;
- while (len != 0 && *--sp == '\0')
- len--;
- for (iel = 0; iel < len; iel++)
- switch (uc = *vals++ & 0377) {
- case '\b':
- Printf("\\b");
- break;
- case '\f':
- Printf("\\f");
- break;
- case '\n': /* generate linebreaks after new-lines */
- Printf("\\n\",\n \"");
- break;
- case '\r':
- Printf("\\r");
- break;
- case '\t':
- Printf("\\t");
- break;
- case '\v':
- Printf("\\v");
- break;
- case '\\':
- Printf("\\\\");
- break;
- case '\'':
- Printf("\\\'");
- break;
- case '\"':
- Printf("\\\"");
- break;
- default:
- if (isprint(uc))
- Printf("%c",uc);
- else
- Printf("\\%.3o",uc);
- break;
- }
- Printf("\"");
- } else { /* use format from C_format attribute */
- for (iel = 0; iel < len-1; iel++) {
- (void) sprintf(sout, fmt, *vals++);
- (void) strcat(sout, " ");
- lput(sout);
- }
- (void) sprintf(sout, fmt, *vals++);
- lput(sout);
- }
- if (!fsp->full_data_cmnts) {
- lastdelim2x (more, lastrow);
- }
- }
- /*
- * Print a number of byte variable values.
- */
- static void
- pr_bvalsx(
- const ncvar_t *vp, /* variable */
- size_t len, /* number of values to print */
- const char *fmt, /* printf format used for each value. If
- * nc_type is NC_CHAR and this is NULL,
- * character arrays will be printed as
- * strings enclosed in quotes. */
- boolean more, /* true if more data for this row will
- * follow, so add trailing comma */
- boolean lastrow, /* true if this is the last row for this
- * variable, so terminate with ";" instead
- * of "," */
- const signed char *vals /* pointer to block of values */
- )
- {
- long iel;
- char sout[100]; /* temporary string for each encoded output */
- for (iel = 0; iel < len-1; iel++) {
- printbval(sout, fmt, vp, *vals++);
- (void) strcat(sout, " ");
- lput(sout);
- }
- printbval(sout, fmt, vp, *vals++);
- lput(sout);
- lastdelim2x (more, lastrow);
- }
- /*
- * Print a number of short variable values.
- */
- static void
- pr_svalsx(
- const ncvar_t *vp, /* variable */
- size_t len, /* number of values to print */
- const char *fmt, /* printf format used for each value. If
- * nc_type is NC_CHAR and this is NULL,
- * character arrays will be printed as
- * strings enclosed in quotes. */
- boolean more, /* true if more data for this row will
- * follow, so add trailing comma */
- boolean lastrow, /* true if this is the last row for this
- * variable, so terminate with ";" instead
- * of "," */
- const short *vals /* pointer to block of values */
- )
- {
- long iel;
- char sout[100]; /* temporary string for each encoded output */
- for (iel = 0; iel < len-1; iel++) {
- printsval(sout, fmt, vp, *vals++);
- (void) strcat(sout, " ");
- lput(sout);
- }
- printsval(sout, fmt, vp, *vals++);
- lput(sout);
- lastdelim2x (more, lastrow);
- }
- /*
- * Print a number of int variable values.
- */
- static void
- pr_ivalsx(
- const ncvar_t *vp, /* variable */
- size_t len, /* number of values to print */
- const char *fmt, /* printf format used for each value. If
- * nc_type is NC_CHAR and this is NULL,
- * character arrays will be printed as
- * strings enclosed in quotes. */
- boolean more, /* true if more data for this row will
- * follow, so add trailing comma */
- boolean lastrow, /* true if this is the last row for this
- * variable, so terminate with ";" instead
- * of "," */
- const int *vals /* pointer to block of values */
- )
- {
- long iel;
- char sout[100]; /* temporary string for each encoded output */
- for (iel = 0; iel < len-1; iel++) {
- printival(sout, fmt, vp, *vals++);
- (void) strcat(sout, " ");
- lput(sout);
- }
- printival(sout, fmt, vp, *vals++);
- lput(sout);
- lastdelim2x (more, lastrow);
- }
- /*
- * Print a number of float variable values.
- */
- static void
- pr_fvalsx(
- const ncvar_t *vp, /* variable */
- size_t len, /* number of values to print */
- const char *fmt, /* printf format used for each value. If
- * nc_type is NC_CHAR and this is NULL,
- * character arrays will be printed as
- * strings enclosed in quotes. */
- boolean more, /* true if more data for this row will
- * follow, so add trailing comma */
- boolean lastrow, /* true if this is the last row for this
- * variable, so terminate with ";" instead
- * of "," */
- const float *vals /* pointer to block of values */
- )
- {
- long iel;
- char sout[100]; /* temporary string for each encoded output */
- for (iel = 0; iel < len-1; iel++) {
- printfval(sout, fmt, vp, *vals++);
- (void) strcat(sout, " ");
- lput(sout);
- }
- printfval(sout, fmt, vp, *vals++);
- lput(sout);
- lastdelim2x (more, lastrow);
- }
- /*
- * Print a number of double variable values.
- */
- static void
- pr_dvalsx(
- const ncvar_t *vp, /* variable */
- size_t len, /* number of values to print */
- const char *fmt, /* printf format used for each value. If
- * nc_type is NC_CHAR and this is NULL,
- * character arrays will be printed as
- * strings enclosed in quotes. */
- boolean more, /* true if more data for this row will
- * follow, so add trailing comma */
- boolean lastrow, /* true if this is the last row for this
- * variable, so terminate with ";" instead
- * of "," */
- const double *vals /* pointer to block of values */
- )
- {
- long iel;
- char sout[100]; /* temporary string for each encoded output */
- for (iel = 0; iel < len-1; iel++) {
- printdval(sout, fmt, vp, *vals++);
- (void) strcat(sout, " ");
- lput(sout);
- }
- printdval(sout, fmt, vp, *vals++);
- lput(sout);
- lastdelim2x (more, lastrow);
- }
- /* Output the data for a single variable, in NcML syntax. */
- int
- vardatax(
- const ncvar_t *vp, /* variable */
- size_t vdims[], /* variable dimension sizes */
- int ncid, /* netcdf id */
- int varid, /* variable id */
- const fspec_t *fsp /* formatting specs */
- )
- {
- size_t cor[NC_MAX_DIMS]; /* corner coordinates */
- size_t edg[NC_MAX_DIMS]; /* edges of hypercube */
- size_t add[NC_MAX_DIMS]; /* "odometer" increment to next "row" */
- #define VALBUFSIZ 1000
- double vals[VALBUFSIZ] ; /* aligned buffer */
- int gulp = VALBUFSIZ;
- int id;
- int ir;
- size_t nels;
- size_t ncols;
- size_t nrows;
- int vrank = vp->ndims;
- static int initeps = 0;
- /* printf format used to print each value */
- const char *fmt = get_fmt(ncid, varid, vp->type);
- if (!initeps) { /* make sure epsilons get initialized */
- init_epsilons();
- initeps = 1;
- }
- nels = 1;
- for (id = 0; id < vrank; id++) {
- cor[id] = 0;
- edg[id] = 1;
- nels *= vdims[id]; /* total number of values for variable */
- }
- Printf(" <values>\n ");
- set_indent (7);
- if (vrank < 1) {
- ncols = 1;
- } else {
- ncols = vdims[vrank-1]; /* size of "row" along last dimension */
- edg[vrank-1] = vdims[vrank-1];
- for (id = 0; id < vrank; id++)
- add[id] = 0;
- if (vrank > 1)
- add[vrank-2] = 1;
- }
- nrows = nels/ncols; /* number of "rows" */
-
- for (ir = 0; ir < nrows; ir++) {
- /*
- * rather than just printing a whole row at once (which might exceed
- * the capacity of MSDOS platforms, for example), we break each row
- * into smaller chunks, if necessary.
- */
- size_t corsav;
- int left = (int)ncols;
- boolean lastrow;
- if (vrank > 0) {
- corsav = cor[vrank-1];
- }
- lastrow = (boolean)(ir == nrows-1);
- while (left > 0) {
- size_t toget = left < gulp ? left : gulp;
- if (vrank > 0)
- edg[vrank-1] = toget;
- switch(vp->type) {
- case NC_CHAR:
- NC_CHECK(
- nc_get_vara_text(ncid, varid, cor, edg, (char *)vals) );
- pr_tvalsx(toget, fmt, left > toget, lastrow,
- (char *) vals, fsp);
- break;
- case NC_BYTE:
- NC_CHECK(
- nc_get_vara_schar(ncid, varid, cor, edg, (signed char *)vals) );
- pr_bvalsx(vp, toget, fmt, left > toget, lastrow,
- (signed char *) vals);
- break;
- case NC_SHORT:
- NC_CHECK(
- nc_get_vara_short(ncid, varid, cor, edg, (short *)vals) );
- pr_svalsx(vp, toget, fmt, left > toget, lastrow,
- (short *) vals);
- break;
- case NC_INT:
- NC_CHECK(
- nc_get_vara_int(ncid, varid, cor, edg, (int *)vals) );
- pr_ivalsx(vp, toget, fmt, left > toget, lastrow,
- (int *) vals);
- break;
- case NC_FLOAT:
- NC_CHECK(
- nc_get_vara_float(ncid, varid, cor, edg, (float *)vals) );
- pr_fvalsx(vp, toget, fmt, left > toget, lastrow,
- (float *) vals);
- break;
- case NC_DOUBLE:
- NC_CHECK(
- nc_get_vara_double(ncid, varid, cor, edg, (double *)vals) );
- pr_dvalsx(vp, toget, fmt, left > toget, lastrow,
- (double *) vals);
- break;
- #ifdef USE_NETCDF4
- case NC_UBYTE:
- /* TODO */
- break;
- case NC_USHORT:
- /* TODO */
- break;
- case NC_UINT:
- /* TODO */
- break;
- case NC_INT64:
- /* TODO */
- break;
- case NC_UINT64:
- /* TODO */
- break;
- case NC_STRING:
- /* TODO */
- break;
- case NC_VLEN:
- /* TODO */
- break;
- case NC_OPAQUE:
- /* TODO */
- break;
- case NC_COMPOUND:
- /* TODO */
- break;
- #endif /* USE_NETCDF4 */
- default:
- error("vardata: bad type");
- }
- left -= toget;
- if (vrank > 0)
- cor[vrank-1] += toget;
- }
- if (vrank > 0)
- cor[vrank-1] = corsav;
- if (ir < nrows-1)
- if (!upcorner(vdims,vp->ndims,cor,add))
- error("vardata: odometer overflowed!");
- set_indent(2);
- }
- Printf(" </values>\n");
- return 0;
- }