BRL-CAD
log.h
Go to the documentation of this file.
1/* L O G . H
2 * BRL-CAD
3 *
4 * Copyright (c) 2004-2023 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 */
94BU_EXPORT extern char *bu_fgets(char *s, int size, FILE *stream);
95
96/** @brief A portable way of doing setlinebuf(). */
97
98BU_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 */
106BU_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 */
113BU_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 */
123BU_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 */
129BU_EXPORT extern void bu_log_delete_hook(bu_hook_t func, void *clientdata);
130
131BU_EXPORT extern void bu_log_hook_save_all(struct bu_hook_list *save_hlp);
132BU_EXPORT extern void bu_log_hook_delete_all(void);
133BU_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 */
138BU_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 */
147BU_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 */
153BU_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 */
195BU_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 */
203BU_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 */
227BU_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 */
233 int type;
234 int value;
235};
236#define BU_LEX_INT 1
238 int type;
239 double value;
240};
241#define BU_LEX_DOUBLE 2
243 int type;
244 int value;
245};
246#define BU_LEX_SYMBOL 3
247#define BU_LEX_KEYWORD 4
249 int type;
250 char *value;
251};
252#define BU_LEX_IDENT 5
253#define BU_LEX_NUMBER 6 /* Pseudo type */
255 int type;
260};
263 char *string;
264};
265#define BU_LEX_NEED_MORE 0
266
267
268BU_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 */
288BU_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:100
#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)
char * bu_fgets(char *s, int size, FILE *stream)
fgets replacement function that also handles CR as an EOL marker
int bu_log(const char *,...) _BU_ATTR_PRINTF12
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