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