/* * Print a number of variable values for NcML */ static void pr_any_valsx( const ncvar_t *vp, /* variable */ size_t len, /* number of values to print */ bool_t more, /* true if more data for this row will * follow, so add trailing comma */ bool_t lastrow, /* true if this is the last row for this * variable, so terminate with ";" instead * of "," */ const void *vals /* pointer to block of values */ ) { long iel; safebuf_t *sb = sbuf_new(); const char *valp = (const char *)vals; for (iel = 0; iel < len-1; iel++) { print_any_val(sb, vp, (void *)valp); valp += vp->tinfo->size; /* next value according to type */ sbuf_cat(sb, " "); lput(sbuf_str(sb)); } print_any_val(sb, vp, (void *)valp); lput(sbuf_str(sb)); lastdelim2x (more, lastrow); sbuf_free(sb); }
static void term_out(char *s) { if (term_sbuf) sbuf_str(term_sbuf, s); else write(1, s, strlen(s)); }
void sbuf_printf(struct sbuf *sbuf, char *s, ...) { char buf[256]; va_list ap; va_start(ap, s); vsnprintf(buf, sizeof(buf), s, ap); va_end(ap); sbuf_str(sbuf, buf); }
/* * Print a number of variable values, where the optional comments * for each value identify the variable, and each dimension index. */ static void pr_any_vals( const ncvar_t *vp, /* variable */ size_t len, /* number of values to print */ 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 void *vals, /* pointer to block of values */ const fspec_t* fsp, /* formatting specs */ const size_t *cor /* corner coordinates */ ) { long iel; safebuf_t *sb = sbuf_new(); const char *valp = (const char *)vals; for (iel = 0; iel < len-1; iel++) { print_any_val(sb, vp, (void *)valp); valp += vp->tinfo->size; /* next value according to type */ if (fsp->full_data_cmnts) { printf(sb->buf); printf(","); annotate (vp, fsp, cor, iel); } else { sbuf_cat(sb, ", "); lput(sbuf_str(sb)); } } print_any_val(sb, vp, (void *)valp); valp += vp->tinfo->size; /* next value according to type */ if (fsp->full_data_cmnts) { printf(sbuf_str(sb)); lastdelim (more, lastrow); annotate (vp, fsp, cor, iel); } else { lput(sbuf_str(sb)); lastdelim2 (more, lastrow); } sbuf_free(sb); }
/* * Print a number of attribute values */ void pr_any_att_vals( const ncatt_t *ap, /* attribute */ const void *vals /* pointer to block of values */ ) { size_t iel; size_t len = ap->len; /* number of values to print */ const char *valp = (const char *)vals; safebuf_t *sb = sbuf_new(); for (iel = 0; iel < len - 1; iel++) { print_any_att_val(sb, ap, (void *)valp); valp += ap->tinfo->size; /* next value according to type */ sbuf_cat(sb, iel == len - 1 ? "" : ", "); lput(sbuf_str(sb)); } print_any_att_val(sb, ap, (void *)valp); lput(sbuf_str(sb)); sbuf_free(sb); }
/* Print data values for variable varid. * * Recursive to handle possibility of variables with multiple * unlimited dimensions, for which the CDL syntax requires use of "{" * and "}" in data section to disambiguate the size of nested records * in a simple linear list of values. */ static int print_rows( int level, /* 0 at top-level, incremented for each recursive level */ 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 */ void *vals, /* allocated buffer for ncols values in a row */ int marks_pending /* number of pending closing "}" record markers */ ) { int d0 = 0; size_t inc = 1; int i; bool_t mark_record = (level > 0 && is_unlim_dim(ncid, vp->dims[level])); safebuf_t *sb = sbuf_new(); if (rank > 0) d0 = vdims[level]; for(i = level + 1; i < rank; i++) { inc *= vdims[i]; } if(mark_record) { /* the whole point of this recursion is printing these "{}" */ lput("{"); marks_pending++; /* matching "}"s to emit after last "row" */ } if(rank - level > 1) { /* this level is just d0 next levels */ size_t *local_cor = emalloc((rank + 1) * sizeof(size_t)); size_t *local_edg = emalloc((rank + 1) * sizeof(size_t)); for(i = 0; i < rank; i++) { local_cor[i] = cor[i]; local_edg[i] = edg[i]; } 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, local_cor, local_edg, vals, 0); local_cor[level] += 1; } print_rows(level + 1, ncid, varid, vp, ncols, rank, vdims, local_cor, local_edg, vals, marks_pending); free(local_edg); free(local_cor); } else { /* bottom out of recursion */ char *valp = vals; bool_t lastrow; int j; if(formatting_specs.brief_data_cmnts && rank > 1) { 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)); } } print_any_val(sb, vp, (void *)valp); /* determine if this is the last row */ lastrow = true; for(j = 0; j < rank - 1; j++) { if (cor[j] != vdims[j] - 1) { lastrow = false; break; } } if (formatting_specs.full_data_cmnts) { for (j = 0; j < marks_pending; j++) { sbuf_cat(sb, "}"); } printf("%s", sbuf_str(sb)); lastdelim (0, lastrow); annotate (vp, cor, i); } else { for (j = 0; j < marks_pending; j++) { sbuf_cat(sb, "}"); } lput(sbuf_str(sb)); lastdelim2 (0, lastrow); } } sbuf_free(sb); return NC_NOERR; }