BRL-CAD
log.h
Go to the documentation of this file.
1 /* L O G . H
2  * BRL-CAD
3  *
4  * Copyright (c) 2004-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library 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 this file; see the file named COPYING for more
18  * information.
19  */
20 
21 /** @defgroup io Input/Output */
22 /** @defgroup log Logging */
23 
24 /** @file log.h
25  *
26  */
27 #ifndef BU_LOG_H
28 #define BU_LOG_H
29 
30 #include "common.h"
31 
32 #include <stdio.h> /* For FILE */
33 #include <stdarg.h> /* For va_list */
34 
35 #include "bu/defines.h"
36 #include "bu/magic.h"
37 #include "bu/parse.h"
38 #include "bu/list.h"
39 
41 
42 /** @addtogroup log */
43 /** @{ */
44 /** @file libbu/backtrace.c
45  *
46  * Extract a backtrace of the current call stack.
47  *
48  */
49 
50 /**
51  * this routine provides a trace of the call stack to the caller,
52  * generally called either directly, via a signal handler, or through
53  * bu_bomb() with the appropriate bu_debug flags set.
54  *
55  * the routine waits indefinitely (in a spin loop) until a signal
56  * (SIGINT) is received, at which point execution continues, or until
57  * some other signal is received that terminates the application.
58  *
59  * the stack backtrace will be written to the provided 'fp' file
60  * pointer. it's the caller's responsibility to open and close
61  * that pointer if necessary. If 'fp' is NULL, stdout will be used.
62  *
63  * returns truthfully if a backtrace was attempted.
64  */
65 BU_EXPORT extern int bu_backtrace(FILE *fp);
66 
67 /** log indentation hook */
68 typedef int (*bu_hook_t)(void *, void *);
69 
70 struct bu_hook_list {
71  struct bu_list l; /**< linked list */
72  bu_hook_t hookfunc; /**< function to call */
73  void *clientdata; /**< data for caller */
74 };
76 #define BU_HOOK_LIST_NULL ((struct bu_hook_list *) 0)
77 
78 /**
79  * assert the integrity of a non-head node bu_hook_list struct.
80  */
81 #define BU_CK_HOOK_LIST(_hl) BU_CKMAG(_hl, BU_HOOK_LIST_MAGIC, "bu_hook_list")
82 
83 /**
84  * initialize a bu_hook_list struct without allocating any memory.
85  * this macro is not suitable for initialization of a list head node.
86  */
87 #define BU_HOOK_LIST_INIT(_hl) { \
88  BU_LIST_INIT_MAGIC(&(_hl)->l, BU_HOOK_LIST_MAGIC); \
89  (_hl)->hookfunc = (_hl)->clientdata = NULL; \
90  }
91 
92 /**
93  * macro suitable for declaration statement initialization of a
94  * bu_hook_list struct. does not allocate memory. not suitable for
95  * initialization of a list head node.
96  */
97 #define BU_HOOK_LIST_INIT_ZERO { {BU_HOOK_LIST_MAGIC, BU_LIST_NULL, BU_LIST_NULL}, NULL, NULL }
98 
99 /**
100  * returns truthfully whether a non-head node bu_hook_list has been
101  * initialized via BU_HOOK_LIST_INIT() or BU_HOOK_LIST_INIT_ZERO.
102  */
103 #define BU_HOOK_LIST_IS_INITIALIZED(_p) (((struct bu_hook_list *)(_p) != BU_HOOK_LIST_NULL) && LIKELY((_p)->l.magic == BU_HOOK_LIST_MAGIC))
104 
105 /** @file libbu/bomb.c
106  *
107  * Main functions for exiting/bombing.
108  *
109  */
110 /**
111  * Adds a hook to the list of bu_bomb hooks. The top (newest) one of these
112  * will be called with its associated client data and a string to be
113  * processed. Typically, these hook functions will display the output
114  * (possibly in an X window) or record it.
115  *
116  * NOTE: The hook functions are all non-PARALLEL.
117  */
118 BU_EXPORT extern void bu_bomb_add_hook(bu_hook_t func, void *clientdata);
119 
120 /**
121  * Abort the running process.
122  *
123  * The bu_bomb routine is called on a fatal error, generally where no
124  * recovery is possible. Error handlers may, however, be registered
125  * with BU_SETJUMP(). This routine intentionally limits calls to
126  * other functions and intentionally uses no stack variables. Just in
127  * case the application is out of memory, bu_bomb deallocates a small
128  * buffer of memory.
129  *
130  * Before termination, it optionally performs the following operations
131  * in the order listed:
132  *
133  * 1. Outputs str to standard error
134  *
135  * 2. Calls any callback functions set in the global bu_bomb_hook_list
136  * variable with str passed as an argument.
137  *
138  * 3. Jumps to any user specified error handler registered with the
139  * BU_SETJUMP() facility.
140  *
141  * 4. Outputs str to the terminal device in case standard error is
142  * redirected.
143  *
144  * 5. Aborts abnormally (via abort()) if BU_DEBUG_COREDUMP is defined.
145  *
146  * 6. Exits with exit(12).
147  *
148  * Only produce a core-dump when that debugging bit is set. Note that
149  * this function is meant to be a last resort semi-graceful abort.
150  *
151  * This routine should never return unless there is a BU_SETJUMP()
152  * handler registered.
153  */
154 BU_EXPORT extern void bu_bomb(const char *str) _BU_ATTR_NORETURN;
155 
156 /**
157  * Semi-graceful termination of the application that doesn't cause a
158  * stack trace, exiting with the specified status after printing the
159  * given message. It's okay for this routine to use the stack,
160  * contrary to bu_bomb's behavior since it should be called for
161  * expected termination situations.
162  *
163  * This routine should generally not be called within a library. Use
164  * bu_bomb or (better) cascade the error back up to the application.
165  *
166  * This routine should never return.
167  */
168 BU_EXPORT extern void bu_exit(int status, const char *fmt, ...) _BU_ATTR_NORETURN _BU_ATTR_PRINTF23;
169 
170 /** @file libbu/crashreport.c
171  *
172  * Generate a crash report file, including a call stack backtrace and
173  * other system details.
174  *
175  */
176 
177 /**
178  * this routine writes out details of the currently running process to
179  * the specified file, including an informational header about the
180  * execution environment, stack trace details, kernel and hardware
181  * information, and current version information.
182  *
183  * returns truthfully if the crash report was written.
184  *
185  * due to various reasons, this routine is NOT thread-safe.
186  */
187 BU_EXPORT extern int bu_crashreport(const char *filename);
188 
189 /** @file libbu/fgets.c
190  *
191  * fgets replacement function that also handles CR as an EOL marker
192  *
193  */
194 
195 /**
196  * Reads in at most one less than size characters from stream and
197  * stores them into the buffer pointed to by s. Reading stops after an
198  * EOF, CR, LF, or a CR/LF combination. If a LF or CR is read, it is
199  * stored into the buffer. If a CR/LF is read, just a CR is stored
200  * into the buffer. A '\\0' is stored after the last character in the
201  * buffer. Returns s on success, and NULL on error or when end of file
202  * occurs while no characters have been read.
203  */
204 BU_EXPORT extern char *bu_fgets(char *s, int size, FILE *stream);
205 
206 /** @file libbu/linebuf.c
207  *
208  * A portable way of doing setlinebuf().
209  *
210  */
211 
212 BU_EXPORT extern void bu_setlinebuf(FILE *fp);
213 
214 /** @file libbu/hook.c
215  *
216  * @brief
217  * BRL-CAD support library's hook utility.
218  *
219  */
220 BU_EXPORT extern void bu_hook_list_init(struct bu_hook_list *hlp);
221 BU_EXPORT extern void bu_hook_add(struct bu_hook_list *hlp,
222  bu_hook_t func,
223  void *clientdata);
224 BU_EXPORT extern void bu_hook_delete(struct bu_hook_list *hlp,
225  bu_hook_t func,
226  void *clientdata);
227 BU_EXPORT extern void bu_hook_call(struct bu_hook_list *hlp,
228  void *buf);
229 BU_EXPORT extern void bu_hook_save_all(struct bu_hook_list *hlp,
230  struct bu_hook_list *save_hlp);
231 BU_EXPORT extern void bu_hook_delete_all(struct bu_hook_list *hlp);
232 BU_EXPORT extern void bu_hook_restore_all(struct bu_hook_list *hlp,
233  struct bu_hook_list *restore_hlp);
234 
235 /** @file libbu/log.c
236  *
237  * @brief
238  * parallel safe version of fprintf for logging
239  *
240  * BRL-CAD support library, error logging routine. Note that the user
241  * may provide his own logging routine, by replacing these functions.
242  * That is why this is in file of its own. For example, LGT and
243  * RTSRV take advantage of this.
244  *
245  * Here is an example of how to set up a custom logging callback.
246  * While bu_log presently writes to STDERR by default, this behavior
247  * should not be relied upon and may be changed to STDOUT in the
248  * future without notice.
249  *
250  @code
251  --- BEGIN EXAMPLE ---
252 
253  int log_output_to_file(void *data, void *str)
254  {
255  FILE *fp = (FILE *)data;
256  fprintf(fp, "LOG: %s", str);
257  return 0;
258  }
259 
260  int main(int ac, char *av[])
261  {
262  FILE *fp = fopen("whatever.log", "w+");
263  bu_log_add_hook(log_output_to_file, (void *)fp);
264  bu_log("Logging to file.\n");
265  bu_log_delete_hook(log_output_to_file, (void *)fp);
266  bu_log("Logging to stderr.\n");
267  fclose(fp);
268  return 0;
269  }
270 
271  --- END EXAMPLE ---
272  @endcode
273  *
274  */
275 
276 
277 /**
278  * Change global indentation level by indicated number of characters.
279  * Call with a large negative number to cancel all indentation.
280  */
281 BU_EXPORT extern void bu_log_indent_delta(int delta);
282 
283 /**
284  * For multi-line vls generators, honor logindent level like bu_log() does,
285  * and prefix the proper number of spaces.
286  * Should be called at the front of each new line.
287  */
288 BU_EXPORT extern void bu_log_indent_vls(struct bu_vls *v);
289 
290 /**
291  * Adds a hook to the list of bu_log hooks. The top (newest) one of these
292  * will be called with its associated client data and a string to be
293  * processed. Typically, these hook functions will display the output
294  * (possibly in an X window) or record it.
295  *
296  * NOTE: The hook functions are all non-PARALLEL.
297  */
298 BU_EXPORT extern void bu_log_add_hook(bu_hook_t func, void *clientdata);
299 
300 /**
301  * Removes the hook matching the function and clientdata parameters from
302  * the hook list. Note that it is not necessarily the active (top) hook.
303  */
304 BU_EXPORT extern void bu_log_delete_hook(bu_hook_t func, void *clientdata);
305 
306 BU_EXPORT extern void bu_log_hook_save_all(struct bu_hook_list *save_hlp);
307 BU_EXPORT extern void bu_log_hook_delete_all(void);
308 BU_EXPORT extern void bu_log_hook_restore_all(struct bu_hook_list *restore_hlp);
309 
310 /**
311  * Log a single character with no flushing.
312  */
313 BU_EXPORT extern void bu_putchar(int c);
314 
315 /**
316  * The routine is primarily called to log library events.
317  *
318  * The function is essentially a semaphore-protected version of
319  * fprintf(stderr) with optional logging hooks and automatic
320  * indentation options. The main difference is that this function
321  * does not keep track of characters printed, so nothing is returned.
322  *
323  * This function recognizes a %V format specifier to print a bu_vls
324  * struct pointer. See bu_vsscanf() for details.
325  */
326 BU_EXPORT extern void bu_log(const char *, ...) _BU_ATTR_PRINTF12;
327 
328 /**
329  * Just like bu_log() except that you can send output to a specified
330  * file pointer.
331  */
332 BU_EXPORT extern void bu_flog(FILE *, const char *, ...) _BU_ATTR_PRINTF23;
333 
334 /** @file libbu/sscanf.c
335  * libbu implementations of vsscanf/sscanf() with extra format
336  * specifiers.
337  */
338 
339 /**
340  * Custom vsscanf which wraps the system sscanf, and is wrapped by bu_sscanf.
341  *
342  * bu_vsscanf differs notably from the underlying system sscanf in that:
343  *
344  * - A maximum field width is required for unsuppressed %s and %[...]
345  * conversions. If a %s or %[...] conversion is encountered which does
346  * not include a maximum field width, the routine bombs in order to avoid
347  * an accidental buffer overrun.
348  *
349  * - %V and %\#V have been added as valid conversions. Both expect a
350  * pointer to a struct bu_vls as their argument.
351  *
352  * %V is comparable to %[^]. It instructs bu_vsscanf to read arbitrary
353  * characters from the source and store them in the vls buffer. The default
354  * maximum field width is infinity.
355  *
356  * %\#V is comparable to %s. It instructs bu_vsscanf to skip
357  * leading whitespace, and then read characters from the source and
358  * store them in the vls buffer until the next whitespace character
359  * is encountered. The default maximum field width is infinity.
360  *
361  * - 0 is always a valid field width for unsuppressed %c, %s, and %[...]
362  * conversions and causes '\0' to be written to the supplied char*
363  * argument.
364  *
365  * - a/e/f/g and A/E/F/G are always synonyms for float conversion.
366  *
367  * - The C99 conversions hh[diouxX], z[diouxX], and t[diouxX] are always
368  * supported.
369  *
370  * This routine has an associated test program named test_sscanf, which
371  * compares its behavior to the system sscanf.
372  */
373 BU_EXPORT extern int bu_vsscanf(const char *src, const char *fmt, va_list ap);
374 
375 /**
376  * Initializes the va_list, then calls bu_vsscanf.
377  *
378  * This routine has an associated test program named test_sscanf, which
379  * compares its behavior to the system sscanf.
380  */
381 BU_EXPORT extern int bu_sscanf(const char *src, const char *fmt, ...) _BU_ATTR_SCANF23;
382 
383 /** @file libbu/scan.c
384  * Routines for scanning certain kinds of data.
385  */
386 
387 /**
388  * Scans a sequence of fastf_t numbers from a string or stdin
389  *
390  * Scanning fastf_t numbers with bu_sscanf() is difficult, because
391  * doing so requires scanning to some intermediate type like double
392  * and then assigning to the fastf_t variable to convert the value to
393  * whatever type fastf_t really is. This function makes it possible
394  * to scan a series of fastf_t numbers separated by some character(s)
395  * easily, by doing the required conversion internally to the
396  * functions. As series of delimiter characters will be skipped,
397  * empty scan fields are not supported (e.g., "0.0,,0.0,1.0" will scan
398  * as 3 fields, not 4 with the 2nd skipped).
399  *
400  * @param[out] c Returns number of characters scanned by the function
401  * @param[in] src A source string to scan from, or NULL to read from stdin
402  * @param[in] delim Any delimiter character(s) to skip between scan values
403  * @param[in] n Number of fastf_t values to scan from the src input string
404  * @param[out] ... Pointers to fastf_t for storing scanned values (optional)
405  *
406  */
407 BU_EXPORT extern int bu_scan_fastf_t(int *c, const char *src, const char *delim, int n, ...);
408 
409 /** @file libbu/dirname.c
410  *
411  * @brief
412  * Routines to process file and path names.
413  *
414  */
415 
416 /**
417  * Given a string containing a hierarchical path, return a dynamic
418  * string to the parent path.
419  *
420  * This function is similar if not identical to most dirname() BSD
421  * system function implementations; but that system function cannot be
422  * used due to significantly inconsistent behavior across platforms.
423  *
424  * This function always recognizes paths separated by a '/' (i.e.,
425  * geometry paths) as well as whatever the native platform directory
426  * separator may be. It is assumed that all file and directory names
427  * in the path will not contain a path separator, even if escaped.
428  *
429  * It is the caller's responsibility to bu_free() the pointer returned
430  * from this routine.
431  *
432  * Examples of strings returned:
433  *
434  * /usr/dir/file /usr/dir
435  * @n /usr/dir/ /usr
436  * @n /usr/file /usr
437  * @n /usr/ /
438  * @n /usr /
439  * @n / /
440  * @n . .
441  * @n .. .
442  * @n usr .
443  * @n a/b a
444  * @n a/ .
445  * @n ../a/b ../a
446  *
447  * This routine will return "." if other valid results are not available
448  * but should never return NULL.
449  */
450 BU_EXPORT extern char *bu_dirname(const char *path);
451 
452 /** @file libbu/basename.c
453  *
454  * A libbu re-implementation of basename() for cross-platform
455  * compatibility.
456  *
457  */
458 /**
459  * Given a string containing a hierarchical path, return a dynamic
460  * string to the portion after the last path separator.
461  *
462  * This function is similar if not identical to most basename() BSD
463  * system function implementations; but that system function cannot be
464  * used due to significantly inconsistent behavior across platforms.
465  *
466  * This function always recognizes paths separated by a '/' (i.e.,
467  * geometry paths) as well as whatever the native platform directory
468  * separator may be. It is assumed that all file and directory names
469  * in the path will not contain a path separator, even if escaped.
470  *
471  * It is the caller's responsibility to allocate basename with
472  * enough memory to hold a string with length strlen(path), since
473  * that is the maximum possible size of bu_basename's output.
474  *
475  * Examples of strings returned:
476  *
477  * /usr/dir/file file
478  * @n /usr/dir/ dir
479  * @n /usr/ usr
480  * @n /usr usr
481  * @n / /
482  * @n . .
483  * @n .. ..
484  * @n usr usr
485  * @n a/b b
486  * @n a/ a
487  * @n /// /
488  */
489 BU_EXPORT extern void bu_basename(char *basename, const char *path);
490 
491 /** @file libbu/lex.c
492  *
493  */
494 
495 #define BU_LEX_ANY 0 /* pseudo type */
496 struct bu_lex_t_int {
497  int type;
498  int value;
499 };
500 #define BU_LEX_INT 1
501 struct bu_lex_t_dbl {
502  int type;
503  double value;
504 };
505 #define BU_LEX_DOUBLE 2
506 struct bu_lex_t_key {
507  int type;
508  int value;
509 };
510 #define BU_LEX_SYMBOL 3
511 #define BU_LEX_KEYWORD 4
512 struct bu_lex_t_id {
513  int type;
514  char *value;
515 };
516 #define BU_LEX_IDENT 5
517 #define BU_LEX_NUMBER 6 /* Pseudo type */
519  int type;
524 };
525 struct bu_lex_key {
526  int tok_val;
527  char *string;
528 };
529 #define BU_LEX_NEED_MORE 0
530 
531 
532 BU_EXPORT extern int bu_lex(union bu_lex_token *token,
533  struct bu_vls *rtstr,
534  struct bu_lex_key *keywords,
535  struct bu_lex_key *symbols);
536 
537 
538 /** @file libbu/mread.c
539  *
540  * multiple-read to fill a buffer
541  *
542  * Provide a general means to a read some count of items from a file
543  * descriptor reading multiple times until the quantity desired is
544  * obtained. This is useful for pipes and network connections that
545  * don't necessarily deliver data with the same grouping as it is
546  * written with.
547  *
548  * If a read error occurs, a negative value will be returns and errno
549  * should be set (by read()).
550  *
551  */
552 
553 /**
554  * "Multiple try" read. Read multiple times until quantity is
555  * obtained or an error occurs. This is useful for pipes.
556  */
557 BU_EXPORT extern long int bu_mread(int fd, void *bufp, long int n);
558 
559 /** @} */
560 
562 
563 #endif /* BU_LOG_H */
564 
565 /*
566  * Local Variables:
567  * mode: C
568  * tab-width: 8
569  * indent-tabs-mode: t
570  * c-file-style: "stroustrup"
571  * End:
572  * ex: shiftwidth=4 tabstop=8
573  */
void bu_log_add_hook(bu_hook_t func, void *clientdata)
Definition: log.c:69
char filename[MAXLENGTH]
Definition: human.c:105
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
void bu_log_hook_save_all(struct bu_hook_list *save_hlp)
Definition: log.c:92
int tok_val
Definition: log.h:526
struct bu_lex_t_id t_id
Definition: log.h:523
Definition: list.h:118
void bu_hook_save_all(struct bu_hook_list *hlp, struct bu_hook_list *save_hlp)
Definition: hook.c:82
struct bu_lex_t_int t_int
Definition: log.h:520
char * value
Definition: log.h:514
if lu s
Definition: nmg_mod.c:3860
#define _BU_ATTR_SCANF23
Definition: defines.h:155
void bu_hook_add(struct bu_hook_list *hlp, bu_hook_t func, void *clientdata)
Definition: hook.c:39
int bu_crashreport(const char *filename)
Definition: crashreport.c:44
int type
Definition: log.h:507
void bu_log_indent_vls(struct bu_vls *v)
Definition: log.c:62
void * clientdata
Definition: log.h:73
Header file for the BRL-CAD common definitions.
int value
Definition: log.h:508
#define _BU_ATTR_PRINTF23
Definition: defines.h:152
void bu_log_indent_delta(int delta)
Definition: log.c:54
token
Definition: exists.c:65
int type
Definition: log.h:513
void bu_exit(int status, const char *fmt,...) _BU_ATTR_NORETURN _BU_ATTR_PRINTF23
Definition: bomb.c:195
void bu_putchar(int c)
Definition: log.c:139
void bu_hook_restore_all(struct bu_hook_list *hlp, struct bu_hook_list *restore_hlp)
Definition: hook.c:108
struct bu_list l
Definition: log.h:71
#define __BEGIN_DECLS
Definition: common.h:73
#define _BU_ATTR_PRINTF12
Definition: defines.h:149
void bu_log_hook_delete_all(void)
Definition: log.c:99
int bu_vsscanf(const char *src, const char *fmt, va_list ap)
Definition: sscanf.c:107
int type
Definition: log.h:502
int bu_sscanf(const char *src, const char *fmt,...) _BU_ATTR_SCANF23
Definition: sscanf.c:676
void bu_hook_call(struct bu_hook_list *hlp, void *buf)
Definition: hook.c:68
void bu_log_hook_restore_all(struct bu_hook_list *restore_hlp)
Definition: log.c:106
int bu_scan_fastf_t(int *c, const char *src, const char *delim, int n,...)
Definition: scan.c:32
long int bu_mread(int fd, void *bufp, long int n)
Definition: mread.c:31
int bu_backtrace(FILE *fp)
Definition: backtrace.c:300
int type
Definition: log.h:497
void bu_basename(char *basename, const char *path)
Definition: basename.c:30
double value
Definition: log.h:503
bu_hook_t hookfunc
Definition: log.h:72
void bu_hook_list_init(struct bu_hook_list *hlp)
Definition: hook.c:30
int(* bu_hook_t)(void *, void *)
Definition: log.h:68
void bu_bomb_add_hook(bu_hook_t func, void *clientdata)
Definition: bomb.c:84
int value
Definition: log.h:498
struct bu_lex_t_dbl t_dbl
Definition: log.h:521
void bu_hook_delete(struct bu_hook_list *hlp, bu_hook_t func, void *clientdata)
Definition: hook.c:52
void bu_hook_delete_all(struct bu_hook_list *hlp)
Definition: hook.c:96
#define __END_DECLS
Definition: common.h:74
int type
Definition: log.h:519
char * bu_fgets(char *s, int size, FILE *stream)
Definition: fgets.c:31
struct bu_lex_t_key t_key
Definition: log.h:522
Definition: vls.h:56
void bu_setlinebuf(FILE *fp)
Definition: linebuf.c:44
void bu_bomb(const char *str) _BU_ATTR_NORETURN
Definition: bomb.c:91
HIDDEN const point_t delta
Definition: sh_prj.c:618
int bu_lex(union bu_lex_token *token, struct bu_vls *rtstr, struct bu_lex_key *keywords, struct bu_lex_key *symbols)
Definition: lex.c:144
#define _BU_ATTR_NORETURN
Definition: defines.h:161
char * bu_dirname(const char *path)
Definition: dirname.c:30
void bu_flog(FILE *, const char *,...) _BU_ATTR_PRINTF23
Definition: log.c:246
void bu_log_delete_hook(bu_hook_t func, void *clientdata)
Definition: log.c:76
char * string
Definition: log.h:527