00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <stdarg.h>
00012 #include <stdio.h>
00013 #include <stdlib.h>
00014 #include <string.h>
00015
00016 #include "netcdf.h"
00017 #include "dumplib.h"
00018 #include "ncdump.h"
00019
00020 static char* has_c_format_att(int ncid, int varid);
00021 static vnode* newvnode(void);
00022
00023 int float_precision_specified = 0;
00024 int double_precision_specified = 0;
00025 char float_var_fmt[] = "%.NNg";
00026 char double_var_fmt[] = "%.NNg";
00027 char float_att_fmt[] = "%#.NNgf";
00028 char double_att_fmt[] = "%#.NNg";
00029
00030
00031
00032
00033 void
00034 error(const char *fmt, ...)
00035 {
00036 va_list args ;
00037
00038 (void) fprintf(stderr,"%s: ", progname);
00039 va_start(args, fmt) ;
00040 (void) vfprintf(stderr,fmt,args) ;
00041 va_end(args) ;
00042
00043 (void) fprintf(stderr, "\n") ;
00044 (void) fflush(stderr);
00045 exit(EXIT_FAILURE);
00046 }
00047
00048 void *
00049 emalloc (
00050 size_t size)
00051 {
00052 void *p;
00053
00054 p = (void *) malloc (size);
00055 if (p == 0) {
00056 error ("out of memory\n");
00057 }
00058 return p;
00059 }
00060
00061 #define LINEPIND " "
00062
00063 static int linep;
00064 static int max_line_len;
00065
00066 void
00067 set_indent(int in)
00068 {
00069 linep = in;
00070 }
00071
00072
00073 void
00074 set_max_len(int len)
00075 {
00076 max_line_len = len-2;
00077 }
00078
00079
00080 void
00081 lput(const char *cp)
00082 {
00083 size_t nn = strlen(cp);
00084
00085 if (nn+linep > max_line_len && nn > 2) {
00086 (void) fputs("\n", stdout);
00087 (void) fputs(LINEPIND, stdout);
00088 linep = (int)strlen(LINEPIND);
00089 }
00090 (void) fputs(cp,stdout);
00091 linep += nn;
00092 }
00093
00094
00095 void
00096 set_formats(int float_digits, int double_digits)
00097 {
00098 (void) sprintf(float_var_fmt, "%%.%dg", float_digits);
00099 (void) sprintf(double_var_fmt, "%%.%dg", double_digits);
00100 (void) sprintf(float_att_fmt, "%%#.%dgf", float_digits);
00101 (void) sprintf(double_att_fmt, "%%#.%dg", double_digits);
00102 }
00103
00104
00105 static char *
00106 has_c_format_att(
00107 int ncid,
00108 int varid
00109 )
00110 {
00111 nc_type cfmt_type;
00112 size_t cfmt_len;
00113 #define C_FMT_NAME "C_format"
00114 #define MAX_CFMT_LEN 100
00115 static char cfmt[MAX_CFMT_LEN];
00116
00117
00118 int nc_stat = nc_inq_att(ncid, varid, "C_format", &cfmt_type, &cfmt_len);
00119
00120 switch(nc_stat) {
00121 case NC_NOERR:
00122 if (cfmt_type == NC_CHAR && cfmt_len != 0 && cfmt_len < MAX_CFMT_LEN) {
00123 int nc_stat = nc_get_att_text(ncid, varid, "C_format", cfmt);
00124 if(nc_stat != NC_NOERR) {
00125 fprintf(stderr, "Getting 'C_format' attribute %s\n",
00126 nc_strerror(nc_stat));
00127 (void) fflush(stderr);
00128 }
00129 return &cfmt[0];
00130 }
00131 break;
00132 case NC_ENOTATT:
00133 break;
00134 default:
00135 fprintf(stderr, "Inquiring about 'C_format' attribute %s\n",
00136 nc_strerror(nc_stat));
00137 (void) fflush(stderr);
00138 break;
00139 }
00140 return 0;
00141 }
00142
00143
00144
00145
00146
00147
00148 const char *
00149 get_fmt(
00150 int ncid,
00151 int varid,
00152 nc_type type
00153 )
00154 {
00155 char *c_format_att;
00156
00157
00158
00159
00160 if (float_precision_specified && type == NC_FLOAT)
00161 return float_var_fmt;
00162
00163 if (double_precision_specified && type == NC_DOUBLE)
00164 return double_var_fmt;
00165
00166
00167 c_format_att = has_c_format_att(ncid, varid);
00168 if (c_format_att)
00169 return c_format_att;
00170
00171
00172 switch (type) {
00173 case NC_BYTE:
00174 return "%d";
00175 case NC_CHAR:
00176 return "%s";
00177 case NC_SHORT:
00178 return "%d";
00179 case NC_INT:
00180 return "%d";
00181 case NC_FLOAT:
00182 return float_var_fmt;
00183 case NC_DOUBLE:
00184 return double_var_fmt;
00185 default:
00186 error("pr_vals: bad type");
00187 }
00188
00189 return 0;
00190 }
00191
00192
00193 static vnode*
00194 newvnode(void)
00195 {
00196 vnode *newvp = (vnode*) emalloc(sizeof(vnode));
00197 return newvp;
00198 }
00199
00200
00201
00202
00203
00204 vnode*
00205 newvlist(void)
00206 {
00207 vnode *vp = newvnode();
00208
00209 vp -> next = 0;
00210 vp -> id = -1;
00211
00212 return vp;
00213 }
00214
00215
00216 void
00217 varadd(vnode* vlist, int varid)
00218 {
00219 vnode *newvp = newvnode();
00220
00221 newvp -> next = vlist -> next;
00222 newvp -> id = varid;
00223 vlist -> next = newvp;
00224 }
00225
00226
00227
00228
00229
00230
00231 int
00232 varmember(const vnode* vlist, int varid)
00233 {
00234 vnode *vp = vlist -> next;
00235
00236 for (; vp ; vp = vp->next)
00237 if (vp->id == varid)
00238 return 1;
00239 return 0;
00240 }
00241
00242
00243
00244
00245
00246
00247 int
00248 iscoordvar(int ncid, int varid)
00249 {
00250 int ndims;
00251 int dimid;
00252 ncdim_t *dims;
00253 int is_coord = 0;
00254 char varname[NC_MAX_NAME];
00255 int varndims;
00256
00257 NC_CHECK( nc_inq_ndims(ncid, &ndims) );
00258 dims = (ncdim_t *) emalloc((ndims + 1) * sizeof(ncdim_t));
00259 for (dimid = 0; dimid < ndims; dimid++) {
00260 NC_CHECK( nc_inq_dimname(ncid, dimid, dims[dimid].name) );
00261 }
00262 NC_CHECK( nc_inq_varname(ncid, varid, varname) );
00263 NC_CHECK( nc_inq_varndims(ncid, varid, &varndims) );
00264
00265 for (dimid = 0; dimid < ndims; dimid++) {
00266 if (strcmp(dims[dimid].name, varname) == 0 && varndims == 1) {
00267 is_coord = 1;
00268 break;
00269 }
00270 }
00271 free(dims);
00272 return is_coord;
00273 }
00274
00275
00276
00277
00278
00279
00280 int
00281 isrecvar(int ncid, int varid)
00282 {
00283 int recdimid;
00284 int ndims;
00285 int is_recvar = 0;
00286 int *dimids;
00287
00288 NC_CHECK( nc_inq_unlimdim(ncid, &recdimid) );
00289 NC_CHECK( nc_inq_varndims(ncid, varid, &ndims) );
00290 if (ndims > 0) {
00291 dimids = (int *) emalloc((ndims + 1) * sizeof(int));
00292 NC_CHECK( nc_inq_vardimid(ncid, varid, dimids) );
00293
00294 if(dimids[0] == recdimid)
00295 is_recvar = 1;
00296 free(dimids);
00297 }
00298 return is_recvar;
00299 }