iceWing
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
tools.h
Go to the documentation of this file.
1 /* -*- mode: C; tab-width: 4; c-basic-offset: 4; -*- */
2 
3 /*
4  * Author: Frank Loemker
5  *
6  * Copyright (C) 1999-2009
7  * Frank Loemker, Applied Computer Science, Faculty of Technology,
8  * Bielefeld University, Germany
9  *
10  * This file is part of iceWing, a graphical plugin shell.
11  *
12  * iceWing is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * iceWing is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25  */
26 
27 #ifndef iw_tools_H
28 #define iw_tools_H
29 
30 #include <sys/types.h>
31 #include <limits.h>
32 #include <glib.h>
33 
34 #ifndef HAVE_UCHAR
35 #if defined(__linux__) || defined(__sun) || defined(__APPLE__)
36 typedef unsigned char uchar;
37 #endif
38 #endif
39 
40 extern char *ICEWING_NAME; /* == "iceWing" */
41 extern char *ICEWING_VERSION; /* iceWing version string */
42 #define ICEWING_NAME_D "iceWing"
43 
44 /* Should the time measurement be performed ? */
45 #define IW_TIME_MESSURE
46 
47 /*
48 #if (defined __alpha) || (defined __sun)
49 #ifndef __GNUC__
50 #define __FUNCTION__ __FILE__
51 #endif
52 #endif
53 */
54 #define __FUNCTION__ __FILE__
55 
56 #ifndef HAVE_BOOL
57 typedef int BOOL;
58 #endif
59 
60 #ifndef TRUE
61 #define FALSE 0
62 #define TRUE 1
63 #endif
64 
65 #ifndef true
66 #define false FALSE
67 #define true TRUE
68 #endif
69 
70 #if !defined(PATH_MAX) && defined(_POSIX_PATH_MAX)
71 #define PATH_MAX _POSIX_PATH_MAX
72 #endif
73 #ifndef PATH_MAX
74 #define PATH_MAX 256
75 #endif
76 
77 /* Return the difference in ms between the timeval's t1 and t2 */
78 #define IW_TIME_DIFF(t1,t2) (((t1).tv_sec-(t2).tv_sec) * 1000 \
79  + ((t1).tv_usec - (t2).tv_usec) / 1000)
80 
81 #undef MIN
82 #define MIN(a, b) ((a) < (b) ? (a) : (b))
83 
84 #undef MAX
85 #define MAX(a, b) ((a) > (b) ? (a) : (b))
86 
87 #undef CLAMP
88 #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
89 
90 #ifndef G_PI
91 #define G_PI 3.14159265358979323846 /* Somehow in the wrong file ... */
92 #endif
93 #ifndef G_PI_2
94 #define G_PI_2 1.57079632679489661923
95 #endif
96 #ifndef G_PI_4
97 #define G_PI_4 0.78539816339744830962
98 #endif
99 #ifndef G_GINT64_FORMAT
100 #define G_GINT64_FORMAT "li"
101 #define GINT64_PRINTTYPE long
102 #else
103 #define GINT64_PRINTTYPE gint64
104 #endif
105 
106 /* Indicator for "no number given" for optional options in parse_args() */
107 #define IW_ARG_NO_NUMBER ((void*)G_MININT)
108 
109 #ifdef __cplusplus
110 extern "C" {
111 #endif
112 
113 #define iw_error_1(a1) iw_error_x (__FUNCTION__,__LINE__,a1)
114 #define iw_error_2(a1,a2) iw_error_x (__FUNCTION__,__LINE__,a1,a2)
115 #define iw_error_3(a1,a2,a3) iw_error_x (__FUNCTION__,__LINE__,a1,a2,a3)
116 #define iw_error_4(a1,a2,a3,a4) iw_error_x (__FUNCTION__,__LINE__,a1,a2,a3,a4)
117 #define iw_error_5(a1,a2,a3,a4,a5) iw_error_x (__FUNCTION__,__LINE__,a1,a2,a3,a4,a5)
118 #define iw_error_6(a1,a2,a3,a4,a5,a6) iw_error_x (__FUNCTION__,__LINE__,a1,a2,a3,a4,a5,a6)
119 #define iw_warning_1(a1) iw_warning_x (__FUNCTION__,__LINE__,a1)
120 #define iw_warning_2(a1,a2) iw_warning_x (__FUNCTION__,__LINE__,a1,a2)
121 #define iw_warning_3(a1,a2,a3) iw_warning_x (__FUNCTION__,__LINE__,a1,a2,a3)
122 #define iw_warning_4(a1,a2,a3,a4) iw_warning_x (__FUNCTION__,__LINE__,a1,a2,a3,a4)
123 #define iw_warning_5(a1,a2,a3,a4,a5) iw_warning_x (__FUNCTION__,__LINE__,a1,a2,a3,a4,a5)
124 #define iw_warning_6(a1,a2,a3,a4,a5,a6) iw_warning_x (__FUNCTION__,__LINE__,a1,a2,a3,a4,a5,a6)
125 
126 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
127 # define iw_error(...) iw_error_x (__FUNCTION__,__LINE__,__VA_ARGS__)
128 # define iw_warning(...) iw_warning_x (__FUNCTION__,__LINE__,__VA_ARGS__)
129 # define iw_error_errno(...) iw_error_errno_x (__FUNCTION__,__LINE__,__VA_ARGS__)
130 # define iw_warning_errno(...) iw_warning_errno_x (__FUNCTION__,__LINE__,__VA_ARGS__)
131 #elif defined(__GNUC__)
132 # define iw_error(format...) iw_error_x (__FUNCTION__,__LINE__,format)
133 # define iw_warning(format...) iw_warning_x (__FUNCTION__,__LINE__,format)
134 # define iw_error_errno(format...) iw_error_errno_x (__FUNCTION__,__LINE__,format)
135 # define iw_warning_errno(format...) iw_warning_errno_x (__FUNCTION__,__LINE__,format)
136 #else
137 void iw_error (const char* str, ...);
138 void iw_warning (const char* str, ...);
139 void iw_error_errno (const char* str, ...);
140 void iw_warning_errno (const char* str, ...);
141 #endif
142 
143 #ifdef IW_DEBUG
144 
145 # define iw_debug_1(t,a1) iw_debug_x (t,__FUNCTION__,__LINE__,a1)
146 # define iw_debug_2(t,a1,a2) iw_debug_x (t,__FUNCTION__,__LINE__,a1,a2)
147 # define iw_debug_3(t,a1,a2,a3) iw_debug_x (t,__FUNCTION__,__LINE__,a1,a2,a3)
148 # define iw_debug_4(t,a1,a2,a3,a4) iw_debug_x (t,__FUNCTION__,__LINE__,a1,a2,a3,a4)
149 # define iw_debug_5(t,a1,a2,a3,a4,a5) iw_debug_x (t,__FUNCTION__,__LINE__,a1,a2,a3,a4,a5)
150 # define iw_debug_6(t,a1,a2,a3,a4,a5,a6) iw_debug_x (t,__FUNCTION__,__LINE__,a1,a2,a3,a4,a5,a6)
151 # define iw_debug_7(t,a1,a2,a3,a4,a5,a6,a7) \
152  iw_debug_x (t,__FUNCTION__,__LINE__,a1,a2,a3,a4,a5,a6,a7)
153 # define iw_debug_8(t,a1,a2,a3,a4,a5,a6,a7,a8) \
154  iw_debug_x (t,__FUNCTION__,__LINE__,a1,a2,a3,a4,a5,a6,a7,a8)
155 # define iw_debug_9(t,a1,a2,a3,a4,a5,a6,a7,a8,a9) \
156  iw_debug_x (t,__FUNCTION__,__LINE__,a1,a2,a3,a4,a5,a6,a7,a8,a9)
157 # define iw_debug_10(t,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) \
158  iw_debug_x (t,__FUNCTION__,__LINE__,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
159 # define iw_assert_1(ex,a1) ((ex) ? (void)0 : iw_error_1(a1))
160 # define iw_assert_2(ex,a1,a2) ((ex) ? (void)0 : iw_error_2(a1,a2))
161 # define iw_assert_3(ex,a1,a2,a3) ((ex) ? (void)0 : iw_error_3(a1,a2,a3))
162 # define iw_assert_4(ex,a1,a2,a3,a4) ((ex) ? (void)0 : iw_error_4(a1,a2,a3,a4))
163 # define iw_assert_5(ex,a1,a2,a3,a4,a5) ((ex) ? (void)0 : iw_error_5(a1,a2,a3,a4,a5))
164 
165 # if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
166 # define iw_debug(t,...) iw_debug_x (t,__FUNCTION__,__LINE__,__VA_ARGS__)
167 # define iw_assert(ex,...) ((ex) ? (void)0 : iw_error(__VA_ARGS__))
168 # elif defined(__GNUC__)
169 # define iw_debug(t,format...) iw_debug_x (t,__FUNCTION__,__LINE__,format)
170 # define iw_assert(ex,format...) ((ex) ? (void)0 : iw_error(format))
171 # else
172 void iw_debug (int level, const char* str, ...);
173 void iw_assert (long expression, const char* str, ...);
174 # endif
175 
176 #else
177 
178 # define iw_debug_1(t,a1)
179 # define iw_debug_2(t,a1,a2)
180 # define iw_debug_3(t,a1,a2,a3)
181 # define iw_debug_4(t,a1,a2,a3,a4)
182 # define iw_debug_5(t,a1,a2,a3,a4,a5)
183 # define iw_debug_6(t,a1,a2,a3,a4,a5,a6)
184 # define iw_debug_7(t,a1,a2,a3,a4,a5,a6,a7)
185 # define iw_debug_8(t,a1,a2,a3,a4,a5,a6,a7,a8)
186 # define iw_debug_9(t,a1,a2,a3,a4,a5,a6,a7,a8,a9)
187 # define iw_debug_10(t,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
188 # define iw_assert_1(ex,a1)
189 # define iw_assert_2(ex,a1,a2)
190 # define iw_assert_3(ex,a1,a2,a3)
191 # define iw_assert_4(ex,a1,a2,a3,a4)
192 # define iw_assert_5(ex,a1,a2,a3,a4,a5)
193 
194 # if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
195 # define iw_debug(t,...)
196 # define iw_assert(ex,...)
197 # elif defined(__GNUC__)
198 # define iw_debug(t,format...)
199 # define iw_assert(ex,format...)
200 # else
201 static inline void iw_debug (int level, const char* str, ...) {}
202 static inline void iw_assert (long expression, const char* str, ...) {}
203 # endif
204 
205 #endif /* IW_DEBUG */
206 
207 /*********************************************************************
208  Call malloc() / calloc() / realloc().
209  If err!=NULL and memory could not be allocated, exit with
210  'out of memory: "err"' by calling iw_error().
211 *********************************************************************/
212 void* iw_malloc (size_t size, const char *err);
213 void* iw_malloc0 (size_t size, const char *err);
214 void* iw_realloc (void *ptr, size_t size, const char *err);
215 
216 /*********************************************************************
217  Allocate 16 byte aligned memory. Must be freed with iw_free_align().
218  If err!=NULL and memory could not be allocated, exit with
219  'out of memory: "err"' by calling iw_error().
220 *********************************************************************/
221 void* iw_malloc_align (size_t size, const char *err);
222 void iw_free_align (void *ptr);
223 
224 /*********************************************************************
225  Return in 'array' a NULL terminated array of strings pointing to
226  the parts of 'str', which are separated by spaces. In 'str' '\0'
227  are inserted. In 'array_len' the number of entries in 'array' is
228  returned.
229 *********************************************************************/
230 void iw_string_split (char *str, int *array_len, char ***array);
231 
232 /*********************************************************************
233  Checks if argv[nr] can be found in pattern, the check is case
234  insensitive. Increment nr afterwards. Format of pattern in EBNF:
235  { "-" token ":" ch ["r"|"ro"|"i"|"io"|"f"|"fo"|"c"] " " }
236  token: string without " " and without ":"
237  ch : Any character, given back if -token is found
238  "r" : Argument is required -> returned in *arg
239  "i" : Int argument is required -> returned in *arg
240  "f" : Float argument is required -> returned in *arg
241  "c" : Token can be continued in any way -> returned in *arg
242  "o" : Argument is optional
243  Example: "-i:Ii -s:Sr -h:H -help:H --help:H"
244  On error, print an error message on stderr and return '\0'.
245 *********************************************************************/
246 char iw_parse_args (int argc, char **argv, int *nr, void **arg,
247  const char *pattern);
248 
249 /*********************************************************************
250  PRIVATE: If args, split args, otherwise use argv. Check for any
251  '@file', load the file, exchange '@file' with the args from the
252  file, and expand any vars, commands, and wildcards. nargv is newly
253  allocated.
254 *********************************************************************/
255 BOOL iw_load_args (char *args, int argc, char **argv, int *nargc, char ***nargv);
256 
257 /*********************************************************************
258  Wrapper for usleep() for enhanced portability (the OSF alpha
259  version is really strange).
260 *********************************************************************/
261 void iw_usleep (unsigned long usec);
262 
263 /*********************************************************************
264  On linux: Show the thread ID as a debug output via gettid().
265 *********************************************************************/
266 void iw_showtid (int level, const char *str);
267 
268 #ifdef IW_TIME_MESSURE
269 #define iw_time_add_static(number,name) \
270  static int number = -1; \
271  if (number<0) number = iw_time_add (name);
272 
273 #define iw_time_add_static2(number,name,number2,name2) \
274  static int number = -1, number2 = -1; \
275  if (number<0) { \
276  number = iw_time_add (name); \
277  number2 = iw_time_add (name2); \
278  }
279 
280 #define iw_time_add_static3(number,name,number2,name2,number3,name3) \
281  static int number = -1, number2 = -1, number3 = -1; \
282  if (number<0) { \
283  number = iw_time_add (name); \
284  number2 = iw_time_add (name2); \
285  number3 = iw_time_add (name3); \
286  }
287 
288 /*********************************************************************
289  Add a new timer and return its number (must be passed to the other
290  time_...() functions). 'name' describes the new timer.
291 *********************************************************************/
292 int iw_time_add (const char *name);
293 
294 /*********************************************************************
295  Enable/Disable time_start(), time_stop(), and time_show().
296 *********************************************************************/
297 void iw_time_set_enabled (BOOL enabled);
298 
299 /*********************************************************************
300  Reset time measurement number nr (-> set mean value, count to 0).
301 *********************************************************************/
302 void iw_time_init (int nr);
303 
304 /*********************************************************************
305  Reset all timer, i.e. call iw_time_init() for all added timers.
306 *********************************************************************/
307 void iw_time_init_all (void);
308 
309 /*********************************************************************
310  Start the timer nr (which was added before with iw_time_add()).
311 *********************************************************************/
312 void iw_time_start (int nr);
313 
314 /*********************************************************************
315  Stop the timer number nr.
316  show==TRUE: Print time and average time for number nr on stdout.
317  Return the elapsed real time in ms.
318 *********************************************************************/
319 long iw_time_stop (int nr, BOOL show);
320 
321 /*********************************************************************
322  Print average time for all registered timers on stdout, for which
323  at least one time time_stop() was called.
324 *********************************************************************/
325 void iw_time_show (void);
326 
327 #else
328 # define iw_time_add_static(number,name)
329 # define iw_time_add_static2(number,name,number2,name2)
330 # define iw_time_add_static3(number,name,number2,name2,number3,name3)
331 # define iw_time_add(name) ((void)0)
332 # define iw_time_set_enabled(enabled)
333 # define iw_time_init_all()
334 # define iw_time_init()
335 # define iw_time_start(nr)
336 # define iw_time_stop(nr,show) ((void)0)
337 # define iw_time_show()
338 #endif
339 
340 /*********************************************************************
341  Output passed arguments (including a short header) on stderr and
342  terminate the program.
343 *********************************************************************/
344 void iw_error_x (const char *proc, int line, const char* str, ...)
345  G_GNUC_PRINTF(3, 4);
346 
347 /*********************************************************************
348  Output passed arguments (including a short header) on stderr.
349 *********************************************************************/
350 void iw_warning_x (const char *proc, int line, const char* str, ...)
351  G_GNUC_PRINTF(3, 4);
352 
353 /*********************************************************************
354  Output passed arguments (including a short header) on stderr,
355  append ': 'strerror(errno) and terminate the program.
356 *********************************************************************/
357 void iw_error_errno_x (const char *proc, int line, const char* str, ...)
358  G_GNUC_PRINTF(3, 4);
359 
360 /*********************************************************************
361  Output passed arguments (including a short header) on stderr and
362  append ': 'strerror(errno).
363 *********************************************************************/
364 void iw_warning_errno_x (const char *proc, int line, const char* str, ...)
365  G_GNUC_PRINTF(3, 4);
366 
367 /*********************************************************************
368  Initialize the talklevel for following debug() calls. Debug
369  messages are only given out if there level < talklevel.
370 *********************************************************************/
371 void iw_debug_set_level (int level);
372 
373 #ifdef IW_DEBUG
374 /*********************************************************************
375  Return the talklevel.
376 *********************************************************************/
377 int iw_debug_get_level (void);
378 
379 /*********************************************************************
380  Output passed arguments on stdout (with a short header)
381  if level < talklevel.
382 *********************************************************************/
383 void iw_debug_x (int level, const char *proc, int line, const char* str, ...)
384  G_GNUC_PRINTF(4, 5);
385 #endif
386 
387 #ifdef __cplusplus
388 }
389 #endif
390 
391 #endif /* iw_tools_H */