Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

vardata.c

Go to the documentation of this file.
00001 /*********************************************************************
00002  *   Copyright 1993, UCAR/Unidata
00003  *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
00004  *   $Header: /misc/elrond0/share/cvs/AFNI/src/netcdf-3.5.0/src/ncdump/vardata.c,v 1.5 2004/04/02 15:12:42 rwcox Exp $
00005  *********************************************************************/
00006 
00007 #include <stdio.h>
00008 #include <ctype.h>
00009 #include <stdlib.h>
00010 #include <string.h>
00011 #ifndef NO_FLOAT_H
00012 #include <float.h>              /* for FLT_EPSILON, DBL_EPSILON */
00013 #endif /* NO_FLOAT_H */
00014 
00015 #include <netcdf.h>
00016 #include "ncdump.h"
00017 #include "dumplib.h"
00018 #include "vardata.h"
00019 
00020 static float float_epsilon(void);
00021 static double double_epsilon(void);
00022 static void init_epsilons(void);
00023 static void printbval(char* sout, const char* fmt, const struct ncvar* varp,
00024                       signed char val);
00025 static void printsval(char* sout, const char* fmt, const struct ncvar* varp,
00026                       short val);
00027 static void printival(char* sout, const char* fmt, const struct ncvar* varp,
00028                       int val);
00029 static void printfval(char* sout, const char* fmt, const struct ncvar* varp,
00030                       float val);
00031 static void printdval(char* sout, const char* fmt, const struct ncvar* varp,
00032                       double val);
00033 static void lastdelim(boolean  more, boolean lastrow);
00034 static void annotate(const struct ncvar* vp, const struct fspec* fsp,
00035                      const size_t* cor, long iel);
00036 static void pr_tvals(const struct ncvar *vp, size_t len, const char *fmt,
00037                      boolean more, boolean lastrow, const char *vals,
00038                      const struct fspec* fsp, const size_t *cor);
00039 static void pr_bvals(const struct ncvar *vp, size_t len, const char *fmt,
00040                      boolean more, boolean lastrow, const signed char *vals,
00041                      const struct fspec* fsp, const size_t *cor);
00042 static void pr_svals(const struct ncvar *vp, size_t len, const char *fmt,
00043                      boolean more, boolean lastrow, const short *vals,
00044                      const struct fspec* fsp, const size_t *cor);
00045 static void pr_ivals(const struct ncvar *vp, size_t len, const char *fmt,
00046                      boolean more, boolean lastrow, const int *vals,
00047                      const struct fspec* fsp, const size_t *cor);
00048 static void pr_fvals(const struct ncvar *vp, size_t len, const char *fmt,
00049                      boolean more, boolean lastrow, const float *vals,
00050                      const struct fspec* fsp, const size_t *cor);
00051 static void pr_dvals(const struct ncvar *vp, size_t len, const char *fmt,
00052                      boolean more, boolean lastrow, const double *vals,
00053                      const struct fspec* fsp, const size_t *cor);
00054 static int  upcorner(const size_t* dims, int ndims, size_t* odom,
00055                      const size_t* add);
00056 static void lastdelim2 (boolean more, boolean lastrow);
00057 
00058 #define STREQ(a, b)     (*(a) == *(b) && strcmp((a), (b)) == 0)
00059 
00060 static float float_eps;
00061 static double double_eps;
00062 
00063 static float
00064 float_epsilon(void)
00065 {
00066     float float_eps;
00067 #ifndef NO_FLOAT_H
00068     float_eps = FLT_EPSILON;
00069 #else /* NO_FLOAT_H */
00070     {
00071         float etop, ebot, eps;
00072         float one = 1.0;
00073         float two = 2.0;
00074         etop = 1.0;
00075         ebot = 0.0;
00076         eps = ebot + (etop - ebot)/two;
00077         while (eps != ebot && eps != etop) {
00078             float epsp1;
00079 
00080             epsp1 = one + eps;
00081             if (epsp1 > one)
00082                 etop = eps;
00083             else
00084                 ebot = eps;
00085             eps = ebot + (etop - ebot)/two;
00086         }
00087         float_eps = two * etop;
00088     }
00089 #endif /* NO_FLOAT_H */
00090     return float_eps;
00091 }
00092 
00093 
00094 static double
00095 double_epsilon(void)
00096 {
00097     double double_eps;
00098 #ifndef NO_FLOAT_H
00099     double_eps = DBL_EPSILON;
00100 #else /* NO_FLOAT_H */
00101     {
00102         double etop, ebot, eps;
00103         double one = 1.0;
00104         double two = 2.0;
00105         etop = 1.0;
00106         ebot = 0.0;
00107         eps = ebot + (etop - ebot)/two;
00108         while (eps != ebot && eps != etop) {
00109             double epsp1;
00110 
00111             epsp1 = one + eps;
00112             if (epsp1 > one)
00113                 etop = eps;
00114             else
00115                 ebot = eps;
00116             eps = ebot + (etop - ebot)/two;
00117         }
00118         double_eps = two * etop;
00119     }
00120 #endif /* NO_FLOAT_H */
00121     return double_eps;
00122 }
00123 
00124 
00125 static void
00126 init_epsilons(void)
00127 {
00128     float_eps = float_epsilon();
00129     double_eps = double_epsilon();
00130 }
00131 
00132 /*
00133  * Output a value of a byte variable, except if there is a fill value for
00134  * the variable and the value is the fill value, print the fill-value string
00135  * instead.
00136  */
00137 static void
00138 printbval(
00139     char *sout,                 /* string where output goes */
00140     const char *fmt,            /* printf format used for value */
00141     const struct ncvar *varp,   /* variable */
00142     signed char val             /* value */
00143     )
00144 {
00145     if (varp->has_fillval) {
00146         double fillval = varp->fillval;
00147         if(fillval == val) {
00148             (void) sprintf(sout, FILL_STRING);
00149             return;
00150         }
00151     }
00152     (void) sprintf(sout, fmt, val);
00153 }
00154 
00155 /*
00156  * Output a value of a short variable, except if there is a fill value for
00157  * the variable and the value is the fill value, print the fill-value string
00158  * instead.
00159  */
00160 static void
00161 printsval(
00162     char *sout,                 /* string where output goes */
00163     const char *fmt,            /* printf format used for value */
00164     const struct ncvar *varp,           /* variable */
00165     short val                   /* value */
00166     )
00167 {
00168     if (varp->has_fillval) {
00169         double fillval = varp->fillval;
00170         if(fillval == val) {
00171             (void) sprintf(sout, FILL_STRING);
00172             return;
00173         }
00174     }
00175     (void) sprintf(sout, fmt, val);
00176 }
00177 
00178 
00179 /*
00180  * Output a value of an int variable, except if there is a fill value for
00181  * the variable and the value is the fill value, print the fill-value string
00182  * instead.
00183  */
00184 static void
00185 printival(
00186     char *sout,                 /* string where output goes */
00187     const char *fmt,            /* printf format used for value */
00188     const struct ncvar *varp,           /* variable */
00189     int val                     /* value */
00190     )
00191 {
00192     if (varp->has_fillval) {
00193         int fillval = (int)varp->fillval;
00194         if(fillval == val) {
00195             (void) sprintf(sout, FILL_STRING);
00196             return;
00197         }
00198     }
00199     (void) sprintf(sout, fmt, val);
00200 }
00201 
00202 
00203 #define absval(x)  ( (x) < 0 ? -(x) : (x) )
00204 
00205 /*
00206  * Output a value of a float variable, except if there is a fill value for
00207  * the variable and the value is the fill value, print the fill-value string
00208  * instead.  Floating-point fill values need only be within machine epsilon of
00209  * defined fill value.
00210  */
00211 static void
00212 printfval(
00213     char *sout,                 /* string where output goes */
00214     const char *fmt,            /* printf format used for value */
00215     const struct ncvar *varp,           /* variable */
00216     float val                   /* value */
00217     )
00218 {
00219     if(varp->has_fillval) {
00220         double fillval = varp->fillval;
00221         if((val > 0) == (fillval > 0) && /* prevents potential overflow */
00222            (absval(val - fillval) <= absval(float_eps * fillval))) {
00223             (void) sprintf(sout, FILL_STRING);
00224             return;
00225         }
00226     }
00227     (void) sprintf(sout, fmt, val);
00228 }
00229 
00230 
00231 /*
00232  * Output a value of a double variable, except if there is a fill value for
00233  * the variable and the value is the fill value, print the fill-value string
00234  * instead.  Floating-point fill values need only be within machine epsilon of
00235  * defined fill value.
00236  */
00237 static void
00238 printdval(
00239     char *sout,                 /* string where output goes */
00240     const char *fmt,            /* printf format used for value */
00241     const struct ncvar *varp,           /* variable */
00242     double val                  /* value */
00243     )
00244 {
00245     if(varp->has_fillval) {
00246         double fillval = varp->fillval;
00247         if((val > 0) == (fillval > 0) && /* prevents potential overflow */
00248            (absval(val - fillval) <= absval(double_eps * fillval))) {
00249             (void) sprintf(sout, FILL_STRING);
00250             return;
00251         }
00252     }
00253     (void) sprintf(sout, fmt, val);
00254 }
00255 
00256 
00257 /*
00258  * print last delimiter in each line before annotation (, or ;)
00259  */
00260 static void
00261 lastdelim (boolean more, boolean lastrow)
00262 {
00263     if (more) {
00264         Printf(", ");
00265     } else {
00266         if(lastrow) {
00267             Printf(";");
00268         } else {
00269             Printf(",");
00270         }
00271     }
00272 }
00273 
00274 /*
00275  * print last delimiter in each line before annotation (, or ;)
00276  */
00277 static void
00278 lastdelim2 (boolean more, boolean lastrow)
00279 {
00280     if (more) {
00281         lput(", ");
00282     } else {
00283         if(lastrow) {
00284             lput(" ;");
00285             lput("\n");
00286         } else {
00287             lput(",\n");
00288             lput("  ");
00289         }
00290     }
00291 }
00292 
00293 
00294 /*
00295  * Annotates a value in data section with var name and indices in comment
00296  */
00297 static void
00298 annotate(
00299      const struct ncvar *vp,    /* variable */
00300      const struct fspec* fsp,   /* formatting specs */
00301      const size_t *cor,         /* corner coordinates */
00302      long iel                   /* which element in current row */
00303      )
00304 {
00305     int vrank = vp->ndims;
00306     int id;
00307     
00308     /* print indices according to data_lang */
00309     (void) printf("  // %s(", vp->name);
00310     switch (fsp->data_lang) {
00311       case LANG_C:
00312         /* C variable indices */
00313         for (id = 0; id < vrank-1; id++)
00314           Printf("%lu,", (unsigned long) cor[id]);
00315         Printf("%lu", (unsigned long) cor[id] + iel);
00316         break;
00317       case LANG_F:
00318         /* Fortran variable indices */
00319         Printf("%lu", (unsigned long) cor[vrank-1] + iel + 1);
00320         for (id = vrank-2; id >=0 ; id--) {
00321             Printf(",%lu", 1 + (unsigned long) cor[id]);
00322         }
00323         break;
00324     }
00325     Printf(")\n    ");
00326 }
00327 
00328 
00329 /*
00330  * Print a number of char variable values, where the optional comments
00331  * for each value identify the variable, and each dimension index.
00332  */
00333 static void
00334 pr_tvals(
00335      const struct ncvar *vp,            /* variable */
00336      size_t len,                /* number of values to print */
00337      const char *fmt,           /* printf format used for each value.  If
00338                                  * nc_type is NC_CHAR and this is NULL,
00339                                  * character arrays will be printed as
00340                                  * strings enclosed in quotes.  */
00341      boolean more,              /* true if more data for this row will
00342                                  * follow, so add trailing comma */
00343      boolean lastrow,           /* true if this is the last row for this
00344                                  * variable, so terminate with ";" instead
00345                                  * of "," */
00346      const char *vals,          /* pointer to block of values */
00347      const struct fspec* fsp,   /* formatting specs */
00348      const size_t *cor          /* corner coordinates */
00349      )
00350 {
00351     long iel;
00352     const char *sp;
00353     unsigned char uc;
00354     char sout[100];             /* temporary string for each encoded output */
00355 
00356     if (fmt == 0 || STREQ(fmt,"%s") || STREQ(fmt,"")) { /* as string */
00357         Printf("\"");
00358         /* adjust len so trailing nulls don't get printed */
00359         sp = vals + len;
00360         while (len != 0 && *--sp == '\0')
00361             len--;
00362         for (iel = 0; iel < len; iel++)
00363             switch (uc = *vals++ & 0377) {
00364             case '\b':
00365                 Printf("\\b");
00366                 break;
00367             case '\f':
00368                 Printf("\\f");
00369                 break;
00370             case '\n':  /* generate linebreaks after new-lines */
00371                 Printf("\\n\",\n    \"");
00372                 break;
00373             case '\r':
00374                 Printf("\\r");
00375                 break;
00376             case '\t':
00377                 Printf("\\t");
00378                 break;
00379             case '\v':
00380                 Printf("\\v");
00381                 break;
00382             case '\\':
00383                 Printf("\\\\");
00384                 break;
00385             case '\'':
00386                 Printf("\\\'");
00387                 break;
00388             case '\"':
00389                 Printf("\\\"");
00390                 break;
00391             default:
00392                 if (isprint(uc))
00393                     Printf("%c",uc);
00394                 else
00395                     Printf("\\%.3o",uc);
00396                 break;
00397             }
00398         Printf("\"");
00399         if (fsp->full_data_cmnts) {
00400             Printf("\"");
00401             lastdelim (more, lastrow);
00402             annotate (vp, fsp,  (size_t *)cor, 0L);
00403         }
00404     } else {            /* use format from C_format attribute */
00405         for (iel = 0; iel < len-1; iel++) {
00406             if (fsp->full_data_cmnts) {
00407                 Printf(fmt, *vals++);
00408                 Printf(", ");
00409                 annotate (vp, fsp,  (size_t *)cor, iel);
00410             } else {
00411                 (void) sprintf(sout, fmt, *vals++);
00412                 (void) strcat(sout, ", ");
00413                 lput(sout);
00414             }
00415         }
00416         if (fsp->full_data_cmnts) {
00417             Printf(fmt, *vals++);
00418             lastdelim (more, lastrow);
00419             annotate (vp, fsp,  (size_t *)cor, iel);
00420         } else {
00421             (void) sprintf(sout, fmt, *vals++);
00422             lput(sout);
00423         }
00424     }
00425     if (!fsp->full_data_cmnts) {
00426         lastdelim2 (more, lastrow);
00427     }
00428 }
00429 
00430 
00431 /*
00432  * Print a number of byte variable values, where the optional comments
00433  * for each value identify the variable, and each dimension index.
00434  */
00435 static void
00436 pr_bvals(
00437      const struct ncvar *vp,    /* variable */
00438      size_t len,                /* number of values to print */
00439      const char *fmt,           /* printf format used for each value.  If
00440                                  * nc_type is NC_CHAR and this is NULL,
00441                                  * character arrays will be printed as
00442                                  * strings enclosed in quotes.  */
00443      boolean more,              /* true if more data for this row will
00444                                  * follow, so add trailing comma */
00445      boolean lastrow,           /* true if this is the last row for this
00446                                  * variable, so terminate with ";" instead
00447                                  * of "," */
00448      const signed char *vals,   /* pointer to block of values */
00449      const struct fspec* fsp,   /* formatting specs */
00450      const size_t *cor          /* corner coordinates */
00451      )
00452 {
00453     long iel;
00454     char sout[100];             /* temporary string for each encoded output */
00455 
00456     for (iel = 0; iel < len-1; iel++) {
00457         printbval(sout, fmt, vp, *vals++);
00458         if (fsp->full_data_cmnts) {
00459             Printf(sout);
00460             Printf(",");
00461             annotate (vp, fsp, cor, iel);
00462         } else {
00463             (void) strcat(sout, ", ");
00464             lput(sout);
00465         }
00466     }
00467     printbval(sout, fmt, vp, *vals++);
00468     if (fsp->full_data_cmnts) {
00469         Printf(sout);
00470         lastdelim (more, lastrow);
00471         annotate (vp, fsp, cor, iel);
00472     } else {
00473         lput(sout);
00474         lastdelim2 (more, lastrow);
00475     }
00476 }
00477 
00478 
00479 /*
00480  * Print a number of short variable values, where the optional comments
00481  * for each value identify the variable, and each dimension index.
00482  */
00483 static void
00484 pr_svals(
00485      const struct ncvar *vp,            /* variable */
00486      size_t len,                /* number of values to print */
00487      const char *fmt,           /* printf format used for each value.  If
00488                                  * nc_type is NC_CHAR and this is NULL,
00489                                  * character arrays will be printed as
00490                                  * strings enclosed in quotes.  */
00491      boolean more,              /* true if more data for this row will
00492                                  * follow, so add trailing comma */
00493      boolean lastrow,           /* true if this is the last row for this
00494                                  * variable, so terminate with ";" instead
00495                                  * of "," */
00496      const short *vals,         /* pointer to block of values */
00497      const struct fspec* fsp,   /* formatting specs */
00498      const size_t *cor          /* corner coordinates */
00499      )
00500 {
00501     long iel;
00502     char sout[100];             /* temporary string for each encoded output */
00503 
00504     for (iel = 0; iel < len-1; iel++) {
00505         printsval(sout, fmt, vp, *vals++);
00506         if (fsp->full_data_cmnts) {
00507             Printf(sout);
00508             Printf(",");
00509             annotate (vp, fsp, cor, iel);
00510         } else {
00511             (void) strcat(sout, ", ");
00512             lput(sout);
00513         }
00514     }
00515     printsval(sout, fmt, vp, *vals++);
00516     if (fsp->full_data_cmnts) {
00517         Printf(sout);
00518         lastdelim (more, lastrow);
00519         annotate (vp, fsp, cor, iel);
00520     } else {
00521         lput(sout);
00522         lastdelim2 (more, lastrow);
00523     }
00524 }
00525 
00526 
00527 
00528 
00529 /*
00530  * Print a number of int variable values, where the optional comments
00531  * for each value identify the variable, and each dimension index.
00532  */
00533 static void
00534 pr_ivals(
00535      const struct ncvar *vp,            /* variable */
00536      size_t len,                /* number of values to print */
00537      const char *fmt,           /* printf format used for each value.  If
00538                                  * nc_type is NC_CHAR and this is NULL,
00539                                  * character arrays will be printed as
00540                                  * strings enclosed in quotes.  */
00541      boolean more,              /* true if more data for this row will
00542                                  * follow, so add trailing comma */
00543      boolean lastrow,           /* true if this is the last row for this
00544                                  * variable, so terminate with ";" instead
00545                                  * of "," */
00546      const int *vals,           /* pointer to block of values */
00547      const struct fspec* fsp,   /* formatting specs */
00548      const size_t *cor          /* corner coordinates */
00549      )
00550 {
00551     long iel;
00552     char sout[100];             /* temporary string for each encoded output */
00553 
00554     for (iel = 0; iel < len-1; iel++) {
00555         printival(sout, fmt, vp, *vals++);
00556         if (fsp->full_data_cmnts) {
00557             Printf(sout);
00558             Printf(",");
00559             annotate (vp, fsp, cor, iel);
00560         } else {
00561             (void) strcat(sout, ", ");
00562             lput(sout);
00563         }
00564     }
00565     printival(sout, fmt, vp, *vals++);
00566     if (fsp->full_data_cmnts) {
00567         Printf(sout);
00568         lastdelim (more, lastrow);
00569         annotate (vp, fsp, cor, iel);
00570     } else {
00571         lput(sout);
00572         lastdelim2 (more, lastrow);
00573     }
00574 }
00575 
00576 
00577 /*
00578  * Print a number of float variable values, where the optional comments
00579  * for each value identify the variable, and each dimension index.
00580  */
00581 static void
00582 pr_fvals(
00583      const struct ncvar *vp,            /* variable */
00584      size_t len,                        /* number of values to print */
00585      const char *fmt,           /* printf format used for each value.  If
00586                                  * nc_type is NC_CHAR and this is NULL,
00587                                  * character arrays will be printed as
00588                                  * strings enclosed in quotes.  */
00589      boolean more,              /* true if more data for this row will
00590                                  * follow, so add trailing comma */
00591      boolean lastrow,           /* true if this is the last row for this
00592                                  * variable, so terminate with ";" instead
00593                                  * of "," */
00594      const float *vals,         /* pointer to block of values */
00595      const struct fspec* fsp,   /* formatting specs */
00596      const size_t *cor          /* corner coordinates */
00597      )
00598 {
00599     long iel;
00600     char sout[100];             /* temporary string for each encoded output */
00601 
00602     for (iel = 0; iel < len-1; iel++) {
00603         printfval(sout, fmt, vp, *vals++);
00604         if (fsp->full_data_cmnts) {
00605             Printf(sout);
00606             Printf(",");
00607             annotate (vp, fsp, cor, iel);
00608         } else {
00609             (void) strcat(sout, ", ");
00610             lput(sout);
00611         }
00612     }
00613     printfval(sout, fmt, vp, *vals++);
00614     if (fsp->full_data_cmnts) {
00615         Printf(sout);
00616         lastdelim (more, lastrow);
00617         annotate (vp, fsp, cor, iel);
00618     } else {
00619         lput(sout);
00620         lastdelim2 (more, lastrow);
00621     }
00622 }
00623 
00624 
00625 /*
00626  * Print a number of double variable values, where the optional comments
00627  * for each value identify the variable, and each dimension index.
00628  */
00629 static void
00630 pr_dvals(
00631      const struct ncvar *vp,            /* variable */
00632      size_t len,                        /* number of values to print */
00633      const char *fmt,           /* printf format used for each value.  If
00634                                  * nc_type is NC_CHAR and this is NULL,
00635                                  * character arrays will be printed as
00636                                  * strings enclosed in quotes.  */
00637      boolean more,              /* true if more data for this row will
00638                                  * follow, so add trailing comma */
00639      boolean lastrow,           /* true if this is the last row for this
00640                                  * variable, so terminate with ";" instead
00641                                  * of "," */
00642      const double *vals,        /* pointer to block of values */
00643      const struct fspec* fsp,   /* formatting specs */
00644      const size_t *cor          /* corner coordinates */
00645      )
00646 {
00647     long iel;
00648     char sout[100];             /* temporary string for each encoded output */
00649 
00650     for (iel = 0; iel < len-1; iel++) {
00651         printdval(sout, fmt, vp, *vals++);
00652         if (fsp->full_data_cmnts) {
00653             Printf(sout);
00654             Printf(",");
00655             annotate (vp, fsp, cor, iel);
00656         } else {
00657             (void) strcat(sout, ", ");
00658             lput(sout);
00659         }
00660     }
00661     printdval(sout, fmt, vp, *vals++);
00662     if (fsp->full_data_cmnts) {
00663         Printf(sout);
00664         lastdelim (more, lastrow);
00665         annotate (vp, fsp, cor, iel);
00666     } else {
00667         lput(sout);
00668         lastdelim2 (more, lastrow);
00669     }
00670 }
00671 
00672 
00673 /*
00674  * Updates a vector of ints, odometer style.  Returns 0 if odometer
00675  * overflowed, else 1.
00676  */
00677 static int
00678 upcorner(
00679      const size_t *dims,        /* The "odometer" limits for each dimension */
00680      int ndims,                 /* Number of dimensions */
00681      size_t* odom,              /* The "odometer" vector to be updated */
00682      const size_t* add          /* A vector to "add" to odom on each update */
00683      )
00684 {
00685     int id;
00686     int ret = 1;
00687 
00688     for (id = ndims-1; id > 0; id--) {
00689         odom[id] += add[id];
00690         if(odom[id] >= dims[id]) {
00691             odom[id-1]++;
00692             odom[id] -= dims[id];
00693         }
00694     }
00695     odom[0] += add[0];
00696     if (odom[0] >= dims[0])
00697       ret = 0;
00698     return ret;
00699 }
00700 
00701 
00702 /* Output the data for a single variable, in CDL syntax. */
00703 int
00704 vardata(
00705      const struct ncvar *vp,    /* variable */
00706      size_t vdims[],            /* variable dimension sizes */
00707      int ncid,                  /* netcdf id */
00708      int varid,                 /* variable id */
00709      const struct fspec* fsp    /* formatting specs */
00710      )
00711 {
00712     size_t cor[NC_MAX_DIMS];    /* corner coordinates */
00713     size_t edg[NC_MAX_DIMS];    /* edges of hypercube */
00714     size_t add[NC_MAX_DIMS];    /* "odometer" increment to next "row"  */
00715 #define VALBUFSIZ 1000
00716     double vals[VALBUFSIZ] ; /* aligned buffer */
00717 
00718     int gulp = VALBUFSIZ;
00719 
00720     int id;
00721     int ir;
00722     size_t nels;
00723     size_t ncols;
00724     size_t nrows;
00725     int vrank = vp->ndims;
00726     static int initeps = 0;
00727 
00728     /* printf format used to print each value */
00729     char *fmt = get_fmt(ncid, varid, vp->type);
00730 
00731     if (!initeps) {             /* make sure epsilons get initialized */
00732         init_epsilons();
00733         initeps = 1;
00734     }
00735 
00736     nels = 1;
00737     for (id = 0; id < vrank; id++) {
00738         cor[id] = 0;
00739         edg[id] = 1;
00740         nels *= vdims[id];      /* total number of values for variable */
00741     }
00742 
00743     if (vrank <= 1) {
00744         Printf("\n %s = ", vp->name);
00745         set_indent ((int)strlen(vp->name) + 4);
00746     } else {
00747         Printf("\n %s =\n  ", vp->name);
00748         set_indent (2);
00749     }
00750 
00751     if (vrank < 1) {
00752         ncols = 1;
00753     } else {
00754         ncols = vdims[vrank-1]; /* size of "row" along last dimension */
00755         edg[vrank-1] = vdims[vrank-1];
00756         for (id = 0; id < vrank; id++)
00757           add[id] = 0;
00758         if (vrank > 1)
00759           add[vrank-2] = 1;
00760     }
00761     nrows = nels/ncols;         /* number of "rows" */
00762     
00763     for (ir = 0; ir < nrows; ir++) {
00764         /*
00765          * rather than just printing a whole row at once (which might exceed
00766          * the capacity of MSDOS platforms, for example), we break each row
00767          * into smaller chunks, if necessary.
00768          */
00769         size_t corsav;
00770         int left = (int)ncols;
00771         boolean lastrow;
00772 
00773         if (vrank > 0) {
00774             corsav = cor[vrank-1];
00775             if (fsp->brief_data_cmnts != false
00776                 && vrank > 1
00777                 && left > 0) {  /* print brief comment with indices range */
00778                 Printf("// %s(",vp->name);
00779                 switch (fsp->data_lang) {
00780                   case LANG_C:
00781                     /* print brief comment with C variable indices */
00782                     for (id = 0; id < vrank-1; id++)
00783                       Printf("%lu,", (unsigned long)cor[id]);
00784                     if (vdims[vrank-1] == 1)
00785                       Printf("0");
00786                     else
00787                       Printf(" 0-%lu", (unsigned long)vdims[vrank-1]-1);
00788                     break;
00789                   case LANG_F:
00790                     /* print brief comment with Fortran variable indices */
00791                     if (vdims[vrank-1] == 1)
00792                       Printf("1");
00793                     else
00794                       Printf("1-%lu ", (unsigned long)vdims[vrank-1]);
00795                     for (id = vrank-2; id >=0 ; id--) {
00796                         Printf(",%lu", (unsigned long)(1 + cor[id]));
00797                     }
00798                     break;
00799                 }
00800                 Printf(")\n    ");
00801                 set_indent(4);
00802             }
00803         }
00804         lastrow = (boolean)(ir == nrows-1);
00805         while (left > 0) {
00806             size_t toget = left < gulp ? left : gulp;
00807             if (vrank > 0)
00808               edg[vrank-1] = toget;
00809             switch(vp->type) {
00810             case NC_CHAR:
00811                 NC_CHECK(
00812                     nc_get_vara_text(ncid, varid, cor, edg, (char *)vals) );
00813                 pr_tvals(vp, toget, fmt, left > toget, lastrow,
00814                          (char *) vals, fsp, cor);
00815                 break;
00816             case NC_BYTE:
00817                 NC_CHECK(
00818                     nc_get_vara_schar(ncid, varid, cor, edg, (signed char *)vals) );
00819                 pr_bvals(vp, toget, fmt, left > toget, lastrow,
00820                          (signed char *) vals, fsp, cor);
00821                 break;
00822             case NC_SHORT:
00823                 NC_CHECK(
00824                     nc_get_vara_short(ncid, varid, cor, edg, (short *)vals) );
00825                 pr_svals(vp, toget, fmt, left > toget, lastrow,
00826                          (short *) vals, fsp, cor);
00827                 break;
00828             case NC_INT:
00829                 NC_CHECK(
00830                     nc_get_vara_int(ncid, varid, cor, edg, (int *)vals) );
00831                 pr_ivals(vp, toget, fmt, left > toget, lastrow,
00832                          (int *) vals, fsp, cor);
00833                 break;
00834             case NC_FLOAT:
00835                 NC_CHECK(
00836                     nc_get_vara_float(ncid, varid, cor, edg, (float *)vals) );
00837                 pr_fvals(vp, toget, fmt, left > toget, lastrow,
00838                          (float *) vals, fsp, cor);
00839                 break;
00840             case NC_DOUBLE:
00841                 NC_CHECK(
00842                     nc_get_vara_double(ncid, varid, cor, edg, (double *)vals) );
00843                 pr_dvals(vp, toget, fmt, left > toget, lastrow,
00844                          (double *) vals, fsp, cor);
00845                 break;
00846             default:
00847                 error("vardata: bad type");
00848             }
00849             left -= toget;
00850             if (vrank > 0)
00851               cor[vrank-1] += toget;
00852         }
00853         if (vrank > 0)
00854           cor[vrank-1] = corsav;
00855         if (ir < nrows-1)
00856           if (!upcorner(vdims,vp->ndims,cor,add))
00857             error("vardata: odometer overflowed!");
00858         set_indent(2);
00859     }
00860 
00861     return 0;
00862 }
 

Powered by Plone

This site conforms to the following standards: