1273562Smarcel/*
2287111Smarcel * Copyright (c) 2014-2015, Juniper Networks, Inc.
3273562Smarcel * All rights reserved.
4273562Smarcel * This SOFTWARE is licensed under the LICENSE provided in the
5273562Smarcel * ../Copyright file. By downloading, installing, copying, or otherwise
6273562Smarcel * using the SOFTWARE, you agree to be bound by the terms of that
7273562Smarcel * LICENSE.
8273562Smarcel * Phil Shafer, July 2014
9273562Smarcel */
10273562Smarcel
11273562Smarcel/**
12282100Smarcel * libxo provides a means of generating text, XML, JSON, and HTML output
13273562Smarcel * using a single set of function calls, maximizing the value of output
14273562Smarcel * while minimizing the cost/impact on the code.
15287111Smarcel *
16287111Smarcel * Full documentation is available in ./doc/libxo.txt or online at:
17287111Smarcel *   http://juniper.github.io/libxo/libxo-manual.html
18273562Smarcel */
19273562Smarcel
20273562Smarcel#ifndef INCLUDE_XO_H
21273562Smarcel#define INCLUDE_XO_H
22273562Smarcel
23287111Smarcel#include <stdio.h>
24282100Smarcel#include <sys/types.h>
25287111Smarcel#include <stdarg.h>
26322172Sphil#include <limits.h>
27287111Smarcel#include <stdlib.h>
28287111Smarcel#include <errno.h>
29282100Smarcel
30282100Smarcel#ifdef __dead2
31282100Smarcel#define NORETURN __dead2
32282100Smarcel#else
33282100Smarcel#define NORETURN
34282100Smarcel#endif /* __dead2 */
35282100Smarcel
36282100Smarcel/*
37282100Smarcel * Normally we'd use the HAVE_PRINTFLIKE define triggered by the
38282100Smarcel * --enable-printflike option to configure, but we don't install
39282100Smarcel * our internal "xoconfig.h", and I'd rather not.  Taking the
40282100Smarcel * coward's path, we'll turn it on inside a #if that allows
41282100Smarcel * others to turn it off where needed.  Not ideal, but functional.
42282100Smarcel */
43322172Sphil#if !defined(NO_PRINTFLIKE)
44322172Sphil#if defined(__linux) && !defined(__printflike)
45322172Sphil#define __printflike(_x, _y) __attribute__((__format__ (__printf__, _x, _y)))
46322172Sphil#endif
47282100Smarcel#define PRINTFLIKE(_x, _y) __printflike(_x, _y)
48282100Smarcel#else
49282100Smarcel#define PRINTFLIKE(_x, _y)
50282100Smarcel#endif /* NO_PRINTFLIKE */
51282100Smarcel
52273562Smarcel/** Formatting types */
53287111Smarceltypedef unsigned short xo_style_t;
54273562Smarcel#define XO_STYLE_TEXT	0	/** Generate text output */
55273562Smarcel#define XO_STYLE_XML	1	/** Generate XML output */
56273562Smarcel#define XO_STYLE_JSON	2	/** Generate JSON output */
57273562Smarcel#define XO_STYLE_HTML	3	/** Generate HTML output */
58287111Smarcel#define XO_STYLE_SDPARAMS 4	/* Generate syslog structured data params */
59287111Smarcel#define XO_STYLE_ENCODER 5	/* Generate calls to external encoder */
60273562Smarcel
61273562Smarcel/** Flags for libxo */
62277353Smarceltypedef unsigned long long xo_xof_flags_t;
63277353Smarcel#define XOF_BIT(_n) ((xo_xof_flags_t) 1 << (_n))
64277353Smarcel#define XOF_CLOSE_FP	XOF_BIT(0) /** Close file pointer on xo_close() */
65277353Smarcel#define XOF_PRETTY	XOF_BIT(1) /** Make 'pretty printed' output */
66287111Smarcel#define XOF_LOG_SYSLOG	XOF_BIT(2) /** Log (on stderr) our syslog content */
67287111Smarcel#define XOF_RESV3	XOF_BIT(3) /* Unused */
68273562Smarcel
69277353Smarcel#define XOF_WARN	XOF_BIT(4) /** Generate warnings for broken calls */
70277353Smarcel#define XOF_XPATH	XOF_BIT(5) /** Emit XPath attributes in HTML  */
71277353Smarcel#define XOF_INFO	XOF_BIT(6) /** Emit additional info fields (HTML) */
72277353Smarcel#define XOF_WARN_XML	XOF_BIT(7) /** Emit warnings in XML (on stdout) */
73273562Smarcel
74277353Smarcel#define XOF_NO_ENV	XOF_BIT(8) /** Don't look at LIBXO_OPTIONS env var */
75277353Smarcel#define XOF_NO_VA_ARG	XOF_BIT(9) /** Don't advance va_list w/ va_arg() */
76277353Smarcel#define XOF_DTRT	XOF_BIT(10) /** Enable "do the right thing" mode */
77277353Smarcel#define XOF_KEYS	XOF_BIT(11) /** Flag 'key' fields for xml and json */
78273562Smarcel
79277353Smarcel#define XOF_IGNORE_CLOSE XOF_BIT(12) /** Ignore errors on close tags */
80277353Smarcel#define XOF_NOT_FIRST	XOF_BIT(13) /* Not the first item (JSON)  */
81277353Smarcel#define XOF_NO_LOCALE	XOF_BIT(14) /** Don't bother with locale */
82287111Smarcel#define XOF_RESV15	XOF_BIT(15) /* Unused */
83273562Smarcel
84277353Smarcel#define XOF_NO_TOP	XOF_BIT(16) /** Don't emit the top braces in JSON */
85287111Smarcel#define XOF_RESV17	XOF_BIT(17) /* Unused  */
86277353Smarcel#define XOF_UNITS	XOF_BIT(18) /** Encode units in XML */
87287111Smarcel#define XOF_RESV19	XOF_BIT(19) /* Unused */
88273562Smarcel
89277353Smarcel#define XOF_UNDERSCORES	XOF_BIT(20) /** Replace dashes with underscores (JSON)*/
90277353Smarcel#define XOF_COLUMNS	XOF_BIT(21) /** xo_emit should return a column count */
91277353Smarcel#define XOF_FLUSH	XOF_BIT(22) /** Flush after each xo_emit call */
92277353Smarcel#define XOF_FLUSH_LINE	XOF_BIT(23) /** Flush after each newline */
93273562Smarcel
94277353Smarcel#define XOF_NO_CLOSE	XOF_BIT(24) /** xo_finish won't close open elements */
95282100Smarcel#define XOF_COLOR_ALLOWED XOF_BIT(25) /** Allow color/effects to be enabled */
96282100Smarcel#define XOF_COLOR	XOF_BIT(26) /** Enable color and effects */
97287111Smarcel#define XOF_NO_HUMANIZE	XOF_BIT(27) /** Block the {h:} modifier */
98277353Smarcel
99287111Smarcel#define XOF_LOG_GETTEXT	XOF_BIT(28) /** Log (stderr) gettext lookup strings */
100287111Smarcel#define XOF_UTF8	XOF_BIT(29) /** Force text output to be UTF8 */
101298083Sphil#define XOF_RETAIN_ALL	XOF_BIT(30) /** Force use of XOEF_RETAIN */
102298083Sphil#define XOF_RETAIN_NONE	XOF_BIT(31) /** Prevent use of XOEF_RETAIN */
103287111Smarcel
104322172Sphil#define XOF_COLOR_MAP	XOF_BIT(32) /** Color map has been initialized */
105322172Sphil
106298083Sphiltypedef unsigned xo_emit_flags_t; /* Flags to xo_emit() and friends */
107298083Sphil#define XOEF_RETAIN	(1<<0)	  /* Retain parsed formatting information */
108298083Sphil
109273562Smarcel/*
110273562Smarcel * The xo_info_t structure provides a mapping between names and
111273562Smarcel * additional data emitted via HTML.
112273562Smarcel */
113273562Smarceltypedef struct xo_info_s {
114273562Smarcel    const char *xi_name;	/* Name of the element */
115273562Smarcel    const char *xi_type;	/* Type of field */
116273562Smarcel    const char *xi_help;	/* Description of field */
117273562Smarcel} xo_info_t;
118273562Smarcel
119287111Smarcel#define XO_INFO_NULL NULL, NULL, NULL /* Use '{ XO_INFO_NULL }' to end lists */
120287111Smarcel
121273562Smarcelstruct xo_handle_s;		/* Opaque structure forward */
122273562Smarceltypedef struct xo_handle_s xo_handle_t; /* Handle for XO output */
123273562Smarcel
124322172Sphil/*
125322172Sphil * Early versions of the API used "int" instead of "size_t" for buffer
126322172Sphil * sizes.  We want to fix this but allow for backwards compatibility
127322172Sphil * where needed.
128322172Sphil */
129322172Sphil#ifdef USE_INT_RETURN_CODES
130322172Sphiltypedef int xo_ssize_t;		/* Buffer size */
131322172Sphil#else /* USE_INT_RETURN_CODES */
132322172Sphiltypedef ssize_t xo_ssize_t;	/* Buffer size */
133322172Sphil#endif /* USE_INT_RETURN_CODES */
134322172Sphil
135322172Sphiltypedef xo_ssize_t (*xo_write_func_t)(void *, const char *);
136273562Smarceltypedef void (*xo_close_func_t)(void *);
137277353Smarceltypedef int (*xo_flush_func_t)(void *);
138273562Smarceltypedef void *(*xo_realloc_func_t)(void *, size_t);
139273562Smarceltypedef void (*xo_free_func_t)(void *);
140273562Smarcel
141273562Smarcel/*
142273562Smarcel * The formatter function mirrors "vsnprintf", with an additional argument
143273562Smarcel * of the xo handle.  The caller should return the number of bytes _needed_
144273562Smarcel * to fit the data, even if this exceeds 'len'.
145273562Smarcel */
146322172Sphiltypedef xo_ssize_t (*xo_formatter_t)(xo_handle_t *, char *, xo_ssize_t,
147273562Smarcel				const char *, va_list);
148273562Smarceltypedef void (*xo_checkpointer_t)(xo_handle_t *, va_list, int);
149273562Smarcel
150273562Smarcelxo_handle_t *
151273562Smarcelxo_create (xo_style_t style, xo_xof_flags_t flags);
152273562Smarcel
153273562Smarcelxo_handle_t *
154273562Smarcelxo_create_to_file (FILE *fp, xo_style_t style, xo_xof_flags_t flags);
155273562Smarcel
156273562Smarcelvoid
157273562Smarcelxo_destroy (xo_handle_t *xop);
158273562Smarcel
159273562Smarcelvoid
160273562Smarcelxo_set_writer (xo_handle_t *xop, void *opaque, xo_write_func_t write_func,
161277353Smarcel	       xo_close_func_t close_func, xo_flush_func_t flush_func);
162273562Smarcel
163273562Smarcelvoid
164273562Smarcelxo_set_allocator (xo_realloc_func_t realloc_func, xo_free_func_t free_func);
165273562Smarcel
166273562Smarcelvoid
167273562Smarcelxo_set_style (xo_handle_t *xop, xo_style_t style);
168273562Smarcel
169273562Smarcelxo_style_t
170273562Smarcelxo_get_style (xo_handle_t *xop);
171273562Smarcel
172273562Smarcelint
173273562Smarcelxo_set_style_name (xo_handle_t *xop, const char *style);
174273562Smarcel
175273562Smarcelint
176273562Smarcelxo_set_options (xo_handle_t *xop, const char *input);
177273562Smarcel
178273562Smarcelxo_xof_flags_t
179273562Smarcelxo_get_flags (xo_handle_t *xop);
180273562Smarcel
181273562Smarcelvoid
182273562Smarcelxo_set_flags (xo_handle_t *xop, xo_xof_flags_t flags);
183273562Smarcel
184273562Smarcelvoid
185273562Smarcelxo_clear_flags (xo_handle_t *xop, xo_xof_flags_t flags);
186273562Smarcel
187298083Sphilint
188298083Sphilxo_set_file_h (xo_handle_t *xop, FILE *fp);
189298083Sphil
190298083Sphilint
191298083Sphilxo_set_file (FILE *fp);
192298083Sphil
193273562Smarcelvoid
194273562Smarcelxo_set_info (xo_handle_t *xop, xo_info_t *infop, int count);
195273562Smarcel
196273562Smarcelvoid
197273562Smarcelxo_set_formatter (xo_handle_t *xop, xo_formatter_t func, xo_checkpointer_t);
198273562Smarcel
199273562Smarcelvoid
200273562Smarcelxo_set_depth (xo_handle_t *xop, int depth);
201273562Smarcel
202322172Sphilxo_ssize_t
203273562Smarcelxo_emit_hv (xo_handle_t *xop, const char *fmt, va_list vap);
204273562Smarcel
205322172Sphilxo_ssize_t
206273562Smarcelxo_emit_h (xo_handle_t *xop, const char *fmt, ...);
207273562Smarcel
208322172Sphilxo_ssize_t
209273562Smarcelxo_emit (const char *fmt, ...);
210273562Smarcel
211322172Sphilxo_ssize_t
212298083Sphilxo_emit_hvf (xo_handle_t *xop, xo_emit_flags_t flags,
213298083Sphil	     const char *fmt, va_list vap);
214298083Sphil
215322172Sphilxo_ssize_t
216298083Sphilxo_emit_hf (xo_handle_t *xop, xo_emit_flags_t flags, const char *fmt, ...);
217298083Sphil
218322172Sphilxo_ssize_t
219298083Sphilxo_emit_f (xo_emit_flags_t flags, const char *fmt, ...);
220298083Sphil
221287111SmarcelPRINTFLIKE(2, 0)
222287111Smarcelstatic inline int
223287111Smarcelxo_emit_hvp (xo_handle_t *xop, const char *fmt, va_list vap)
224287111Smarcel{
225287111Smarcel    return xo_emit_hv(xop, fmt, vap);
226287111Smarcel}
227287111Smarcel
228287111SmarcelPRINTFLIKE(2, 3)
229287111Smarcelstatic inline int
230287111Smarcelxo_emit_hp (xo_handle_t *xop, const char *fmt, ...)
231287111Smarcel{
232287111Smarcel    va_list vap;
233287111Smarcel    va_start(vap, fmt);
234287111Smarcel    int rc = xo_emit_hv(xop, fmt, vap);
235287111Smarcel    va_end(vap);
236287111Smarcel    return rc;
237287111Smarcel}
238287111Smarcel
239287111SmarcelPRINTFLIKE(1, 2)
240287111Smarcelstatic inline int
241287111Smarcelxo_emit_p (const char *fmt, ...)
242287111Smarcel{
243287111Smarcel    va_list vap;
244287111Smarcel    va_start(vap, fmt);
245287111Smarcel    int rc = xo_emit_hv(NULL, fmt, vap);
246287111Smarcel    va_end(vap);
247287111Smarcel    return rc;
248287111Smarcel}
249287111Smarcel
250298083SphilPRINTFLIKE(3, 0)
251298083Sphilstatic inline int
252298083Sphilxo_emit_hvfp (xo_handle_t *xop, xo_emit_flags_t flags,
253298083Sphil	      const char *fmt, va_list vap)
254298083Sphil{
255298083Sphil    return xo_emit_hvf(xop, flags, fmt, vap);
256298083Sphil}
257298083Sphil
258298083SphilPRINTFLIKE(3, 4)
259298083Sphilstatic inline int
260298083Sphilxo_emit_hfp (xo_handle_t *xop, xo_emit_flags_t flags, const char *fmt, ...)
261298083Sphil{
262298083Sphil    va_list vap;
263298083Sphil    va_start(vap, fmt);
264298083Sphil    int rc = xo_emit_hvf(xop, flags, fmt, vap);
265298083Sphil    va_end(vap);
266298083Sphil    return rc;
267298083Sphil}
268298083Sphil
269298083SphilPRINTFLIKE(2, 3)
270298083Sphilstatic inline int
271298083Sphilxo_emit_fp (xo_emit_flags_t flags, const char *fmt, ...)
272298083Sphil{
273298083Sphil    va_list vap;
274298083Sphil    va_start(vap, fmt);
275298083Sphil    int rc = xo_emit_hvf(NULL, flags, fmt, vap);
276298083Sphil    va_end(vap);
277298083Sphil    return rc;
278298083Sphil}
279298083Sphil
280322172Sphilxo_ssize_t
281273562Smarcelxo_open_container_h (xo_handle_t *xop, const char *name);
282273562Smarcel
283322172Sphilxo_ssize_t
284273562Smarcelxo_open_container (const char *name);
285273562Smarcel
286322172Sphilxo_ssize_t
287273562Smarcelxo_open_container_hd (xo_handle_t *xop, const char *name);
288273562Smarcel
289322172Sphilxo_ssize_t
290273562Smarcelxo_open_container_d (const char *name);
291273562Smarcel
292322172Sphilxo_ssize_t
293273562Smarcelxo_close_container_h (xo_handle_t *xop, const char *name);
294273562Smarcel
295322172Sphilxo_ssize_t
296273562Smarcelxo_close_container (const char *name);
297273562Smarcel
298322172Sphilxo_ssize_t
299273562Smarcelxo_close_container_hd (xo_handle_t *xop);
300273562Smarcel
301322172Sphilxo_ssize_t
302273562Smarcelxo_close_container_d (void);
303273562Smarcel
304322172Sphilxo_ssize_t
305273562Smarcelxo_open_list_h (xo_handle_t *xop, const char *name);
306273562Smarcel
307322172Sphilxo_ssize_t
308273562Smarcelxo_open_list (const char *name);
309273562Smarcel
310322172Sphilxo_ssize_t
311273562Smarcelxo_open_list_hd (xo_handle_t *xop, const char *name);
312273562Smarcel
313322172Sphilxo_ssize_t
314273562Smarcelxo_open_list_d (const char *name);
315273562Smarcel
316322172Sphilxo_ssize_t
317273562Smarcelxo_close_list_h (xo_handle_t *xop, const char *name);
318273562Smarcel
319322172Sphilxo_ssize_t
320273562Smarcelxo_close_list (const char *name);
321273562Smarcel
322322172Sphilxo_ssize_t
323273562Smarcelxo_close_list_hd (xo_handle_t *xop);
324273562Smarcel
325322172Sphilxo_ssize_t
326273562Smarcelxo_close_list_d (void);
327273562Smarcel
328322172Sphilxo_ssize_t
329273562Smarcelxo_open_instance_h (xo_handle_t *xop, const char *name);
330273562Smarcel
331322172Sphilxo_ssize_t
332273562Smarcelxo_open_instance (const char *name);
333273562Smarcel
334322172Sphilxo_ssize_t
335273562Smarcelxo_open_instance_hd (xo_handle_t *xop, const char *name);
336273562Smarcel
337322172Sphilxo_ssize_t
338273562Smarcelxo_open_instance_d (const char *name);
339273562Smarcel
340322172Sphilxo_ssize_t
341273562Smarcelxo_close_instance_h (xo_handle_t *xop, const char *name);
342273562Smarcel
343322172Sphilxo_ssize_t
344273562Smarcelxo_close_instance (const char *name);
345273562Smarcel
346322172Sphilxo_ssize_t
347273562Smarcelxo_close_instance_hd (xo_handle_t *xop);
348273562Smarcel
349322172Sphilxo_ssize_t
350273562Smarcelxo_close_instance_d (void);
351273562Smarcel
352322172Sphilxo_ssize_t
353277353Smarcelxo_open_marker_h (xo_handle_t *xop, const char *name);
354277353Smarcel
355322172Sphilxo_ssize_t
356277353Smarcelxo_open_marker (const char *name);
357277353Smarcel
358322172Sphilxo_ssize_t
359277353Smarcelxo_close_marker_h (xo_handle_t *xop, const char *name);
360277353Smarcel
361322172Sphilxo_ssize_t
362277353Smarcelxo_close_marker (const char *name);
363277353Smarcel
364322172Sphilxo_ssize_t
365273562Smarcelxo_attr_h (xo_handle_t *xop, const char *name, const char *fmt, ...);
366273562Smarcel
367322172Sphilxo_ssize_t
368273562Smarcelxo_attr_hv (xo_handle_t *xop, const char *name, const char *fmt, va_list vap);
369273562Smarcel
370322172Sphilxo_ssize_t
371273562Smarcelxo_attr (const char *name, const char *fmt, ...);
372273562Smarcel
373273562Smarcelvoid
374273562Smarcelxo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap);
375273562Smarcel
376273562Smarcelvoid
377273562Smarcelxo_error_h (xo_handle_t *xop, const char *fmt, ...);
378273562Smarcel
379273562Smarcelvoid
380273562Smarcelxo_error (const char *fmt, ...);
381273562Smarcel
382322172Sphilxo_ssize_t
383273562Smarcelxo_flush_h (xo_handle_t *xop);
384273562Smarcel
385322172Sphilxo_ssize_t
386273562Smarcelxo_flush (void);
387273562Smarcel
388322172Sphilxo_ssize_t
389273562Smarcelxo_finish_h (xo_handle_t *xop);
390273562Smarcel
391322172Sphilxo_ssize_t
392273562Smarcelxo_finish (void);
393273562Smarcel
394273562Smarcelvoid
395287111Smarcelxo_finish_atexit (void);
396287111Smarcel
397287111Smarcelvoid
398273562Smarcelxo_set_leading_xpath (xo_handle_t *xop, const char *path);
399273562Smarcel
400273562Smarcelvoid
401282100Smarcelxo_warn_hc (xo_handle_t *xop, int code, const char *fmt, ...) PRINTFLIKE(3, 4);
402273562Smarcel
403273562Smarcelvoid
404282100Smarcelxo_warn_c (int code, const char *fmt, ...) PRINTFLIKE(2, 3);
405273562Smarcel
406273562Smarcelvoid
407282100Smarcelxo_warn (const char *fmt, ...) PRINTFLIKE(1, 2);
408273562Smarcel
409273562Smarcelvoid
410282100Smarcelxo_warnx (const char *fmt, ...) PRINTFLIKE(1, 2);
411273562Smarcel
412273562Smarcelvoid
413282100Smarcelxo_err (int eval, const char *fmt, ...) NORETURN PRINTFLIKE(2, 3);
414273562Smarcel
415273562Smarcelvoid
416282100Smarcelxo_errx (int eval, const char *fmt, ...) NORETURN PRINTFLIKE(2, 3);
417273562Smarcel
418273562Smarcelvoid
419282100Smarcelxo_errc (int eval, int code, const char *fmt, ...) NORETURN PRINTFLIKE(3, 4);
420273562Smarcel
421273562Smarcelvoid
422287111Smarcelxo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap) PRINTFLIKE(3, 0);
423273562Smarcel
424273562Smarcelvoid
425282100Smarcelxo_message_hc (xo_handle_t *xop, int code, const char *fmt, ...) PRINTFLIKE(3, 4);
426273562Smarcel
427273562Smarcelvoid
428282100Smarcelxo_message_c (int code, const char *fmt, ...) PRINTFLIKE(2, 3);
429273562Smarcel
430273562Smarcelvoid
431287111Smarcelxo_message_e (const char *fmt, ...) PRINTFLIKE(1, 2);
432287111Smarcel
433287111Smarcelvoid
434282100Smarcelxo_message (const char *fmt, ...) PRINTFLIKE(1, 2);
435273562Smarcel
436273562Smarcelvoid
437287111Smarcelxo_emit_warn_hcv (xo_handle_t *xop, int as_warning, int code,
438287111Smarcel		  const char *fmt, va_list vap);
439287111Smarcel
440287111Smarcelvoid
441287111Smarcelxo_emit_warn_hc (xo_handle_t *xop, int code, const char *fmt, ...);
442287111Smarcel
443287111Smarcelvoid
444287111Smarcelxo_emit_warn_c (int code, const char *fmt, ...);
445287111Smarcel
446287111Smarcelvoid
447287111Smarcelxo_emit_warn (const char *fmt, ...);
448287111Smarcel
449287111Smarcelvoid
450287111Smarcelxo_emit_warnx (const char *fmt, ...);
451287111Smarcel
452287111Smarcelvoid
453287111Smarcelxo_emit_err (int eval, const char *fmt, ...) NORETURN;
454287111Smarcel
455287111Smarcelvoid
456287111Smarcelxo_emit_errx (int eval, const char *fmt, ...) NORETURN;
457287111Smarcel
458287111Smarcelvoid
459287111Smarcelxo_emit_errc (int eval, int code, const char *fmt, ...) NORETURN;
460287111Smarcel
461287111SmarcelPRINTFLIKE(4, 0)
462287111Smarcelstatic inline void
463287111Smarcelxo_emit_warn_hcvp (xo_handle_t *xop, int as_warning, int code,
464287111Smarcel		  const char *fmt, va_list vap)
465287111Smarcel{
466287111Smarcel    xo_emit_warn_hcv(xop, as_warning, code, fmt, vap);
467287111Smarcel}
468287111Smarcel
469287111SmarcelPRINTFLIKE(3, 4)
470287111Smarcelstatic inline void
471287111Smarcelxo_emit_warn_hcp (xo_handle_t *xop, int code, const char *fmt, ...)
472287111Smarcel{
473287111Smarcel    va_list vap;
474287111Smarcel    va_start(vap, fmt);
475287111Smarcel    xo_emit_warn_hcv(xop, 1, code, fmt, vap);
476287111Smarcel    va_end(vap);
477287111Smarcel}
478287111Smarcel
479287111SmarcelPRINTFLIKE(2, 3)
480287111Smarcelstatic inline void
481287111Smarcelxo_emit_warn_cp (int code, const char *fmt, ...)
482287111Smarcel{
483287111Smarcel    va_list vap;
484287111Smarcel    va_start(vap, fmt);
485287111Smarcel    xo_emit_warn_hcv(NULL, 1, code, fmt, vap);
486287111Smarcel    va_end(vap);
487287111Smarcel}
488287111Smarcel
489287111SmarcelPRINTFLIKE(1, 2)
490287111Smarcelstatic inline void
491287111Smarcelxo_emit_warn_p (const char *fmt, ...)
492287111Smarcel{
493287111Smarcel    int code = errno;
494287111Smarcel    va_list vap;
495287111Smarcel    va_start(vap, fmt);
496287111Smarcel    xo_emit_warn_hcv(NULL, 1, code, fmt, vap);
497287111Smarcel    va_end(vap);
498287111Smarcel}
499287111Smarcel
500287111SmarcelPRINTFLIKE(1, 2)
501287111Smarcelstatic inline void
502287111Smarcelxo_emit_warnx_p (const char *fmt, ...)
503287111Smarcel{
504287111Smarcel    va_list vap;
505287111Smarcel    va_start(vap, fmt);
506287111Smarcel    xo_emit_warn_hcv(NULL, 1, -1, fmt, vap);
507287111Smarcel    va_end(vap);
508287111Smarcel}
509287111Smarcel
510287111SmarcelNORETURN PRINTFLIKE(2, 3)
511287111Smarcelstatic inline void
512287111Smarcelxo_emit_err_p (int eval, const char *fmt, ...)
513287111Smarcel{
514287111Smarcel    int code = errno;
515287111Smarcel    va_list vap;
516287111Smarcel    va_start(vap, fmt);
517287111Smarcel    xo_emit_warn_hcv(NULL, 0, code, fmt, vap);
518287111Smarcel    va_end(vap);
519287111Smarcel
520287111Smarcel    exit(eval);
521287111Smarcel}
522287111Smarcel
523287111SmarcelPRINTFLIKE(2, 3)
524287111Smarcelstatic inline void
525287111Smarcelxo_emit_errx_p (int eval, const char *fmt, ...)
526287111Smarcel{
527287111Smarcel    va_list vap;
528287111Smarcel    va_start(vap, fmt);
529287111Smarcel    xo_emit_warn_hcv(NULL, 0, -1, fmt, vap);
530287111Smarcel    va_end(vap);
531287111Smarcel    exit(eval);
532287111Smarcel}
533287111Smarcel
534287111SmarcelPRINTFLIKE(3, 4)
535287111Smarcelstatic inline void
536287111Smarcelxo_emit_errc_p (int eval, int code, const char *fmt, ...)
537287111Smarcel{
538287111Smarcel    va_list vap;
539287111Smarcel    va_start(vap, fmt);
540287111Smarcel    xo_emit_warn_hcv(NULL, 0, code, fmt, vap);
541287111Smarcel    va_end(vap);
542287111Smarcel    exit(eval);
543287111Smarcel}
544287111Smarcel
545287111Smarcelvoid
546287111Smarcelxo_emit_err_v (int eval, int code, const char *fmt, va_list vap) NORETURN PRINTFLIKE(3, 0);
547287111Smarcel
548287111Smarcelvoid
549273562Smarcelxo_no_setlocale (void);
550273562Smarcel
551282100Smarcel/**
552282100Smarcel * @brief Lift libxo-specific arguments from a set of arguments
553282100Smarcel *
554282100Smarcel * libxo-enable programs typically use command line options to enable
555282100Smarcel * all the nifty-cool libxo features.  xo_parse_args() makes this simple
556282100Smarcel * by pre-processing the command line arguments given to main(), handling
557282100Smarcel * and removing the libxo-specific ones, meaning anything starting with
558282100Smarcel * "--libxo".  A full description of these arguments is in the base
559282100Smarcel * documentation.
560282100Smarcel * @param[in] argc Number of arguments (ala #main())
561282100Smarcel * @param[in] argc Array of argument strings (ala #main())
562282100Smarcel * @return New number of arguments, or -1 for failure.
563282100Smarcel */
564273562Smarcelint
565273562Smarcelxo_parse_args (int argc, char **argv);
566273562Smarcel
567282100Smarcel/**
568273562Smarcel * This is the "magic" number returned by libxo-supporting commands
569273562Smarcel * when passed the equally magic "--libxo-check" option.  If you
570282100Smarcel * return this, we can (unsafely) assume that since you know the magic
571282100Smarcel * handshake, you'll happily handle future --libxo options and not do
572282100Smarcel * something violent like reboot the box or create another hole in the
573282100Smarcel * ozone layer.
574273562Smarcel */
575273562Smarcel#define XO_HAS_LIBXO	121
576273562Smarcel
577282100Smarcel/**
578282100Smarcel * externs for libxo's version number strings
579273562Smarcel */
580282100Smarcelextern const char xo_version[];	      /** Base version triple string */
581282100Smarcelextern const char xo_version_extra[]; /** Extra version magic content */
582273562Smarcel
583282100Smarcel/**
584282100Smarcel * @brief Dump the internal stack of a libxo handle.
585282100Smarcel *
586282100Smarcel * This diagnostic function is something I will ask you to call from
587282100Smarcel * your program when you write to tell me libxo has gone bat-stink
588282100Smarcel * crazy and has discarded your list or container or content.  Output
589282100Smarcel * content will be what we lovingly call "developer entertainment".
590282100Smarcel * @param[in] xop A valid libxo handle, or NULL for the default handle
591282100Smarcel */
592277353Smarcelvoid
593277353Smarcelxo_dump_stack (xo_handle_t *xop);
594277353Smarcel
595282100Smarcel/**
596282100Smarcel * @brief Recode the name of the program, suitable for error output.
597282100Smarcel *
598282100Smarcel * libxo will record the given name for use while generating error
599282100Smarcel * messages.  The contents are not copied, so the value must continue
600282100Smarcel * to point to a valid memory location.  This allows the caller to change
601282100Smarcel * the value, but requires the caller to manage the memory.  Typically
602282100Smarcel * this is called with argv[0] from main().
603282100Smarcel * @param[in] name The name of the current application program
604282100Smarcel */
605277353Smarcelvoid
606277353Smarcelxo_set_program (const char *name);
607277353Smarcel
608282100Smarcel/**
609282100Smarcel * @brief Add a version string to the output, where possible.
610282100Smarcel *
611282100Smarcel * Adds a version number to the output, suitable for tracking
612282100Smarcel * changes in the content.  This is only important for the "encoding"
613282100Smarcel * format styles (XML and JSON) and allows a user of the data to
614282100Smarcel * discern which version of the data model is in use.
615282100Smarcel * @param[in] version The version number, encoded as a string
616282100Smarcel */
617282100Smarcelvoid
618282100Smarcelxo_set_version (const char *version);
619282100Smarcel
620282100Smarcel/**
621282100Smarcel * #xo_set_version with a handle.
622282100Smarcel * @param[in] xop A valid libxo handle, or NULL for the default handle
623282100Smarcel * @param[in] version The version number, encoded as a string
624282100Smarcel */
625282100Smarcelvoid
626282100Smarcelxo_set_version_h (xo_handle_t *xop, const char *version);
627282100Smarcel
628287111Smarcelvoid
629287111Smarcelxo_open_log (const char *ident, int logopt, int facility);
630287111Smarcel
631287111Smarcelvoid
632287111Smarcelxo_close_log (void);
633287111Smarcel
634287111Smarcelint
635287111Smarcelxo_set_logmask (int maskpri);
636287111Smarcel
637287111Smarcelvoid
638287111Smarcelxo_set_unit_test_mode (int value);
639287111Smarcel
640287111Smarcelvoid
641287111Smarcelxo_syslog (int priority, const char *name, const char *message, ...);
642287111Smarcel
643287111Smarcelvoid
644287111Smarcelxo_vsyslog (int priority, const char *name, const char *message, va_list args);
645287111Smarcel
646287111Smarceltypedef void (*xo_syslog_open_t)(void);
647287111Smarceltypedef void (*xo_syslog_send_t)(const char *full_msg,
648287111Smarcel				 const char *v0_hdr, const char *text_only);
649287111Smarceltypedef void (*xo_syslog_close_t)(void);
650287111Smarcel
651287111Smarcelvoid
652287111Smarcelxo_set_syslog_handler (xo_syslog_open_t open_func, xo_syslog_send_t send_func,
653287111Smarcel		       xo_syslog_close_t close_func);
654287111Smarcel
655287111Smarcelvoid
656287111Smarcelxo_set_syslog_enterprise_id (unsigned short eid);
657287111Smarcel
658287111Smarceltypedef void (*xo_simplify_field_func_t)(const char *, unsigned, int);
659287111Smarcel
660287111Smarcelchar *
661287111Smarcelxo_simplify_format (xo_handle_t *xop, const char *fmt, int with_numbers,
662287111Smarcel		    xo_simplify_field_func_t field_cb);
663287111Smarcel
664322172Sphilxo_ssize_t
665298083Sphilxo_emit_field_hv (xo_handle_t *xop, const char *rolmod, const char *contents,
666298083Sphil		  const char *fmt, const char *efmt,
667298083Sphil		  va_list vap);
668298083Sphil
669322172Sphilxo_ssize_t
670298083Sphilxo_emit_field_h (xo_handle_t *xop, const char *rolmod, const char *contents,
671298083Sphil		 const char *fmt, const char *efmt, ...);
672298083Sphil
673322172Sphilxo_ssize_t
674298083Sphilxo_emit_field (const char *rolmod, const char *contents,
675298083Sphil	       const char *fmt, const char *efmt, ...);
676298083Sphil
677298083Sphilvoid
678298083Sphilxo_retain_clear_all (void);
679298083Sphil
680298083Sphilvoid
681298083Sphilxo_retain_clear (const char *fmt);
682298083Sphil
683273562Smarcel#endif /* INCLUDE_XO_H */
684