Deleted Added
full compact
xo.h (287111) xo.h (298083)
1/*
2 * Copyright (c) 2014-2015, Juniper Networks, Inc.
3 * All rights reserved.
4 * This SOFTWARE is licensed under the LICENSE provided in the
5 * ../Copyright file. By downloading, installing, copying, or otherwise
6 * using the SOFTWARE, you agree to be bound by the terms of that
7 * LICENSE.
8 * Phil Shafer, July 2014
9 */
10
11/**
12 * libxo provides a means of generating text, XML, JSON, and HTML output
13 * using a single set of function calls, maximizing the value of output
14 * while minimizing the cost/impact on the code.
15 *
16 * Full documentation is available in ./doc/libxo.txt or online at:
17 * http://juniper.github.io/libxo/libxo-manual.html
18 */
19
20#ifndef INCLUDE_XO_H
21#define INCLUDE_XO_H
22
23#include <stdio.h>
24#include <sys/types.h>
25#include <stdarg.h>
26#include <stdlib.h>
27#include <errno.h>
28
29#ifdef __dead2
30#define NORETURN __dead2
31#else
32#define NORETURN
33#endif /* __dead2 */
34
35/*
36 * Normally we'd use the HAVE_PRINTFLIKE define triggered by the
37 * --enable-printflike option to configure, but we don't install
38 * our internal "xoconfig.h", and I'd rather not. Taking the
39 * coward's path, we'll turn it on inside a #if that allows
40 * others to turn it off where needed. Not ideal, but functional.
41 */
42#if !defined(NO_PRINTFLIKE) && !defined(__linux__)
43#define PRINTFLIKE(_x, _y) __printflike(_x, _y)
44#else
45#define PRINTFLIKE(_x, _y)
46#endif /* NO_PRINTFLIKE */
47
48/** Formatting types */
49typedef unsigned short xo_style_t;
50#define XO_STYLE_TEXT 0 /** Generate text output */
51#define XO_STYLE_XML 1 /** Generate XML output */
52#define XO_STYLE_JSON 2 /** Generate JSON output */
53#define XO_STYLE_HTML 3 /** Generate HTML output */
54#define XO_STYLE_SDPARAMS 4 /* Generate syslog structured data params */
55#define XO_STYLE_ENCODER 5 /* Generate calls to external encoder */
56
57/** Flags for libxo */
58typedef unsigned long long xo_xof_flags_t;
59#define XOF_BIT(_n) ((xo_xof_flags_t) 1 << (_n))
60#define XOF_CLOSE_FP XOF_BIT(0) /** Close file pointer on xo_close() */
61#define XOF_PRETTY XOF_BIT(1) /** Make 'pretty printed' output */
62#define XOF_LOG_SYSLOG XOF_BIT(2) /** Log (on stderr) our syslog content */
63#define XOF_RESV3 XOF_BIT(3) /* Unused */
64
65#define XOF_WARN XOF_BIT(4) /** Generate warnings for broken calls */
66#define XOF_XPATH XOF_BIT(5) /** Emit XPath attributes in HTML */
67#define XOF_INFO XOF_BIT(6) /** Emit additional info fields (HTML) */
68#define XOF_WARN_XML XOF_BIT(7) /** Emit warnings in XML (on stdout) */
69
70#define XOF_NO_ENV XOF_BIT(8) /** Don't look at LIBXO_OPTIONS env var */
71#define XOF_NO_VA_ARG XOF_BIT(9) /** Don't advance va_list w/ va_arg() */
72#define XOF_DTRT XOF_BIT(10) /** Enable "do the right thing" mode */
73#define XOF_KEYS XOF_BIT(11) /** Flag 'key' fields for xml and json */
74
75#define XOF_IGNORE_CLOSE XOF_BIT(12) /** Ignore errors on close tags */
76#define XOF_NOT_FIRST XOF_BIT(13) /* Not the first item (JSON) */
77#define XOF_NO_LOCALE XOF_BIT(14) /** Don't bother with locale */
78#define XOF_RESV15 XOF_BIT(15) /* Unused */
79
80#define XOF_NO_TOP XOF_BIT(16) /** Don't emit the top braces in JSON */
81#define XOF_RESV17 XOF_BIT(17) /* Unused */
82#define XOF_UNITS XOF_BIT(18) /** Encode units in XML */
83#define XOF_RESV19 XOF_BIT(19) /* Unused */
84
85#define XOF_UNDERSCORES XOF_BIT(20) /** Replace dashes with underscores (JSON)*/
86#define XOF_COLUMNS XOF_BIT(21) /** xo_emit should return a column count */
87#define XOF_FLUSH XOF_BIT(22) /** Flush after each xo_emit call */
88#define XOF_FLUSH_LINE XOF_BIT(23) /** Flush after each newline */
89
90#define XOF_NO_CLOSE XOF_BIT(24) /** xo_finish won't close open elements */
91#define XOF_COLOR_ALLOWED XOF_BIT(25) /** Allow color/effects to be enabled */
92#define XOF_COLOR XOF_BIT(26) /** Enable color and effects */
93#define XOF_NO_HUMANIZE XOF_BIT(27) /** Block the {h:} modifier */
94
95#define XOF_LOG_GETTEXT XOF_BIT(28) /** Log (stderr) gettext lookup strings */
96#define XOF_UTF8 XOF_BIT(29) /** Force text output to be UTF8 */
1/*
2 * Copyright (c) 2014-2015, Juniper Networks, Inc.
3 * All rights reserved.
4 * This SOFTWARE is licensed under the LICENSE provided in the
5 * ../Copyright file. By downloading, installing, copying, or otherwise
6 * using the SOFTWARE, you agree to be bound by the terms of that
7 * LICENSE.
8 * Phil Shafer, July 2014
9 */
10
11/**
12 * libxo provides a means of generating text, XML, JSON, and HTML output
13 * using a single set of function calls, maximizing the value of output
14 * while minimizing the cost/impact on the code.
15 *
16 * Full documentation is available in ./doc/libxo.txt or online at:
17 * http://juniper.github.io/libxo/libxo-manual.html
18 */
19
20#ifndef INCLUDE_XO_H
21#define INCLUDE_XO_H
22
23#include <stdio.h>
24#include <sys/types.h>
25#include <stdarg.h>
26#include <stdlib.h>
27#include <errno.h>
28
29#ifdef __dead2
30#define NORETURN __dead2
31#else
32#define NORETURN
33#endif /* __dead2 */
34
35/*
36 * Normally we'd use the HAVE_PRINTFLIKE define triggered by the
37 * --enable-printflike option to configure, but we don't install
38 * our internal "xoconfig.h", and I'd rather not. Taking the
39 * coward's path, we'll turn it on inside a #if that allows
40 * others to turn it off where needed. Not ideal, but functional.
41 */
42#if !defined(NO_PRINTFLIKE) && !defined(__linux__)
43#define PRINTFLIKE(_x, _y) __printflike(_x, _y)
44#else
45#define PRINTFLIKE(_x, _y)
46#endif /* NO_PRINTFLIKE */
47
48/** Formatting types */
49typedef unsigned short xo_style_t;
50#define XO_STYLE_TEXT 0 /** Generate text output */
51#define XO_STYLE_XML 1 /** Generate XML output */
52#define XO_STYLE_JSON 2 /** Generate JSON output */
53#define XO_STYLE_HTML 3 /** Generate HTML output */
54#define XO_STYLE_SDPARAMS 4 /* Generate syslog structured data params */
55#define XO_STYLE_ENCODER 5 /* Generate calls to external encoder */
56
57/** Flags for libxo */
58typedef unsigned long long xo_xof_flags_t;
59#define XOF_BIT(_n) ((xo_xof_flags_t) 1 << (_n))
60#define XOF_CLOSE_FP XOF_BIT(0) /** Close file pointer on xo_close() */
61#define XOF_PRETTY XOF_BIT(1) /** Make 'pretty printed' output */
62#define XOF_LOG_SYSLOG XOF_BIT(2) /** Log (on stderr) our syslog content */
63#define XOF_RESV3 XOF_BIT(3) /* Unused */
64
65#define XOF_WARN XOF_BIT(4) /** Generate warnings for broken calls */
66#define XOF_XPATH XOF_BIT(5) /** Emit XPath attributes in HTML */
67#define XOF_INFO XOF_BIT(6) /** Emit additional info fields (HTML) */
68#define XOF_WARN_XML XOF_BIT(7) /** Emit warnings in XML (on stdout) */
69
70#define XOF_NO_ENV XOF_BIT(8) /** Don't look at LIBXO_OPTIONS env var */
71#define XOF_NO_VA_ARG XOF_BIT(9) /** Don't advance va_list w/ va_arg() */
72#define XOF_DTRT XOF_BIT(10) /** Enable "do the right thing" mode */
73#define XOF_KEYS XOF_BIT(11) /** Flag 'key' fields for xml and json */
74
75#define XOF_IGNORE_CLOSE XOF_BIT(12) /** Ignore errors on close tags */
76#define XOF_NOT_FIRST XOF_BIT(13) /* Not the first item (JSON) */
77#define XOF_NO_LOCALE XOF_BIT(14) /** Don't bother with locale */
78#define XOF_RESV15 XOF_BIT(15) /* Unused */
79
80#define XOF_NO_TOP XOF_BIT(16) /** Don't emit the top braces in JSON */
81#define XOF_RESV17 XOF_BIT(17) /* Unused */
82#define XOF_UNITS XOF_BIT(18) /** Encode units in XML */
83#define XOF_RESV19 XOF_BIT(19) /* Unused */
84
85#define XOF_UNDERSCORES XOF_BIT(20) /** Replace dashes with underscores (JSON)*/
86#define XOF_COLUMNS XOF_BIT(21) /** xo_emit should return a column count */
87#define XOF_FLUSH XOF_BIT(22) /** Flush after each xo_emit call */
88#define XOF_FLUSH_LINE XOF_BIT(23) /** Flush after each newline */
89
90#define XOF_NO_CLOSE XOF_BIT(24) /** xo_finish won't close open elements */
91#define XOF_COLOR_ALLOWED XOF_BIT(25) /** Allow color/effects to be enabled */
92#define XOF_COLOR XOF_BIT(26) /** Enable color and effects */
93#define XOF_NO_HUMANIZE XOF_BIT(27) /** Block the {h:} modifier */
94
95#define XOF_LOG_GETTEXT XOF_BIT(28) /** Log (stderr) gettext lookup strings */
96#define XOF_UTF8 XOF_BIT(29) /** Force text output to be UTF8 */
97#define XOF_RETAIN_ALL XOF_BIT(30) /** Force use of XOEF_RETAIN */
98#define XOF_RETAIN_NONE XOF_BIT(31) /** Prevent use of XOEF_RETAIN */
97
99
100typedef unsigned xo_emit_flags_t; /* Flags to xo_emit() and friends */
101#define XOEF_RETAIN (1<<0) /* Retain parsed formatting information */
102
98/*
99 * The xo_info_t structure provides a mapping between names and
100 * additional data emitted via HTML.
101 */
102typedef struct xo_info_s {
103 const char *xi_name; /* Name of the element */
104 const char *xi_type; /* Type of field */
105 const char *xi_help; /* Description of field */
106} xo_info_t;
107
108#define XO_INFO_NULL NULL, NULL, NULL /* Use '{ XO_INFO_NULL }' to end lists */
109
110struct xo_handle_s; /* Opaque structure forward */
111typedef struct xo_handle_s xo_handle_t; /* Handle for XO output */
112
113typedef int (*xo_write_func_t)(void *, const char *);
114typedef void (*xo_close_func_t)(void *);
115typedef int (*xo_flush_func_t)(void *);
116typedef void *(*xo_realloc_func_t)(void *, size_t);
117typedef void (*xo_free_func_t)(void *);
118
119/*
120 * The formatter function mirrors "vsnprintf", with an additional argument
121 * of the xo handle. The caller should return the number of bytes _needed_
122 * to fit the data, even if this exceeds 'len'.
123 */
124typedef int (*xo_formatter_t)(xo_handle_t *, char *, int,
125 const char *, va_list);
126typedef void (*xo_checkpointer_t)(xo_handle_t *, va_list, int);
127
128xo_handle_t *
129xo_create (xo_style_t style, xo_xof_flags_t flags);
130
131xo_handle_t *
132xo_create_to_file (FILE *fp, xo_style_t style, xo_xof_flags_t flags);
133
134void
135xo_destroy (xo_handle_t *xop);
136
137void
138xo_set_writer (xo_handle_t *xop, void *opaque, xo_write_func_t write_func,
139 xo_close_func_t close_func, xo_flush_func_t flush_func);
140
141void
142xo_set_allocator (xo_realloc_func_t realloc_func, xo_free_func_t free_func);
143
144void
145xo_set_style (xo_handle_t *xop, xo_style_t style);
146
147xo_style_t
148xo_get_style (xo_handle_t *xop);
149
150int
151xo_set_style_name (xo_handle_t *xop, const char *style);
152
153int
154xo_set_options (xo_handle_t *xop, const char *input);
155
156xo_xof_flags_t
157xo_get_flags (xo_handle_t *xop);
158
159void
160xo_set_flags (xo_handle_t *xop, xo_xof_flags_t flags);
161
162void
163xo_clear_flags (xo_handle_t *xop, xo_xof_flags_t flags);
164
103/*
104 * The xo_info_t structure provides a mapping between names and
105 * additional data emitted via HTML.
106 */
107typedef struct xo_info_s {
108 const char *xi_name; /* Name of the element */
109 const char *xi_type; /* Type of field */
110 const char *xi_help; /* Description of field */
111} xo_info_t;
112
113#define XO_INFO_NULL NULL, NULL, NULL /* Use '{ XO_INFO_NULL }' to end lists */
114
115struct xo_handle_s; /* Opaque structure forward */
116typedef struct xo_handle_s xo_handle_t; /* Handle for XO output */
117
118typedef int (*xo_write_func_t)(void *, const char *);
119typedef void (*xo_close_func_t)(void *);
120typedef int (*xo_flush_func_t)(void *);
121typedef void *(*xo_realloc_func_t)(void *, size_t);
122typedef void (*xo_free_func_t)(void *);
123
124/*
125 * The formatter function mirrors "vsnprintf", with an additional argument
126 * of the xo handle. The caller should return the number of bytes _needed_
127 * to fit the data, even if this exceeds 'len'.
128 */
129typedef int (*xo_formatter_t)(xo_handle_t *, char *, int,
130 const char *, va_list);
131typedef void (*xo_checkpointer_t)(xo_handle_t *, va_list, int);
132
133xo_handle_t *
134xo_create (xo_style_t style, xo_xof_flags_t flags);
135
136xo_handle_t *
137xo_create_to_file (FILE *fp, xo_style_t style, xo_xof_flags_t flags);
138
139void
140xo_destroy (xo_handle_t *xop);
141
142void
143xo_set_writer (xo_handle_t *xop, void *opaque, xo_write_func_t write_func,
144 xo_close_func_t close_func, xo_flush_func_t flush_func);
145
146void
147xo_set_allocator (xo_realloc_func_t realloc_func, xo_free_func_t free_func);
148
149void
150xo_set_style (xo_handle_t *xop, xo_style_t style);
151
152xo_style_t
153xo_get_style (xo_handle_t *xop);
154
155int
156xo_set_style_name (xo_handle_t *xop, const char *style);
157
158int
159xo_set_options (xo_handle_t *xop, const char *input);
160
161xo_xof_flags_t
162xo_get_flags (xo_handle_t *xop);
163
164void
165xo_set_flags (xo_handle_t *xop, xo_xof_flags_t flags);
166
167void
168xo_clear_flags (xo_handle_t *xop, xo_xof_flags_t flags);
169
170int
171xo_set_file_h (xo_handle_t *xop, FILE *fp);
172
173int
174xo_set_file (FILE *fp);
175
165void
166xo_set_info (xo_handle_t *xop, xo_info_t *infop, int count);
167
168void
169xo_set_formatter (xo_handle_t *xop, xo_formatter_t func, xo_checkpointer_t);
170
171void
172xo_set_depth (xo_handle_t *xop, int depth);
173
174int
175xo_emit_hv (xo_handle_t *xop, const char *fmt, va_list vap);
176
177int
178xo_emit_h (xo_handle_t *xop, const char *fmt, ...);
179
180int
181xo_emit (const char *fmt, ...);
182
176void
177xo_set_info (xo_handle_t *xop, xo_info_t *infop, int count);
178
179void
180xo_set_formatter (xo_handle_t *xop, xo_formatter_t func, xo_checkpointer_t);
181
182void
183xo_set_depth (xo_handle_t *xop, int depth);
184
185int
186xo_emit_hv (xo_handle_t *xop, const char *fmt, va_list vap);
187
188int
189xo_emit_h (xo_handle_t *xop, const char *fmt, ...);
190
191int
192xo_emit (const char *fmt, ...);
193
194int
195xo_emit_hvf (xo_handle_t *xop, xo_emit_flags_t flags,
196 const char *fmt, va_list vap);
197
198int
199xo_emit_hf (xo_handle_t *xop, xo_emit_flags_t flags, const char *fmt, ...);
200
201int
202xo_emit_f (xo_emit_flags_t flags, const char *fmt, ...);
203
183PRINTFLIKE(2, 0)
184static inline int
185xo_emit_hvp (xo_handle_t *xop, const char *fmt, va_list vap)
186{
187 return xo_emit_hv(xop, fmt, vap);
188}
189
190PRINTFLIKE(2, 3)
191static inline int
192xo_emit_hp (xo_handle_t *xop, const char *fmt, ...)
193{
194 va_list vap;
195 va_start(vap, fmt);
196 int rc = xo_emit_hv(xop, fmt, vap);
197 va_end(vap);
198 return rc;
199}
200
201PRINTFLIKE(1, 2)
202static inline int
203xo_emit_p (const char *fmt, ...)
204{
205 va_list vap;
206 va_start(vap, fmt);
207 int rc = xo_emit_hv(NULL, fmt, vap);
208 va_end(vap);
209 return rc;
210}
211
204PRINTFLIKE(2, 0)
205static inline int
206xo_emit_hvp (xo_handle_t *xop, const char *fmt, va_list vap)
207{
208 return xo_emit_hv(xop, fmt, vap);
209}
210
211PRINTFLIKE(2, 3)
212static inline int
213xo_emit_hp (xo_handle_t *xop, const char *fmt, ...)
214{
215 va_list vap;
216 va_start(vap, fmt);
217 int rc = xo_emit_hv(xop, fmt, vap);
218 va_end(vap);
219 return rc;
220}
221
222PRINTFLIKE(1, 2)
223static inline int
224xo_emit_p (const char *fmt, ...)
225{
226 va_list vap;
227 va_start(vap, fmt);
228 int rc = xo_emit_hv(NULL, fmt, vap);
229 va_end(vap);
230 return rc;
231}
232
233PRINTFLIKE(3, 0)
234static inline int
235xo_emit_hvfp (xo_handle_t *xop, xo_emit_flags_t flags,
236 const char *fmt, va_list vap)
237{
238 return xo_emit_hvf(xop, flags, fmt, vap);
239}
240
241PRINTFLIKE(3, 4)
242static inline int
243xo_emit_hfp (xo_handle_t *xop, xo_emit_flags_t flags, const char *fmt, ...)
244{
245 va_list vap;
246 va_start(vap, fmt);
247 int rc = xo_emit_hvf(xop, flags, fmt, vap);
248 va_end(vap);
249 return rc;
250}
251
252PRINTFLIKE(2, 3)
253static inline int
254xo_emit_fp (xo_emit_flags_t flags, const char *fmt, ...)
255{
256 va_list vap;
257 va_start(vap, fmt);
258 int rc = xo_emit_hvf(NULL, flags, fmt, vap);
259 va_end(vap);
260 return rc;
261}
262
212int
213xo_open_container_h (xo_handle_t *xop, const char *name);
214
215int
216xo_open_container (const char *name);
217
218int
219xo_open_container_hd (xo_handle_t *xop, const char *name);
220
221int
222xo_open_container_d (const char *name);
223
224int
225xo_close_container_h (xo_handle_t *xop, const char *name);
226
227int
228xo_close_container (const char *name);
229
230int
231xo_close_container_hd (xo_handle_t *xop);
232
233int
234xo_close_container_d (void);
235
236int
237xo_open_list_h (xo_handle_t *xop, const char *name);
238
239int
240xo_open_list (const char *name);
241
242int
243xo_open_list_hd (xo_handle_t *xop, const char *name);
244
245int
246xo_open_list_d (const char *name);
247
248int
249xo_close_list_h (xo_handle_t *xop, const char *name);
250
251int
252xo_close_list (const char *name);
253
254int
255xo_close_list_hd (xo_handle_t *xop);
256
257int
258xo_close_list_d (void);
259
260int
261xo_open_instance_h (xo_handle_t *xop, const char *name);
262
263int
264xo_open_instance (const char *name);
265
266int
267xo_open_instance_hd (xo_handle_t *xop, const char *name);
268
269int
270xo_open_instance_d (const char *name);
271
272int
273xo_close_instance_h (xo_handle_t *xop, const char *name);
274
275int
276xo_close_instance (const char *name);
277
278int
279xo_close_instance_hd (xo_handle_t *xop);
280
281int
282xo_close_instance_d (void);
283
284int
285xo_open_marker_h (xo_handle_t *xop, const char *name);
286
287int
288xo_open_marker (const char *name);
289
290int
291xo_close_marker_h (xo_handle_t *xop, const char *name);
292
293int
294xo_close_marker (const char *name);
295
296int
297xo_attr_h (xo_handle_t *xop, const char *name, const char *fmt, ...);
298
299int
300xo_attr_hv (xo_handle_t *xop, const char *name, const char *fmt, va_list vap);
301
302int
303xo_attr (const char *name, const char *fmt, ...);
304
305void
306xo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap);
307
308void
309xo_error_h (xo_handle_t *xop, const char *fmt, ...);
310
311void
312xo_error (const char *fmt, ...);
313
314int
315xo_flush_h (xo_handle_t *xop);
316
317int
318xo_flush (void);
319
320int
321xo_finish_h (xo_handle_t *xop);
322
323int
324xo_finish (void);
325
326void
327xo_finish_atexit (void);
328
329void
330xo_set_leading_xpath (xo_handle_t *xop, const char *path);
331
332void
333xo_warn_hc (xo_handle_t *xop, int code, const char *fmt, ...) PRINTFLIKE(3, 4);
334
335void
336xo_warn_c (int code, const char *fmt, ...) PRINTFLIKE(2, 3);
337
338void
339xo_warn (const char *fmt, ...) PRINTFLIKE(1, 2);
340
341void
342xo_warnx (const char *fmt, ...) PRINTFLIKE(1, 2);
343
344void
345xo_err (int eval, const char *fmt, ...) NORETURN PRINTFLIKE(2, 3);
346
347void
348xo_errx (int eval, const char *fmt, ...) NORETURN PRINTFLIKE(2, 3);
349
350void
351xo_errc (int eval, int code, const char *fmt, ...) NORETURN PRINTFLIKE(3, 4);
352
353void
354xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap) PRINTFLIKE(3, 0);
355
356void
357xo_message_hc (xo_handle_t *xop, int code, const char *fmt, ...) PRINTFLIKE(3, 4);
358
359void
360xo_message_c (int code, const char *fmt, ...) PRINTFLIKE(2, 3);
361
362void
363xo_message_e (const char *fmt, ...) PRINTFLIKE(1, 2);
364
365void
366xo_message (const char *fmt, ...) PRINTFLIKE(1, 2);
367
368void
369xo_emit_warn_hcv (xo_handle_t *xop, int as_warning, int code,
370 const char *fmt, va_list vap);
371
372void
373xo_emit_warn_hc (xo_handle_t *xop, int code, const char *fmt, ...);
374
375void
376xo_emit_warn_c (int code, const char *fmt, ...);
377
378void
379xo_emit_warn (const char *fmt, ...);
380
381void
382xo_emit_warnx (const char *fmt, ...);
383
384void
385xo_emit_err (int eval, const char *fmt, ...) NORETURN;
386
387void
388xo_emit_errx (int eval, const char *fmt, ...) NORETURN;
389
390void
391xo_emit_errc (int eval, int code, const char *fmt, ...) NORETURN;
392
393PRINTFLIKE(4, 0)
394static inline void
395xo_emit_warn_hcvp (xo_handle_t *xop, int as_warning, int code,
396 const char *fmt, va_list vap)
397{
398 xo_emit_warn_hcv(xop, as_warning, code, fmt, vap);
399}
400
401PRINTFLIKE(3, 4)
402static inline void
403xo_emit_warn_hcp (xo_handle_t *xop, int code, const char *fmt, ...)
404{
405 va_list vap;
406 va_start(vap, fmt);
407 xo_emit_warn_hcv(xop, 1, code, fmt, vap);
408 va_end(vap);
409}
410
411PRINTFLIKE(2, 3)
412static inline void
413xo_emit_warn_cp (int code, const char *fmt, ...)
414{
415 va_list vap;
416 va_start(vap, fmt);
417 xo_emit_warn_hcv(NULL, 1, code, fmt, vap);
418 va_end(vap);
419}
420
421PRINTFLIKE(1, 2)
422static inline void
423xo_emit_warn_p (const char *fmt, ...)
424{
425 int code = errno;
426 va_list vap;
427 va_start(vap, fmt);
428 xo_emit_warn_hcv(NULL, 1, code, fmt, vap);
429 va_end(vap);
430}
431
432PRINTFLIKE(1, 2)
433static inline void
434xo_emit_warnx_p (const char *fmt, ...)
435{
436 va_list vap;
437 va_start(vap, fmt);
438 xo_emit_warn_hcv(NULL, 1, -1, fmt, vap);
439 va_end(vap);
440}
441
442NORETURN PRINTFLIKE(2, 3)
443static inline void
444xo_emit_err_p (int eval, const char *fmt, ...)
445{
446 int code = errno;
447 va_list vap;
448 va_start(vap, fmt);
449 xo_emit_warn_hcv(NULL, 0, code, fmt, vap);
450 va_end(vap);
451
452 exit(eval);
453}
454
455PRINTFLIKE(2, 3)
456static inline void
457xo_emit_errx_p (int eval, const char *fmt, ...)
458{
459 va_list vap;
460 va_start(vap, fmt);
461 xo_emit_warn_hcv(NULL, 0, -1, fmt, vap);
462 va_end(vap);
463 exit(eval);
464}
465
466PRINTFLIKE(3, 4)
467static inline void
468xo_emit_errc_p (int eval, int code, const char *fmt, ...)
469{
470 va_list vap;
471 va_start(vap, fmt);
472 xo_emit_warn_hcv(NULL, 0, code, fmt, vap);
473 va_end(vap);
474 exit(eval);
475}
476
477void
478xo_emit_err_v (int eval, int code, const char *fmt, va_list vap) NORETURN PRINTFLIKE(3, 0);
479
480void
481xo_no_setlocale (void);
482
483/**
484 * @brief Lift libxo-specific arguments from a set of arguments
485 *
486 * libxo-enable programs typically use command line options to enable
487 * all the nifty-cool libxo features. xo_parse_args() makes this simple
488 * by pre-processing the command line arguments given to main(), handling
489 * and removing the libxo-specific ones, meaning anything starting with
490 * "--libxo". A full description of these arguments is in the base
491 * documentation.
492 * @param[in] argc Number of arguments (ala #main())
493 * @param[in] argc Array of argument strings (ala #main())
494 * @return New number of arguments, or -1 for failure.
495 */
496int
497xo_parse_args (int argc, char **argv);
498
499/**
500 * This is the "magic" number returned by libxo-supporting commands
501 * when passed the equally magic "--libxo-check" option. If you
502 * return this, we can (unsafely) assume that since you know the magic
503 * handshake, you'll happily handle future --libxo options and not do
504 * something violent like reboot the box or create another hole in the
505 * ozone layer.
506 */
507#define XO_HAS_LIBXO 121
508
509/**
510 * externs for libxo's version number strings
511 */
512extern const char xo_version[]; /** Base version triple string */
513extern const char xo_version_extra[]; /** Extra version magic content */
514
515/**
516 * @brief Dump the internal stack of a libxo handle.
517 *
518 * This diagnostic function is something I will ask you to call from
519 * your program when you write to tell me libxo has gone bat-stink
520 * crazy and has discarded your list or container or content. Output
521 * content will be what we lovingly call "developer entertainment".
522 * @param[in] xop A valid libxo handle, or NULL for the default handle
523 */
524void
525xo_dump_stack (xo_handle_t *xop);
526
527/**
528 * @brief Recode the name of the program, suitable for error output.
529 *
530 * libxo will record the given name for use while generating error
531 * messages. The contents are not copied, so the value must continue
532 * to point to a valid memory location. This allows the caller to change
533 * the value, but requires the caller to manage the memory. Typically
534 * this is called with argv[0] from main().
535 * @param[in] name The name of the current application program
536 */
537void
538xo_set_program (const char *name);
539
540/**
541 * @brief Add a version string to the output, where possible.
542 *
543 * Adds a version number to the output, suitable for tracking
544 * changes in the content. This is only important for the "encoding"
545 * format styles (XML and JSON) and allows a user of the data to
546 * discern which version of the data model is in use.
547 * @param[in] version The version number, encoded as a string
548 */
549void
550xo_set_version (const char *version);
551
552/**
553 * #xo_set_version with a handle.
554 * @param[in] xop A valid libxo handle, or NULL for the default handle
555 * @param[in] version The version number, encoded as a string
556 */
557void
558xo_set_version_h (xo_handle_t *xop, const char *version);
559
560void
561xo_open_log (const char *ident, int logopt, int facility);
562
563void
564xo_close_log (void);
565
566int
567xo_set_logmask (int maskpri);
568
569void
570xo_set_unit_test_mode (int value);
571
572void
573xo_syslog (int priority, const char *name, const char *message, ...);
574
575void
576xo_vsyslog (int priority, const char *name, const char *message, va_list args);
577
578typedef void (*xo_syslog_open_t)(void);
579typedef void (*xo_syslog_send_t)(const char *full_msg,
580 const char *v0_hdr, const char *text_only);
581typedef void (*xo_syslog_close_t)(void);
582
583void
584xo_set_syslog_handler (xo_syslog_open_t open_func, xo_syslog_send_t send_func,
585 xo_syslog_close_t close_func);
586
587void
588xo_set_syslog_enterprise_id (unsigned short eid);
589
590typedef void (*xo_simplify_field_func_t)(const char *, unsigned, int);
591
592char *
593xo_simplify_format (xo_handle_t *xop, const char *fmt, int with_numbers,
594 xo_simplify_field_func_t field_cb);
595
263int
264xo_open_container_h (xo_handle_t *xop, const char *name);
265
266int
267xo_open_container (const char *name);
268
269int
270xo_open_container_hd (xo_handle_t *xop, const char *name);
271
272int
273xo_open_container_d (const char *name);
274
275int
276xo_close_container_h (xo_handle_t *xop, const char *name);
277
278int
279xo_close_container (const char *name);
280
281int
282xo_close_container_hd (xo_handle_t *xop);
283
284int
285xo_close_container_d (void);
286
287int
288xo_open_list_h (xo_handle_t *xop, const char *name);
289
290int
291xo_open_list (const char *name);
292
293int
294xo_open_list_hd (xo_handle_t *xop, const char *name);
295
296int
297xo_open_list_d (const char *name);
298
299int
300xo_close_list_h (xo_handle_t *xop, const char *name);
301
302int
303xo_close_list (const char *name);
304
305int
306xo_close_list_hd (xo_handle_t *xop);
307
308int
309xo_close_list_d (void);
310
311int
312xo_open_instance_h (xo_handle_t *xop, const char *name);
313
314int
315xo_open_instance (const char *name);
316
317int
318xo_open_instance_hd (xo_handle_t *xop, const char *name);
319
320int
321xo_open_instance_d (const char *name);
322
323int
324xo_close_instance_h (xo_handle_t *xop, const char *name);
325
326int
327xo_close_instance (const char *name);
328
329int
330xo_close_instance_hd (xo_handle_t *xop);
331
332int
333xo_close_instance_d (void);
334
335int
336xo_open_marker_h (xo_handle_t *xop, const char *name);
337
338int
339xo_open_marker (const char *name);
340
341int
342xo_close_marker_h (xo_handle_t *xop, const char *name);
343
344int
345xo_close_marker (const char *name);
346
347int
348xo_attr_h (xo_handle_t *xop, const char *name, const char *fmt, ...);
349
350int
351xo_attr_hv (xo_handle_t *xop, const char *name, const char *fmt, va_list vap);
352
353int
354xo_attr (const char *name, const char *fmt, ...);
355
356void
357xo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap);
358
359void
360xo_error_h (xo_handle_t *xop, const char *fmt, ...);
361
362void
363xo_error (const char *fmt, ...);
364
365int
366xo_flush_h (xo_handle_t *xop);
367
368int
369xo_flush (void);
370
371int
372xo_finish_h (xo_handle_t *xop);
373
374int
375xo_finish (void);
376
377void
378xo_finish_atexit (void);
379
380void
381xo_set_leading_xpath (xo_handle_t *xop, const char *path);
382
383void
384xo_warn_hc (xo_handle_t *xop, int code, const char *fmt, ...) PRINTFLIKE(3, 4);
385
386void
387xo_warn_c (int code, const char *fmt, ...) PRINTFLIKE(2, 3);
388
389void
390xo_warn (const char *fmt, ...) PRINTFLIKE(1, 2);
391
392void
393xo_warnx (const char *fmt, ...) PRINTFLIKE(1, 2);
394
395void
396xo_err (int eval, const char *fmt, ...) NORETURN PRINTFLIKE(2, 3);
397
398void
399xo_errx (int eval, const char *fmt, ...) NORETURN PRINTFLIKE(2, 3);
400
401void
402xo_errc (int eval, int code, const char *fmt, ...) NORETURN PRINTFLIKE(3, 4);
403
404void
405xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap) PRINTFLIKE(3, 0);
406
407void
408xo_message_hc (xo_handle_t *xop, int code, const char *fmt, ...) PRINTFLIKE(3, 4);
409
410void
411xo_message_c (int code, const char *fmt, ...) PRINTFLIKE(2, 3);
412
413void
414xo_message_e (const char *fmt, ...) PRINTFLIKE(1, 2);
415
416void
417xo_message (const char *fmt, ...) PRINTFLIKE(1, 2);
418
419void
420xo_emit_warn_hcv (xo_handle_t *xop, int as_warning, int code,
421 const char *fmt, va_list vap);
422
423void
424xo_emit_warn_hc (xo_handle_t *xop, int code, const char *fmt, ...);
425
426void
427xo_emit_warn_c (int code, const char *fmt, ...);
428
429void
430xo_emit_warn (const char *fmt, ...);
431
432void
433xo_emit_warnx (const char *fmt, ...);
434
435void
436xo_emit_err (int eval, const char *fmt, ...) NORETURN;
437
438void
439xo_emit_errx (int eval, const char *fmt, ...) NORETURN;
440
441void
442xo_emit_errc (int eval, int code, const char *fmt, ...) NORETURN;
443
444PRINTFLIKE(4, 0)
445static inline void
446xo_emit_warn_hcvp (xo_handle_t *xop, int as_warning, int code,
447 const char *fmt, va_list vap)
448{
449 xo_emit_warn_hcv(xop, as_warning, code, fmt, vap);
450}
451
452PRINTFLIKE(3, 4)
453static inline void
454xo_emit_warn_hcp (xo_handle_t *xop, int code, const char *fmt, ...)
455{
456 va_list vap;
457 va_start(vap, fmt);
458 xo_emit_warn_hcv(xop, 1, code, fmt, vap);
459 va_end(vap);
460}
461
462PRINTFLIKE(2, 3)
463static inline void
464xo_emit_warn_cp (int code, const char *fmt, ...)
465{
466 va_list vap;
467 va_start(vap, fmt);
468 xo_emit_warn_hcv(NULL, 1, code, fmt, vap);
469 va_end(vap);
470}
471
472PRINTFLIKE(1, 2)
473static inline void
474xo_emit_warn_p (const char *fmt, ...)
475{
476 int code = errno;
477 va_list vap;
478 va_start(vap, fmt);
479 xo_emit_warn_hcv(NULL, 1, code, fmt, vap);
480 va_end(vap);
481}
482
483PRINTFLIKE(1, 2)
484static inline void
485xo_emit_warnx_p (const char *fmt, ...)
486{
487 va_list vap;
488 va_start(vap, fmt);
489 xo_emit_warn_hcv(NULL, 1, -1, fmt, vap);
490 va_end(vap);
491}
492
493NORETURN PRINTFLIKE(2, 3)
494static inline void
495xo_emit_err_p (int eval, const char *fmt, ...)
496{
497 int code = errno;
498 va_list vap;
499 va_start(vap, fmt);
500 xo_emit_warn_hcv(NULL, 0, code, fmt, vap);
501 va_end(vap);
502
503 exit(eval);
504}
505
506PRINTFLIKE(2, 3)
507static inline void
508xo_emit_errx_p (int eval, const char *fmt, ...)
509{
510 va_list vap;
511 va_start(vap, fmt);
512 xo_emit_warn_hcv(NULL, 0, -1, fmt, vap);
513 va_end(vap);
514 exit(eval);
515}
516
517PRINTFLIKE(3, 4)
518static inline void
519xo_emit_errc_p (int eval, int code, const char *fmt, ...)
520{
521 va_list vap;
522 va_start(vap, fmt);
523 xo_emit_warn_hcv(NULL, 0, code, fmt, vap);
524 va_end(vap);
525 exit(eval);
526}
527
528void
529xo_emit_err_v (int eval, int code, const char *fmt, va_list vap) NORETURN PRINTFLIKE(3, 0);
530
531void
532xo_no_setlocale (void);
533
534/**
535 * @brief Lift libxo-specific arguments from a set of arguments
536 *
537 * libxo-enable programs typically use command line options to enable
538 * all the nifty-cool libxo features. xo_parse_args() makes this simple
539 * by pre-processing the command line arguments given to main(), handling
540 * and removing the libxo-specific ones, meaning anything starting with
541 * "--libxo". A full description of these arguments is in the base
542 * documentation.
543 * @param[in] argc Number of arguments (ala #main())
544 * @param[in] argc Array of argument strings (ala #main())
545 * @return New number of arguments, or -1 for failure.
546 */
547int
548xo_parse_args (int argc, char **argv);
549
550/**
551 * This is the "magic" number returned by libxo-supporting commands
552 * when passed the equally magic "--libxo-check" option. If you
553 * return this, we can (unsafely) assume that since you know the magic
554 * handshake, you'll happily handle future --libxo options and not do
555 * something violent like reboot the box or create another hole in the
556 * ozone layer.
557 */
558#define XO_HAS_LIBXO 121
559
560/**
561 * externs for libxo's version number strings
562 */
563extern const char xo_version[]; /** Base version triple string */
564extern const char xo_version_extra[]; /** Extra version magic content */
565
566/**
567 * @brief Dump the internal stack of a libxo handle.
568 *
569 * This diagnostic function is something I will ask you to call from
570 * your program when you write to tell me libxo has gone bat-stink
571 * crazy and has discarded your list or container or content. Output
572 * content will be what we lovingly call "developer entertainment".
573 * @param[in] xop A valid libxo handle, or NULL for the default handle
574 */
575void
576xo_dump_stack (xo_handle_t *xop);
577
578/**
579 * @brief Recode the name of the program, suitable for error output.
580 *
581 * libxo will record the given name for use while generating error
582 * messages. The contents are not copied, so the value must continue
583 * to point to a valid memory location. This allows the caller to change
584 * the value, but requires the caller to manage the memory. Typically
585 * this is called with argv[0] from main().
586 * @param[in] name The name of the current application program
587 */
588void
589xo_set_program (const char *name);
590
591/**
592 * @brief Add a version string to the output, where possible.
593 *
594 * Adds a version number to the output, suitable for tracking
595 * changes in the content. This is only important for the "encoding"
596 * format styles (XML and JSON) and allows a user of the data to
597 * discern which version of the data model is in use.
598 * @param[in] version The version number, encoded as a string
599 */
600void
601xo_set_version (const char *version);
602
603/**
604 * #xo_set_version with a handle.
605 * @param[in] xop A valid libxo handle, or NULL for the default handle
606 * @param[in] version The version number, encoded as a string
607 */
608void
609xo_set_version_h (xo_handle_t *xop, const char *version);
610
611void
612xo_open_log (const char *ident, int logopt, int facility);
613
614void
615xo_close_log (void);
616
617int
618xo_set_logmask (int maskpri);
619
620void
621xo_set_unit_test_mode (int value);
622
623void
624xo_syslog (int priority, const char *name, const char *message, ...);
625
626void
627xo_vsyslog (int priority, const char *name, const char *message, va_list args);
628
629typedef void (*xo_syslog_open_t)(void);
630typedef void (*xo_syslog_send_t)(const char *full_msg,
631 const char *v0_hdr, const char *text_only);
632typedef void (*xo_syslog_close_t)(void);
633
634void
635xo_set_syslog_handler (xo_syslog_open_t open_func, xo_syslog_send_t send_func,
636 xo_syslog_close_t close_func);
637
638void
639xo_set_syslog_enterprise_id (unsigned short eid);
640
641typedef void (*xo_simplify_field_func_t)(const char *, unsigned, int);
642
643char *
644xo_simplify_format (xo_handle_t *xop, const char *fmt, int with_numbers,
645 xo_simplify_field_func_t field_cb);
646
647int
648xo_emit_field_hv (xo_handle_t *xop, const char *rolmod, const char *contents,
649 const char *fmt, const char *efmt,
650 va_list vap);
651
652int
653xo_emit_field_h (xo_handle_t *xop, const char *rolmod, const char *contents,
654 const char *fmt, const char *efmt, ...);
655
656int
657xo_emit_field (const char *rolmod, const char *contents,
658 const char *fmt, const char *efmt, ...);
659
660void
661xo_retain_clear_all (void);
662
663void
664xo_retain_clear (const char *fmt);
665
596#endif /* INCLUDE_XO_H */
666#endif /* INCLUDE_XO_H */