1 /* Copyright (C) 1992-1998 The Geometry Center
2 * Copyright (C) 1998-2000 Stuart Levy, Tamara Munzner, Mark Phillips
3 *
4 * This file is part of Geomview.
5 *
6 * Geomview is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * Geomview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with Geomview; see the file COPYING. If not, write
18 * to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
19 * USA, or visit http://www.gnu.org.
20 */
21
22
23 /* Authors: Charlie Gunn, Stuart Levy, Tamara Munzner, Mark Phillips */
24
25 #ifndef OOGLUTILDEF
26 #define OOGLUTILDEF
27
28 #include <stdio.h>
29 #include <string.h>
30
31 #include "iobuffer.h"
32
33 #ifdef _WIN32
34 # define M_PI 3.14159265358979323
35 extern int finite(double v);
36 extern int strcasecmp(char *s1, char *s2);
37 #endif
38
39
40 /*
41 * Definition so that (obsolete Irix 3) SGIs won't barf on member function prototypes.
42 */
43 #ifdef no_prototypes
44 #define P(foo) ()
45 #else
46 #define P(foo) foo
47 #endif
48
49
50 #define COUNT(array) (int)(sizeof(array)/sizeof(array[0]))
51
52 /*
53 * Public definitions for miscellaneous useful OOGL internal stuff.
54 */
55
56 #define OOGLMagic(key, vers) (0x9c800000 | (((key)&0x7f)<<16) | ((vers)&0xffff) )
57 #define OOGLIsMagic(magic) (((magic) & 0xff800000) == 0x9c800000)
58
59 /*
60 * Memory allocation
61 */
62 #ifndef OOG_NewP
63 extern void *(*OOG_NewP)(size_t);
64 #endif
65 #ifndef OOG_RenewP
66 extern void *(*OOG_RenewP)(void *, size_t);
67 #endif
68
69 #ifndef OOGLFree
70 extern void (*OOGLFree)(void *);
71 #endif
72 #ifndef OOG_NewE
73 extern void *OOG_NewE(int, char *);
74 #endif
75 #ifndef OOG_RenewE
76 extern void *OOG_RenewE(void *, int, char *);
77 #endif
78
_OOGLNew(size_t size)79 static inline void *_OOGLNew(size_t size)
80 {
81 return OOG_NewP(size);
82 }
_OOGLRenew(void * p,size_t size)83 static inline void *_OOGLRenew(void *p, size_t size)
84 {
85 return OOG_RenewP(p, size);
86 }
87 #define OOGLNew(t) (t *)_OOGLNew(sizeof(t))
88 #define OOGLNewN(t,N) (t *)_OOGLNew(sizeof(t)*(N))
89 #define OOGLRenewN(t,p,N) (t *)_OOGLRenew(p, sizeof(t)*(N))
90 #define OOGLRealloc(t,p) (t *)_OOGLRenew(p, sizeof(t))
91
92 #define OOGLNewE(t, errmsg) (t *)OOG_NewE(sizeof(t), errmsg)
93 #define OOGLNewNE(t,N, errmsg) (t *)OOG_NewE(sizeof(t)*(N), errmsg)
94 #define OOGLRenewNE(t,p,N, errmsg) (t *)OOG_RenewE(p, sizeof(t)*(N), errmsg)
95
96 /*
97 * Backward compatibility
98 */
99 #define GeomNew(t) OOGLNew(t)
100 #define GeomNewN(t,N) OOGLNewN(t,N)
101 #define GeomFree(p) OOGLFree(p)
102 #define GeomError OOGLError
103
104 /*
105 * Error handling
106 */
107 extern char *_GFILE; /* Name of file where error is found */
108 extern int _GLINE; /* Line number in file where error is found */
109 extern int OOGL_Errorcode; /* Unique integer error code */
110 extern void OOGLWarn (char *fmt, ...);
111 extern const char *sperrno(unsigned int);
112 extern const char *sperror(void);
113
114 /* Kludge for obtaining file name and line number of error: */
115 #define OOGLError (_GFILE= __FILE__, _GLINE=__LINE__,0)?0:_OOGLError
116
117 extern int _OOGLError(int, char *fmt, ...);
118
119 extern void OOGLSyntax(IOBFILE *, char *fmt, ...);
120
121 /* Bit fields in error codes */
122 #define OE_VERBOSE 0x1
123 #define OE_FATAL 0x2
124
125 /*
126 * Variable-sized arrays ("vectors"). Manipulates variables of type "vvec".
127 * Maintains the data they point to, but doesn't allocate the vvec's themselves;
128 * typical use might be
129 * vvec myvec;
130 * VVINIT(myvec, float, 10);
131 * while( ... ) {
132 * *VVAPPEND(myvec, float) = something;
133 * }
134 * for(i = 0; i < VVSIZE(myvec); i++)
135 * ... VVEC(myvec, float)[i] ...
136 *
137 */
138 typedef struct vvec {
139 char *base; /* The real data */
140 int count; /* Number of elements in use (indices 0..count-1) */
141 int allocated; /* Number of elements allocated */
142 int elsize; /* sizeof(element type) */
143 char dozero; /* Zero-fill all new elements */
144 char malloced; /* "base" has been malloced */
145 char spare1, spare2; /* for future extensions */
146 } vvec;
147
148 #include <vvec.h> /* inline vv-functions */
149
150 /*
151 * Macros take 'vvec' arguments, while functions take addresses of vvec's.
152 * VVINIT() : initialize new empty array; first malloc will grab >= 'minelems'.
153 * VVZERO() : request that all newly allocated elements be cleared to zeros
154 * VVINDEX() : return address of index'th element, ensuring that it exists.
155 * VVAPPEND() : increments array size, returning address of new last element
156 * VVEC() : returns address of array base; VVEC()[i] is the i'th element
157 * assuming that its existence was ensured by earlier call to
158 * VVAPPEND() or VVINDEX() or vvneeds().
159 * VVCOUNT() : number of valid elements in array. Maintained by user.
160 */
161 #define VVINIT(vv,type,minelems) vvinit(&(vv), sizeof(type), minelems)
162 #define VVEC(vv, type) ((type *)((vv).base))
163 #define VVCOUNT(vv) (vv).count
164 #define VVINDEX(vv,type,index) ((type *)vvindex(&(vv), (index)))
165 #define VVAPPEND(vv, type) VVINDEX(vv, type, (vv).count++)
166
167 /* Functions take addresses of vvec's. Besides the above, there are
168 * vvtrim() : trim allocated but unused space (beyond VVCOUNT()'th element).
169 * vvfree() : free malloced array.
170 * vvneeds(): ensure that at least this many elements are allocated
171 * vvzero() : all newly allocated elements will be filled with binary zeros
172 * vvuse() : Use the given non-malloced buffer until more room is needed;
173 * call vvuse() after vvinit() but before allocating anything.
174 * vvcopy() : copies one vvec into another, allocating space in the
175 * destination to accommodate the data and copying everything.
176 */
177 static inline void vvinit(vvec *v, int elsize, int minelems);
178 static inline void vvuse(vvec *v, void *buf, int allocated);
179 static inline void vvtrim(vvec *v); /* Trim allocated but unused data */
180 static inline void vvfree(vvec *v); /* Free all malloced data */
181 static inline void vvneeds(vvec *v, int needed);
182 static inline void *vvindex(vvec *v, int index);
183 static inline void vvzero(vvec *v);
184 static inline void vvcopy(vvec *src, vvec *dest);
185
186 /*
187 * File-I/O utility routines
188 */
189 /*
190 * int iobfnextc(IOBFILE *f, int flags)
191 * Advances f to the next "interesting" character and
192 * returns it. The returned char is ungetc'ed so the next getc()
193 * will yield the same value.
194 * Interesting depends on flags:
195 * 0 : Skip blanks, tabs, newlines, and comments (#...\n).
196 * 1 : Skip blanks, tabs, and comments, but newlines are interesting
197 * (including the \n that terminates a comment).
198 * 2 : Skip blanks, tabs, and newlines, but stop at #.
199 * 3 : Skip blanks and tabs but stop at # or \n.
200 *
201 * int
202 * iobfexpectstr(IOBFILE *file, char *string)
203 * Expect the given string to appear immediately on file.
204 * Return 0 if the complete string is found,
205 * else the offset+1 of the last matched char within string.
206 * The first unmatched char is ungetc'd.
207 *
208 * int
209 * iobfexpecttoken(IOBFILE *file, char *string)
210 * Expect the given string to appear on the file, possibly after
211 * skipping some white space and comments.
212 * Return 0 if found, else the offset+1 of last matched char in string.
213 * The first unmatched char is ungetc'd.
214 *
215 * char *iobftoken(IOBFILE *f, int flags)
216 * Skips uninteresting characters with fnextc(f, flags),
217 * then returns a "token" - string of consecutive interesting characters.
218 * Returns NULL if EOF is reached with no token, or if
219 * flags specifies stopping at end-of-line and this is encountered with
220 * no token found.
221 * The token is effectively statically allocated and will be
222 * overwritten by the next ftoken() call.
223 *
224 * int iobfgetnd(file, ndouble, doublep, binary)
225 * Read an array of doubles from a file in "ascii" or "binary" format.
226 * Returns number of doubles successfully read, should = nfloats.
227 * "Binary" means "Bit-Endian IEEE 64-bit floating-point" format.
228 *
229 * int iobfgetnf(file, nfloats, floatp, binary)
230 * Read an array of floats from a file in "ascii" or "binary" format.
231 * Returns number of floats successfully read, should = nfloats.
232 * "Binary" means "Big-Endian IEEE 32-bit floating-point" format.
233 *
234 * int iobfgetni(IOBFILE *file, int nints, int *intsp, int binary)
235 * Read an array of ints from a file in "ascii" or "binary" format.
236 * Returns number of ints successfully read, should = nints.
237 * "Binary" means "32-bit big-endian" integer format.
238 *
239 * int iobfgetns(IOBFILE *file, int nshorts, short *intsp, int binary)
240 * Read an array of shorts from a file in "ascii" or "binary" format.
241 * Returns number of shorts successfully read, should = nints.
242 * "Binary" means "16-bit big-endian" integer format.
243 *
244 * int iobfgettransform(IOBFILE *f,
245 * int ntransforms, float *transforms, int binary)
246 * Reads 4x4 matrices from IOBFILE. Returns the number of matrices found,
247 * up to ntransforms. Returns 0 if no numbers are found.
248 * On finding incomplete matrices (not a multiple of 16 floats)
249 * returns -1, regardless of whether any whole matrices were found.
250 * In ASCII (binary==0) mode, matrices are read in conventional order
251 * which is the transpose of the internal form. Binary mode reads
252 * 32-bit IEEE floats in internal order.
253 *
254 * int fputtransform(FILE *f, int ntransforms, float *transforms, int binary)
255 * Writes 4x4 matrices to FILE. Returns the number written, i.e.
256 * ntransforms unless an error occurs. See fgettransform() for format.
257 *
258 */
259
260 #define NODATA -2 /* async_fnextc() and async_getc() return NODATA if
261 * none is immediately available
262 */
263
264 extern int async_iobfgetc(IOBFILE *f);
265 extern int async_iobfnextc(IOBFILE *f, int flags);
266 extern char *iobfcontext(IOBFILE *f);
267 extern char *iobftoken(IOBFILE *iobf, int flags);
268 extern char *iobfquotetoken(IOBFILE *iobf, int flags, int *quote);
269 extern char *
270 iobfquotedelimtok(const char *delims, IOBFILE *iobf, int flags, int *quote);
271 extern char *iobfdelimtok(const char *delims, IOBFILE *iobf, int flags);
272 extern int iobfescape(IOBFILE *f);
273 extern int iobfexpectstr(IOBFILE *iobf, char *str);
274 extern int iobfexpecttoken(IOBFILE *iobf, char *str);
275 extern int iobfgetnd(IOBFILE *f, int maxd, double *dv, int binary);
276 extern int iobfgetnf(IOBFILE *f, int maxf, float *fv, int binary);
277 extern int iobfgetni(IOBFILE *f, int maxi, int *iv, int binary);
278 extern int iobfgetns(IOBFILE *f, int maxs, short *sv, int binary);
279 extern int iobfgettransform(IOBFILE *iobf, int ntrans, float *trans, int bin);
280 extern int iobfhasdata(IOBFILE *f);
281 extern int iobfnextc(IOBFILE *f, int flags);
282
283 extern char *fdelimtok(const char *delims, FILE *f, int flags);
284 extern int fescape(FILE *f);
285 extern int fexpectstr(FILE *f, char *str);
286 extern int fexpecttoken(FILE *f, char *str);
287 extern int fgetnd(FILE *f, int maxd, double *dv, int binary);
288 extern int fgetnf(FILE *f, int maxf, float *fv, int binary);
289 extern int fgetni(FILE *f, int maxi, int *iv, int binary);
290 extern int fgetns(FILE *f, int maxs, short *sv, int binary);
291 extern int fgettransform(FILE *f, int ntrans, float *trans, int bin);
292 extern int fnextc(FILE *f, int flags);
293 extern char *ftoken(FILE *f, int flags);
294 extern int fputnf(FILE *, int nfloats, float *floatp, int binary);
295 extern int fputtransform(FILE *, int ntrans, float *transforms, int binary);
296
297 extern char *findfile(char *superfile, char *file);
298 extern void filedirs(char *dirs[]);
299 extern char **getfiledirs();
300 char *envexpand(char *s);
301
302 extern char **ooglglob(char *s);
303 extern void ooglblkfree(char **av0);
304
305 /* gettimeofday, where WHEN may be NULL */
306 struct timeval *timeof(struct timeval *when);
307 /* Add offset to base, yielding result */
308 void addtime(struct timeval *result, struct timeval *base, double offset);
309 /* Time in second since base */
310 double timeoffset(struct timeval *base, struct timeval *when);
311
312 /*
313 * macro for grabbing the next value from either a region of
314 * memory or a va_list.
315 * al should be the address of the va_list
316 * p should be the address of a poiner to the region of memory,
317 * or NULL, which means use the va_list instead.
318 */
319 #define OOGL_VA_ARG(type,al,p) (p ? ((type*)((*p)+=sizeof(type)))[-1] \
320 : (va_arg (*al, type)))
321
322
323 #include "porting.h"
324
325
326 #endif
327