BRL-CAD
log.h
Go to the documentation of this file.
1 /* L O G . H
2  * BRL-CAD
3  *
4  * Copyright (c) 2004-2024 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 #ifndef BU_LOG_H
22 #define BU_LOG_H
23 
24 #include "common.h"
25 
26 #include <stdio.h> /* For FILE */
27 #include <stdarg.h> /* For va_list */
28 
29 #include "bu/defines.h"
30 #include "bu/magic.h"
31 #include "bu/parse.h"
32 #include "bu/hook.h"
33 
34 #include "bu/exit.h" /* XXX not used here, not intended to be kept included here */
35 
36 
37 __BEGIN_DECLS
38 
39 /** @addtogroup bu_log
40  *
41  * @brief
42  * BRL-CAD support library, error logging routines.
43  *
44  * Note that the user may provide his own logging routine, by replacing these
45  * functions. That is why this is in file of its own. For example, LGT and
46  * RTSRV take advantage of this.
47  *
48  * Here is an example of how to set up a custom logging callback. While bu_log
49  * presently writes to STDERR by default, this behavior should not be relied
50  * upon and may be changed to STDOUT in the future without notice.
51  *
52  * @code
53  * --- BEGIN EXAMPLE ---
54  *
55  * int log_output_to_file(void *data, void *str)
56  * {
57  * FILE *fp = (FILE *)data;
58  * fprintf(fp, "LOG: %s", str);
59  * return 0;
60  * }
61  *
62  * int main(int ac, char *av[])
63  * {
64  * FILE *fp = fopen("whatever.log", "w+");
65  * bu_log_add_hook(log_output_to_file, (void *)fp);
66  * bu_log("Logging to file.\n");
67  * bu_log_delete_hook(log_output_to_file, (void *)fp);
68  * bu_log("Logging to stderr.\n");
69  * fclose(fp);
70  * return 0;
71  * }
72  *
73  * --- END EXAMPLE ---
74  * @endcode
75  *
76  */
77 /** @{ */
78 /** @file bu/log.h */
79 
80 /**
81  * @brief
82  * fgets replacement function that also handles CR as an EOL marker
83  */
84 
85 /**
86  * Reads in at most one less than size characters from stream and
87  * stores them into the buffer pointed to by s. Reading stops after an
88  * EOF, CR, LF, or a CR/LF combination. If a LF or CR is read, it is
89  * stored into the buffer. If a CR/LF is read, just a CR is stored
90  * into the buffer. A '\\0' is stored after the last character in the
91  * buffer. Returns s on success, and NULL on error or when end of file
92  * occurs while no characters have been read.
93  */
94 BU_EXPORT extern char *bu_fgets(char *s, int size, FILE *stream);
95 
96 /** @brief A portable way of doing setlinebuf(). */
97 
98 BU_EXPORT extern void bu_setlinebuf(FILE *fp);
99 
100 /** @brief parallel safe version of fprintf for logging */
101 
102 /**
103  * Change global indentation level by indicated number of characters.
104  * Call with a large negative number to cancel all indentation.
105  */
106 BU_EXPORT extern void bu_log_indent_delta(int delta);
107 
108 /**
109  * For multi-line vls generators, honor logindent level like bu_log() does,
110  * and prefix the proper number of spaces.
111  * Should be called at the front of each new line.
112  */
113 BU_EXPORT extern void bu_log_indent_vls(struct bu_vls *v);
114 
115 /**
116  * Adds a hook to the list of bu_log hooks. The top (newest) one of these
117  * will be called with its associated client data and a string to be
118  * processed. Typically, these hook functions will display the output
119  * (possibly in an X window) or record it.
120  *
121  * NOTE: The hook functions are all non-PARALLEL.
122  */
123 BU_EXPORT extern void bu_log_add_hook(bu_hook_t func, void *clientdata);
124 
125 /**
126  * Removes the hook matching the function and clientdata parameters from
127  * the hook list. Note that it is not necessarily the active (top) hook.
128  */
129 BU_EXPORT extern void bu_log_delete_hook(bu_hook_t func, void *clientdata);
130 
131 BU_EXPORT extern void bu_log_hook_save_all(struct bu_hook_list *save_hlp);
132 BU_EXPORT extern void bu_log_hook_delete_all(void);
133 BU_EXPORT extern void bu_log_hook_restore_all(struct bu_hook_list *restore_hlp);
134 
135 /**
136  * Log a single character with no flushing.
137  */
138 BU_EXPORT extern void bu_putchar(int c);
139 
140 /**
141  * The routine is primarily called to log library events.
142  *
143  * The function is essentially a semaphore-protected version of
144  * fprintf(stderr) with optional logging hooks and automatic
145  * indentation options.
146  */
147 BU_EXPORT extern int bu_log(const char *, ...) _BU_ATTR_PRINTF12;
148 
149 /**
150  * Just like bu_log() except that you can send output to a specified
151  * file pointer.
152  */
153 BU_EXPORT extern int bu_flog(FILE *, const char *, ...) _BU_ATTR_PRINTF23;
154 
155 /**
156  * @brief
157  * libbu implementations of vsscanf/sscanf() with extra format
158  * specifiers.
159  */
160 
161 /**
162  * Custom vsscanf which wraps the system sscanf, and is wrapped by bu_sscanf.
163  *
164  * bu_vsscanf differs notably from the underlying system sscanf in that:
165  *
166  * - A maximum field width is required for unsuppressed %s and %[...]
167  * conversions. If a %s or %[...] conversion is encountered which does
168  * not include a maximum field width, the routine bombs in order to avoid
169  * an accidental buffer overrun.
170  *
171  * - %V and %\#V have been added as valid conversions. Both expect a
172  * pointer to a struct bu_vls as their argument.
173  *
174  * %V is comparable to %[^]. It instructs bu_vsscanf to read arbitrary
175  * characters from the source and store them in the vls buffer. The default
176  * maximum field width is infinity.
177  *
178  * %\#V is comparable to %s. It instructs bu_vsscanf to skip
179  * leading whitespace, and then read characters from the source and
180  * store them in the vls buffer until the next whitespace character
181  * is encountered. The default maximum field width is infinity.
182  *
183  * - 0 is always a valid field width for unsuppressed %c, %s, and %[...]
184  * conversions and causes '\0' to be written to the supplied char*
185  * argument.
186  *
187  * - a/e/f/g and A/E/F/G are always synonyms for float conversion.
188  *
189  * - The C99 conversions hh[diouxX], z[diouxX], and t[diouxX] are always
190  * supported.
191  *
192  * This routine has an associated test program named test_sscanf, which
193  * compares its behavior to the system sscanf.
194  */
195 BU_EXPORT extern int bu_vsscanf(const char *src, const char *fmt, va_list ap);
196 
197 /**
198  * Initializes the va_list, then calls bu_vsscanf.
199  *
200  * This routine has an associated test program named test_sscanf, which
201  * compares its behavior to the system sscanf.
202  */
203 BU_EXPORT extern int bu_sscanf(const char *src, const char *fmt, ...) _BU_ATTR_SCANF23;
204 
205 /** Routines for scanning certain kinds of data. */
206 
207 /**
208  * Scans a sequence of fastf_t numbers from a string or stdin
209  *
210  * Scanning fastf_t numbers with bu_sscanf() is difficult, because
211  * doing so requires scanning to some intermediate type like double
212  * and then assigning to the fastf_t variable to convert the value to
213  * whatever type fastf_t really is. This function makes it possible
214  * to scan a series of fastf_t numbers separated by some character(s)
215  * easily, by doing the required conversion internally to the
216  * functions. As series of delimiter characters will be skipped,
217  * empty scan fields are not supported (e.g., "0.0,,0.0,1.0" will scan
218  * as 3 fields, not 4 with the 2nd skipped).
219  *
220  * @param[out] c Returns number of characters scanned by the function
221  * @param[in] src A source string to scan from, or NULL to read from stdin
222  * @param[in] delim Any delimiter character(s) to skip between scan values
223  * @param[in] n Number of fastf_t values to scan from the src input string
224  * @param[out] ... Pointers to fastf_t for storing scanned values (optional)
225  *
226  */
227 BU_EXPORT extern int bu_scan_fastf_t(int *c, const char *src, const char *delim, size_t n, ...);
228 
229 
230 
231 #define BU_LEX_ANY 0 /* pseudo type */
232 struct bu_lex_t_int {
233  int type;
234  int value;
235 };
236 #define BU_LEX_INT 1
237 struct bu_lex_t_dbl {
238  int type;
239  double value;
240 };
241 #define BU_LEX_DOUBLE 2
242 struct bu_lex_t_key {
243  int type;
244  int value;
245 };
246 #define BU_LEX_SYMBOL 3
247 #define BU_LEX_KEYWORD 4
248 struct bu_lex_t_id {
249  int type;
250  char *value;
251 };
252 #define BU_LEX_IDENT 5
253 #define BU_LEX_NUMBER 6 /* Pseudo type */
255  int type;
256  struct bu_lex_t_int t_int;
257  struct bu_lex_t_dbl t_dbl;
258  struct bu_lex_t_key t_key;
259  struct bu_lex_t_id t_id;
260 };
261 struct bu_lex_key {
262  int tok_val;
263  char *string;
264 };
265 #define BU_LEX_NEED_MORE 0
266 
267 
268 BU_EXPORT extern int bu_lex(union bu_lex_token *token,
269  struct bu_vls *rtstr,
270  struct bu_lex_key *keywords,
271  struct bu_lex_key *symbols);
272 
273 
274 /** @brief multiple-read to fill a buffer */
275 
276 /**
277  * Provide a general means to a read some count of items from a file
278  * descriptor reading multiple times until the quantity desired is
279  * obtained. This is useful for pipes and network connections that
280  * don't necessarily deliver data with the same grouping as it is
281  * written with.
282  *
283  * If a read error occurs, a negative value will be returns and errno
284  * should be set (by read()).
285  * "Multiple try" read. Read multiple times until quantity is
286  * obtained or an error occurs. This is useful for pipes.
287  */
288 BU_EXPORT extern long int bu_mread(int fd, void *bufp, long int n);
289 
290 /** @} */
291 
292 __END_DECLS
293 
294 #endif /* BU_LOG_H */
295 
296 /*
297  * Local Variables:
298  * mode: C
299  * tab-width: 8
300  * indent-tabs-mode: t
301  * c-file-style: "stroustrup"
302  * End:
303  * ex: shiftwidth=4 tabstop=8
304  */
Header file for the BRL-CAD common definitions.
#define _BU_ATTR_PRINTF23
Definition: defines.h:95
#define _BU_ATTR_SCANF23
Definition: defines.h:105
#define _BU_ATTR_PRINTF12
Definition: defines.h:90
int bu_scan_fastf_t(int *c, const char *src, const char *delim, size_t n,...)
void bu_log_indent_vls(struct bu_vls *v)
void bu_setlinebuf(FILE *fp)
A portable way of doing setlinebuf().
void bu_log_hook_restore_all(struct bu_hook_list *restore_hlp)
int bu_sscanf(const char *src, const char *fmt,...) _BU_ATTR_SCANF23
void bu_log_hook_delete_all(void)
int bu_vsscanf(const char *src, const char *fmt, va_list ap)
libbu implementations of vsscanf/sscanf() with extra format specifiers.
int bu_flog(FILE *, const char *,...) _BU_ATTR_PRINTF23
void bu_putchar(int c)
void bu_log_add_hook(bu_hook_t func, void *clientdata)
void bu_log_hook_save_all(struct bu_hook_list *save_hlp)
int(* bu_hook_t)(void *, void *)
Definition: hook.h:41
long int bu_mread(int fd, void *bufp, long int n)
multiple-read to fill a buffer
int bu_lex(union bu_lex_token *token, struct bu_vls *rtstr, struct bu_lex_key *keywords, struct bu_lex_key *symbols)
void bu_log_indent_delta(int delta)
parallel safe version of fprintf for logging
void bu_log_delete_hook(bu_hook_t func, void *clientdata)
int bu_log(const char *,...) _BU_ATTR_PRINTF12
char * bu_fgets(char *s, int size, FILE *stream)
fgets replacement function that also handles CR as an EOL marker
void float float int * n
Definition: tig.h:74
void float float int int int int float * size
Definition: tig.h:132
void int * c
Definition: tig.h:139
Global registry of recognized magic numbers.
int tok_val
Definition: log.h:262
char * string
Definition: log.h:263
int type
Definition: log.h:238
double value
Definition: log.h:239
char * value
Definition: log.h:250
int type
Definition: log.h:249
int value
Definition: log.h:234
int type
Definition: log.h:233
int value
Definition: log.h:244
int type
Definition: log.h:243
Definition: vls.h:53
struct bu_lex_t_dbl t_dbl
Definition: log.h:257
struct bu_lex_t_key t_key
Definition: log.h:258
struct bu_lex_t_id t_id
Definition: log.h:259
int type
Definition: log.h:255
struct bu_lex_t_int t_int
Definition: log.h:256