1 /*********************************************************************
2  *   Copyright 1993, University Corporation for Atmospheric Research
3  *   See netcdf/README file for copying and redistribution conditions.
4  *   $Id$
5  *********************************************************************/
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 
11 #ifndef NO_STDARG
12 #include <stdarg.h>
13 #else
14 #include <varargs.h>
15 #endif
16 
17 #include"h4config.h"
18 #ifdef H4_HAVE_NETCDF
19 #include "netcdf.h"
20 #else
21 #include "hdf4_netcdf.h"
22 #endif
23 
24 #include "dumplib.h"
25 
26 /*
27  * Print error message to stderr, don't exit
28  */
29 #ifndef NO_STDARG
30 void
error(const char * fmt,...)31 error(const char *fmt, ...)
32 #else
33 /*VARARGS1*/
34 void
35 error(fmt, va_alist)
36      const char *fmt ;
37      va_dcl
38 #endif
39 {
40     va_list args ;
41 
42     (void) fprintf(stderr,"*** %s: ", progname);
43 
44 #ifndef NO_STDARG
45     va_start(args, fmt) ;
46 #else
47     va_start(args) ;
48 #endif
49     (void) vfprintf(stderr,fmt,args) ;
50     va_end(args) ;
51 
52     (void) fprintf(stderr, "\n") ;
53     (void) fflush(stderr);	/* to ensure log files are current */
54 }
55 
56 #define LINEPIND	"    "	/* indent of continued lines */
57 
58 static int linep;
59 static int max_line_len;
60 
61 void
set_indent(in)62 set_indent(in)
63      int in;
64 {
65     linep = in;
66 }
67 
68 
69 void
set_max_len(len)70 set_max_len(len)
71      int len;
72 {
73     max_line_len = len-2;
74 }
75 
76 
77 void
lput(cp)78 lput(cp)
79      const char *cp;
80 {
81     int nn = strlen(cp);
82 
83     if (nn+linep > max_line_len && nn > 2) {
84 	(void) fputs("\n", stdout);
85 	(void) fputs(LINEPIND, stdout);
86 	linep = strlen(LINEPIND);
87     }
88     (void) fputs(cp,stdout);
89     linep += nn;
90 }
91 
92 
93 static char *formats[] =
94 {
95     "%d",			/* bytes, shorts */
96     "%s",			/* char arrays as strings */
97     "%ld",			/* longs */
98     "%.7g ",			/* floats */
99     "%.15g"			/* doubles */
100 };
101 
102 
103 /* In case different formats specified with -d option, set them here. */
104 void
set_formats(flt,dbl)105 set_formats(flt, dbl)
106      char *flt;
107      char *dbl;
108 {
109     strcpy(formats[3], flt);
110     strcpy(formats[4], dbl);
111 }
112 
113 
114 static char *
has_c_format_att(ncid,varid)115 has_c_format_att(ncid, varid)
116     int ncid;			/* netcdf id */
117     int varid;			/* variable id */
118 {
119     nc_type cfmt_type;
120     int cfmt_len;
121     int savopts;
122 #define C_FMT_NAME	"C_format" /* name of C format attribute */
123 #define	MAX_CFMT_LEN	100	/* max length of C format attribute */
124     static char cfmt[MAX_CFMT_LEN];
125 
126     /*
127      * turn off error handling, we expect ncattinq to fail if there is no
128      * C_format attribute
129      */
130     savopts = ncopts;
131     ncopts = 0;
132     if (ncattinq(ncid, varid, "C_format", &cfmt_type, &cfmt_len) != -1) {
133 	ncopts = savopts;	/* restore error handling */
134 	if (cfmt_type == NC_CHAR && cfmt_len > 0 && cfmt_len < MAX_CFMT_LEN) {
135 	    if (ncattget(ncid, varid, "C_format", (void *)cfmt) != -1)
136 	      return &cfmt[0];
137 	}
138     }
139     ncopts = savopts;		/* restore error handling */
140     return 0;
141 }
142 
143 
144 /*
145  * Determine print format to use for each value for this variable.  Use value
146  * of attribute C_format if it exists, otherwise a sensible default.
147  */
148 const char *
get_fmt(ncid,varid,type)149 get_fmt(ncid, varid, type)
150      int ncid;			/* netcdf id */
151      int varid;			/* variable id */
152      nc_type type;		/* netCDF data type */
153 {
154     char *c_format_att = has_c_format_att(ncid, varid);
155 
156     /* If C_format attribute exists, return it */
157     if (c_format_att)
158       return c_format_att;
159 
160     /* Otherwise return sensible default. */
161     switch (type) {
162       case NC_BYTE:
163 	return formats[0];
164       case NC_CHAR:
165 	return formats[1];
166       case NC_SHORT:
167 	return formats[0];
168       case NC_LONG:
169  	return formats[2];
170       case NC_FLOAT:
171 	return formats[3];
172       case NC_DOUBLE:
173 	return formats[4];
174       default:
175 	error("pr_vals: bad type");
176     return NULL;
177     }
178 }
179 
180 
181 static vnode*
newvnode()182 newvnode()
183 {
184     vnode *newvp = (vnode*) malloc(sizeof(vnode));
185 
186     if (!newvp) {
187 	error("out of memory!");
188 	exit(EXIT_FAILURE);
189     }
190     return newvp;
191 }
192 
193 
194 vnode*
newvlist()195 newvlist()
196 {
197     vnode *vp = newvnode();
198 
199     vp -> next = 0;
200     vp -> id = -1;		/* bad id */
201 
202     return vp;
203 }
204 
205 
206 void
varadd(vlist,varid)207 varadd(vlist, varid)
208      vnode* vlist;
209      int varid;
210 {
211     vnode *newvp = newvnode();
212 
213     newvp -> next = vlist -> next;
214     newvp -> id = varid;
215     vlist -> next = newvp;
216 }
217 
218 
219 int
varmember(vlist,varid)220 varmember(vlist, varid)
221      vnode* vlist;
222      int varid;
223 {
224     vnode *vp = vlist -> next;
225 
226     for (; vp ; vp = vp->next)
227       if (vp->id == varid)
228 	return 1;
229     return 0;
230 }
231 
232