]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libxo/libxo/xo.h
Update mandoc to 20160116
[FreeBSD/FreeBSD.git] / contrib / libxo / libxo / xo.h
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 */
49 typedef 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 */
58 typedef 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
98 /*
99  * The xo_info_t structure provides a mapping between names and
100  * additional data emitted via HTML.
101  */
102 typedef 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
110 struct xo_handle_s;             /* Opaque structure forward */
111 typedef struct xo_handle_s xo_handle_t; /* Handle for XO output */
112
113 typedef int (*xo_write_func_t)(void *, const char *);
114 typedef void (*xo_close_func_t)(void *);
115 typedef int (*xo_flush_func_t)(void *);
116 typedef void *(*xo_realloc_func_t)(void *, size_t);
117 typedef 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  */
124 typedef int (*xo_formatter_t)(xo_handle_t *, char *, int,
125                                 const char *, va_list);
126 typedef void (*xo_checkpointer_t)(xo_handle_t *, va_list, int);
127
128 xo_handle_t *
129 xo_create (xo_style_t style, xo_xof_flags_t flags);
130
131 xo_handle_t *
132 xo_create_to_file (FILE *fp, xo_style_t style, xo_xof_flags_t flags);
133
134 void
135 xo_destroy (xo_handle_t *xop);
136
137 void
138 xo_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
141 void
142 xo_set_allocator (xo_realloc_func_t realloc_func, xo_free_func_t free_func);
143
144 void
145 xo_set_style (xo_handle_t *xop, xo_style_t style);
146
147 xo_style_t
148 xo_get_style (xo_handle_t *xop);
149
150 int
151 xo_set_style_name (xo_handle_t *xop, const char *style);
152
153 int
154 xo_set_options (xo_handle_t *xop, const char *input);
155
156 xo_xof_flags_t
157 xo_get_flags (xo_handle_t *xop);
158
159 void
160 xo_set_flags (xo_handle_t *xop, xo_xof_flags_t flags);
161
162 void
163 xo_clear_flags (xo_handle_t *xop, xo_xof_flags_t flags);
164
165 void
166 xo_set_info (xo_handle_t *xop, xo_info_t *infop, int count);
167
168 void
169 xo_set_formatter (xo_handle_t *xop, xo_formatter_t func, xo_checkpointer_t);
170
171 void
172 xo_set_depth (xo_handle_t *xop, int depth);
173
174 int
175 xo_emit_hv (xo_handle_t *xop, const char *fmt, va_list vap);
176
177 int
178 xo_emit_h (xo_handle_t *xop, const char *fmt, ...);
179
180 int
181 xo_emit (const char *fmt, ...);
182
183 PRINTFLIKE(2, 0)
184 static inline int
185 xo_emit_hvp (xo_handle_t *xop, const char *fmt, va_list vap)
186 {
187     return xo_emit_hv(xop, fmt, vap);
188 }
189
190 PRINTFLIKE(2, 3)
191 static inline int
192 xo_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
201 PRINTFLIKE(1, 2)
202 static inline int
203 xo_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
212 int
213 xo_open_container_h (xo_handle_t *xop, const char *name);
214
215 int
216 xo_open_container (const char *name);
217
218 int
219 xo_open_container_hd (xo_handle_t *xop, const char *name);
220
221 int
222 xo_open_container_d (const char *name);
223
224 int
225 xo_close_container_h (xo_handle_t *xop, const char *name);
226
227 int
228 xo_close_container (const char *name);
229
230 int
231 xo_close_container_hd (xo_handle_t *xop);
232
233 int
234 xo_close_container_d (void);
235
236 int
237 xo_open_list_h (xo_handle_t *xop, const char *name);
238
239 int
240 xo_open_list (const char *name);
241
242 int
243 xo_open_list_hd (xo_handle_t *xop, const char *name);
244
245 int
246 xo_open_list_d (const char *name);
247
248 int
249 xo_close_list_h (xo_handle_t *xop, const char *name);
250
251 int
252 xo_close_list (const char *name);
253
254 int
255 xo_close_list_hd (xo_handle_t *xop);
256
257 int
258 xo_close_list_d (void);
259
260 int
261 xo_open_instance_h (xo_handle_t *xop, const char *name);
262
263 int
264 xo_open_instance (const char *name);
265
266 int
267 xo_open_instance_hd (xo_handle_t *xop, const char *name);
268
269 int
270 xo_open_instance_d (const char *name);
271
272 int
273 xo_close_instance_h (xo_handle_t *xop, const char *name);
274
275 int
276 xo_close_instance (const char *name);
277
278 int
279 xo_close_instance_hd (xo_handle_t *xop);
280
281 int
282 xo_close_instance_d (void);
283
284 int
285 xo_open_marker_h (xo_handle_t *xop, const char *name);
286
287 int
288 xo_open_marker (const char *name);
289
290 int
291 xo_close_marker_h (xo_handle_t *xop, const char *name);
292
293 int
294 xo_close_marker (const char *name);
295
296 int
297 xo_attr_h (xo_handle_t *xop, const char *name, const char *fmt, ...);
298
299 int
300 xo_attr_hv (xo_handle_t *xop, const char *name, const char *fmt, va_list vap);
301
302 int
303 xo_attr (const char *name, const char *fmt, ...);
304
305 void
306 xo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap);
307
308 void
309 xo_error_h (xo_handle_t *xop, const char *fmt, ...);
310
311 void
312 xo_error (const char *fmt, ...);
313
314 int
315 xo_flush_h (xo_handle_t *xop);
316
317 int
318 xo_flush (void);
319
320 int
321 xo_finish_h (xo_handle_t *xop);
322
323 int
324 xo_finish (void);
325
326 void
327 xo_finish_atexit (void);
328
329 void
330 xo_set_leading_xpath (xo_handle_t *xop, const char *path);
331
332 void
333 xo_warn_hc (xo_handle_t *xop, int code, const char *fmt, ...) PRINTFLIKE(3, 4);
334
335 void
336 xo_warn_c (int code, const char *fmt, ...) PRINTFLIKE(2, 3);
337
338 void
339 xo_warn (const char *fmt, ...) PRINTFLIKE(1, 2);
340
341 void
342 xo_warnx (const char *fmt, ...) PRINTFLIKE(1, 2);
343
344 void
345 xo_err (int eval, const char *fmt, ...) NORETURN PRINTFLIKE(2, 3);
346
347 void
348 xo_errx (int eval, const char *fmt, ...) NORETURN PRINTFLIKE(2, 3);
349
350 void
351 xo_errc (int eval, int code, const char *fmt, ...) NORETURN PRINTFLIKE(3, 4);
352
353 void
354 xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap) PRINTFLIKE(3, 0);
355
356 void
357 xo_message_hc (xo_handle_t *xop, int code, const char *fmt, ...) PRINTFLIKE(3, 4);
358
359 void
360 xo_message_c (int code, const char *fmt, ...) PRINTFLIKE(2, 3);
361
362 void
363 xo_message_e (const char *fmt, ...) PRINTFLIKE(1, 2);
364
365 void
366 xo_message (const char *fmt, ...) PRINTFLIKE(1, 2);
367
368 void
369 xo_emit_warn_hcv (xo_handle_t *xop, int as_warning, int code,
370                   const char *fmt, va_list vap);
371
372 void
373 xo_emit_warn_hc (xo_handle_t *xop, int code, const char *fmt, ...);
374
375 void
376 xo_emit_warn_c (int code, const char *fmt, ...);
377
378 void
379 xo_emit_warn (const char *fmt, ...);
380
381 void
382 xo_emit_warnx (const char *fmt, ...);
383
384 void
385 xo_emit_err (int eval, const char *fmt, ...) NORETURN;
386
387 void
388 xo_emit_errx (int eval, const char *fmt, ...) NORETURN;
389
390 void
391 xo_emit_errc (int eval, int code, const char *fmt, ...) NORETURN;
392
393 PRINTFLIKE(4, 0)
394 static inline void
395 xo_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
401 PRINTFLIKE(3, 4)
402 static inline void
403 xo_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
411 PRINTFLIKE(2, 3)
412 static inline void
413 xo_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
421 PRINTFLIKE(1, 2)
422 static inline void
423 xo_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
432 PRINTFLIKE(1, 2)
433 static inline void
434 xo_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
442 NORETURN PRINTFLIKE(2, 3)
443 static inline void
444 xo_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
455 PRINTFLIKE(2, 3)
456 static inline void
457 xo_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
466 PRINTFLIKE(3, 4)
467 static inline void
468 xo_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
477 void
478 xo_emit_err_v (int eval, int code, const char *fmt, va_list vap) NORETURN PRINTFLIKE(3, 0);
479
480 void
481 xo_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  */
496 int
497 xo_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  */
512 extern const char xo_version[];       /** Base version triple string */
513 extern 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  */
524 void
525 xo_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  */
537 void
538 xo_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  */
549 void
550 xo_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  */
557 void
558 xo_set_version_h (xo_handle_t *xop, const char *version);
559
560 void
561 xo_open_log (const char *ident, int logopt, int facility);
562
563 void
564 xo_close_log (void);
565
566 int
567 xo_set_logmask (int maskpri);
568
569 void
570 xo_set_unit_test_mode (int value);
571
572 void
573 xo_syslog (int priority, const char *name, const char *message, ...);
574
575 void
576 xo_vsyslog (int priority, const char *name, const char *message, va_list args);
577
578 typedef void (*xo_syslog_open_t)(void);
579 typedef void (*xo_syslog_send_t)(const char *full_msg,
580                                  const char *v0_hdr, const char *text_only);
581 typedef void (*xo_syslog_close_t)(void);
582
583 void
584 xo_set_syslog_handler (xo_syslog_open_t open_func, xo_syslog_send_t send_func,
585                        xo_syslog_close_t close_func);
586
587 void
588 xo_set_syslog_enterprise_id (unsigned short eid);
589
590 typedef void (*xo_simplify_field_func_t)(const char *, unsigned, int);
591
592 char *
593 xo_simplify_format (xo_handle_t *xop, const char *fmt, int with_numbers,
594                     xo_simplify_field_func_t field_cb);
595
596 #endif /* INCLUDE_XO_H */