1*d4a07e70Sfengbojiang.. index:: API 2*d4a07e70Sfengbojiang 3*d4a07e70SfengbojiangThe libxo API 4*d4a07e70Sfengbojiang============= 5*d4a07e70Sfengbojiang 6*d4a07e70SfengbojiangThis section gives details about the functions in libxo, how to call 7*d4a07e70Sfengbojiangthem, and the actions they perform. 8*d4a07e70Sfengbojiang 9*d4a07e70Sfengbojiang.. index:: Handles 10*d4a07e70Sfengbojiang.. _handles: 11*d4a07e70Sfengbojiang 12*d4a07e70SfengbojiangHandles 13*d4a07e70Sfengbojiang------- 14*d4a07e70Sfengbojiang 15*d4a07e70Sfengbojianglibxo uses "handles" to control its rendering functionality. The 16*d4a07e70Sfengbojianghandle contains state and buffered data, as well as callback functions 17*d4a07e70Sfengbojiangto process data. 18*d4a07e70Sfengbojiang 19*d4a07e70SfengbojiangHandles give an abstraction for libxo that encapsulates the state of a 20*d4a07e70Sfengbojiangstream of output. Handles have the data type "`xo_handle_t`" and are 21*d4a07e70Sfengbojiangopaque to the caller. 22*d4a07e70Sfengbojiang 23*d4a07e70SfengbojiangThe library has a default handle that is automatically initialized. 24*d4a07e70SfengbojiangBy default, this handle will send text style output (`XO_STYLE_TEXT`) to 25*d4a07e70Sfengbojiangstandard output. The xo_set_style and xo_set_flags functions can be 26*d4a07e70Sfengbojiangused to change this behavior. 27*d4a07e70Sfengbojiang 28*d4a07e70SfengbojiangFor the typical command that is generating output on standard output, 29*d4a07e70Sfengbojiangthere is no need to create an explicit handle, but they are available 30*d4a07e70Sfengbojiangwhen needed, e.g., for daemons that generate multiple streams of 31*d4a07e70Sfengbojiangoutput. 32*d4a07e70Sfengbojiang 33*d4a07e70SfengbojiangMany libxo functions take a handle as their first parameter; most that 34*d4a07e70Sfengbojiangdo not use the default handle. Any function taking a handle can be 35*d4a07e70Sfengbojiangpassed NULL to access the default handle. For the convenience of 36*d4a07e70Sfengbojiangcallers, the libxo library includes handle-less functions that 37*d4a07e70Sfengbojiangimplicitly use the default handle. 38*d4a07e70Sfengbojiang 39*d4a07e70SfengbojiangFor example, the following are equivalent:: 40*d4a07e70Sfengbojiang 41*d4a07e70Sfengbojiang xo_emit("test"); 42*d4a07e70Sfengbojiang xo_emit_h(NULL, "test"); 43*d4a07e70Sfengbojiang 44*d4a07e70SfengbojiangHandles are created using `xo_create` and destroy using 45*d4a07e70Sfengbojiang`xo_destroy`. 46*d4a07e70Sfengbojiang 47*d4a07e70Sfengbojiang.. index:: xo_create 48*d4a07e70Sfengbojiang 49*d4a07e70Sfengbojiangxo_create 50*d4a07e70Sfengbojiang~~~~~~~~~ 51*d4a07e70Sfengbojiang 52*d4a07e70Sfengbojiang.. c:function:: xo_handle_t *xo_create (xo_style_t style, xo_xof_flags_t flags) 53*d4a07e70Sfengbojiang 54*d4a07e70Sfengbojiang The `xo_create` function allocates a new handle which can be passed 55*d4a07e70Sfengbojiang to further libxo function calls. The `xo_handle_t` structure is 56*d4a07e70Sfengbojiang opaque. 57*d4a07e70Sfengbojiang 58*d4a07e70Sfengbojiang :param xo_style_t style: Output style (XO_STYLE\_*) 59*d4a07e70Sfengbojiang :param xo_xof_flags_t flags: Flags for this handle (XOF\_*) 60*d4a07e70Sfengbojiang :return: New libxo handle 61*d4a07e70Sfengbojiang :rtype: xo_handle_t \* 62*d4a07e70Sfengbojiang 63*d4a07e70Sfengbojiang :: 64*d4a07e70Sfengbojiang 65*d4a07e70Sfengbojiang EXAMPLE: 66*d4a07e70Sfengbojiang xo_handle_t *xop = xo_create(XO_STYLE_JSON, XOF_WARN | XOF_PRETTY); 67*d4a07e70Sfengbojiang .... 68*d4a07e70Sfengbojiang xo_emit_h(xop, "testing\n"); 69*d4a07e70Sfengbojiang 70*d4a07e70Sfengbojiang See also :ref:`output-styles` and :ref:`flags`. 71*d4a07e70Sfengbojiang 72*d4a07e70Sfengbojiang.. index:: xo_create_to_file 73*d4a07e70Sfengbojiang.. index:: XOF_CLOSE_FP 74*d4a07e70Sfengbojiang 75*d4a07e70Sfengbojiangxo_create_to_file 76*d4a07e70Sfengbojiang~~~~~~~~~~~~~~~~~ 77*d4a07e70Sfengbojiang 78*d4a07e70Sfengbojiang.. c:function:: 79*d4a07e70Sfengbojiang xo_handle_t *xo_create_to_file (FILE *fp, unsigned style, unsigned flags) 80*d4a07e70Sfengbojiang 81*d4a07e70Sfengbojiang The `xo_create_to_file` function is aconvenience function is 82*d4a07e70Sfengbojiang provided for situations when output should be written to a different 83*d4a07e70Sfengbojiang file, rather than the default of standard output. 84*d4a07e70Sfengbojiang 85*d4a07e70Sfengbojiang The `XOF_CLOSE_FP` flag can be set on the returned handle to trigger a 86*d4a07e70Sfengbojiang call to fclose() for the FILE pointer when the handle is destroyed, 87*d4a07e70Sfengbojiang avoiding the need for the caller to perform this task. 88*d4a07e70Sfengbojiang 89*d4a07e70Sfengbojiang :param fp: FILE to use as base for this handle 90*d4a07e70Sfengbojiang :type fp: FILE * 91*d4a07e70Sfengbojiang :param xo_style_t style: Output style (XO_STYLE\_*) 92*d4a07e70Sfengbojiang :param xo_xof_flags_t flags: Flags for this handle (XOF\_*) 93*d4a07e70Sfengbojiang :return: New libxo handle 94*d4a07e70Sfengbojiang :rtype: xo_handle_t \* 95*d4a07e70Sfengbojiang 96*d4a07e70Sfengbojiang.. index:: xo_set_writer 97*d4a07e70Sfengbojiang.. index:: xo_write_func_t 98*d4a07e70Sfengbojiang.. index:: xo_close_func_t 99*d4a07e70Sfengbojiang.. index:: xo_flush_func_t 100*d4a07e70Sfengbojiang 101*d4a07e70Sfengbojiangxo_set_writer 102*d4a07e70Sfengbojiang~~~~~~~~~~~~~ 103*d4a07e70Sfengbojiang 104*d4a07e70Sfengbojiang.. c:function:: 105*d4a07e70Sfengbojiang void xo_set_writer (xo_handle_t *xop, void *opaque, \ 106*d4a07e70Sfengbojiang xo_write_func_t write_func, xo_close_func_t close_func, \ 107*d4a07e70Sfengbojiang xo_flush_func_t flush_func) 108*d4a07e70Sfengbojiang 109*d4a07e70Sfengbojiang The `xo_set_writer` function allows custom functions which can 110*d4a07e70Sfengbojiang tailor how libxo writes data. The `opaque` argument is recorded and 111*d4a07e70Sfengbojiang passed back to the functions, allowing the function to acquire 112*d4a07e70Sfengbojiang context information. The *write_func* function writes data to the 113*d4a07e70Sfengbojiang output stream. The *close_func* function can release this opaque 114*d4a07e70Sfengbojiang data and any other resources as needed. The *flush_func* function 115*d4a07e70Sfengbojiang is called to flush buffered data associated with the opaque object. 116*d4a07e70Sfengbojiang 117*d4a07e70Sfengbojiang :param xop: Handle to modify (or NULL for default handle) 118*d4a07e70Sfengbojiang :type xop: xo_handle_t * 119*d4a07e70Sfengbojiang :param opaque: Pointer to opaque data passed to the given functions 120*d4a07e70Sfengbojiang :type opaque: void * 121*d4a07e70Sfengbojiang :param xo_write_func_t write_func: New write function 122*d4a07e70Sfengbojiang :param xo_close_func_t close_func: New close function 123*d4a07e70Sfengbojiang :param xo_flush_func_t flush_func: New flush function 124*d4a07e70Sfengbojiang :returns: void 125*d4a07e70Sfengbojiang 126*d4a07e70Sfengbojiang.. index:: xo_get_style 127*d4a07e70Sfengbojiang 128*d4a07e70Sfengbojiangxo_get_style 129*d4a07e70Sfengbojiang~~~~~~~~~~~~ 130*d4a07e70Sfengbojiang 131*d4a07e70Sfengbojiang.. c:function:: xo_style_t xo_get_style(xo_handle_t *xop) 132*d4a07e70Sfengbojiang 133*d4a07e70Sfengbojiang Use the `xo_get_style` function to find the current output style for 134*d4a07e70Sfengbojiang a given handle. To use the default handle, pass a `NULL` handle. 135*d4a07e70Sfengbojiang 136*d4a07e70Sfengbojiang :param xop: Handle to interrogate (or NULL for default handle) 137*d4a07e70Sfengbojiang :type xop: xo_handle_t * 138*d4a07e70Sfengbojiang :returns: Output style (XO_STYLE\_*) 139*d4a07e70Sfengbojiang :rtype: xo_style_t 140*d4a07e70Sfengbojiang 141*d4a07e70Sfengbojiang :: 142*d4a07e70Sfengbojiang 143*d4a07e70Sfengbojiang EXAMPLE:: 144*d4a07e70Sfengbojiang style = xo_get_style(NULL); 145*d4a07e70Sfengbojiang 146*d4a07e70Sfengbojiang.. index:: XO_STYLE_TEXT 147*d4a07e70Sfengbojiang.. index:: XO_STYLE_XML 148*d4a07e70Sfengbojiang.. index:: XO_STYLE_JSON 149*d4a07e70Sfengbojiang.. index:: XO_STYLE_HTML 150*d4a07e70Sfengbojiang 151*d4a07e70Sfengbojiang.. _output-styles: 152*d4a07e70Sfengbojiang 153*d4a07e70SfengbojiangOutput Styles (XO_STYLE\_\*) 154*d4a07e70Sfengbojiang++++++++++++++++++++++++++++ 155*d4a07e70Sfengbojiang 156*d4a07e70SfengbojiangThe libxo functions accept a set of output styles: 157*d4a07e70Sfengbojiang 158*d4a07e70Sfengbojiang =============== ========================= 159*d4a07e70Sfengbojiang Flag Description 160*d4a07e70Sfengbojiang =============== ========================= 161*d4a07e70Sfengbojiang XO_STYLE_TEXT Traditional text output 162*d4a07e70Sfengbojiang XO_STYLE_XML XML encoded data 163*d4a07e70Sfengbojiang XO_STYLE_JSON JSON encoded data 164*d4a07e70Sfengbojiang XO_STYLE_HTML HTML encoded data 165*d4a07e70Sfengbojiang =============== ========================= 166*d4a07e70Sfengbojiang 167*d4a07e70SfengbojiangThe "XML", "JSON", and "HTML" output styles all use the UTF-8 168*d4a07e70Sfengbojiangcharacter encoding. "TEXT" using locale-based encoding. 169*d4a07e70Sfengbojiang 170*d4a07e70Sfengbojiang.. index:: xo_set_style 171*d4a07e70Sfengbojiang 172*d4a07e70Sfengbojiangxo_set_style 173*d4a07e70Sfengbojiang~~~~~~~~~~~~ 174*d4a07e70Sfengbojiang 175*d4a07e70Sfengbojiang.. c:function:: void xo_set_style(xo_handle_t *xop, xo_style_t style) 176*d4a07e70Sfengbojiang 177*d4a07e70Sfengbojiang The `xo_set_style` function is used to change the output style 178*d4a07e70Sfengbojiang setting for a handle. To use the default handle, pass a `NULL` 179*d4a07e70Sfengbojiang handle. 180*d4a07e70Sfengbojiang 181*d4a07e70Sfengbojiang :param xop: Handle to modify 182*d4a07e70Sfengbojiang :type xop: xo_handle_t * 183*d4a07e70Sfengbojiang :param xo_style_t style: Output style (XO_STYLE\_*) 184*d4a07e70Sfengbojiang :returns: void 185*d4a07e70Sfengbojiang 186*d4a07e70Sfengbojiang :: 187*d4a07e70Sfengbojiang 188*d4a07e70Sfengbojiang EXAMPLE: 189*d4a07e70Sfengbojiang xo_set_style(NULL, XO_STYLE_XML); 190*d4a07e70Sfengbojiang 191*d4a07e70Sfengbojiang.. index:: xo_set_style_name 192*d4a07e70Sfengbojiang 193*d4a07e70Sfengbojiangxo_set_style_name 194*d4a07e70Sfengbojiang~~~~~~~~~~~~~~~~~ 195*d4a07e70Sfengbojiang 196*d4a07e70Sfengbojiang.. c:function:: int xo_set_style_name (xo_handle_t *xop, const char *style) 197*d4a07e70Sfengbojiang 198*d4a07e70Sfengbojiang The `xo_set_style_name` function can be used to set the style based 199*d4a07e70Sfengbojiang on a name encoded as a string: The name can be any of the supported 200*d4a07e70Sfengbojiang styles: "text", "xml", "json", or "html". 201*d4a07e70Sfengbojiang 202*d4a07e70Sfengbojiang :param xop: Handle for modify (or NULL for default handle) 203*d4a07e70Sfengbojiang :type xop: xo_handle_t \* 204*d4a07e70Sfengbojiang :param style: Text name of the style 205*d4a07e70Sfengbojiang :type style: const char \* 206*d4a07e70Sfengbojiang :returns: zero for success, non-zero for error 207*d4a07e70Sfengbojiang :rtype: int 208*d4a07e70Sfengbojiang 209*d4a07e70Sfengbojiang :: 210*d4a07e70Sfengbojiang 211*d4a07e70Sfengbojiang EXAMPLE: 212*d4a07e70Sfengbojiang xo_set_style_name(NULL, "html"); 213*d4a07e70Sfengbojiang 214*d4a07e70Sfengbojiang.. index:: xo_set_flags 215*d4a07e70Sfengbojiang 216*d4a07e70Sfengbojiangxo_set_flags 217*d4a07e70Sfengbojiang~~~~~~~~~~~~ 218*d4a07e70Sfengbojiang 219*d4a07e70Sfengbojiang.. c:function:: void xo_set_flags(xo_handle_t *xop, xo_xof_flags_t flags) 220*d4a07e70Sfengbojiang 221*d4a07e70Sfengbojiang :param xop: Handle for modify (or NULL for default handle) 222*d4a07e70Sfengbojiang :type xop: xo_handle_t \* 223*d4a07e70Sfengbojiang :param xo_xof_flags_t flags: Flags to add for the handle 224*d4a07e70Sfengbojiang :returns: void 225*d4a07e70Sfengbojiang 226*d4a07e70Sfengbojiang Use the `xo_set_flags` function to turn on flags for a given libxo 227*d4a07e70Sfengbojiang handle. To use the default handle, pass a `NULL` handle. 228*d4a07e70Sfengbojiang 229*d4a07e70Sfengbojiang :: 230*d4a07e70Sfengbojiang 231*d4a07e70Sfengbojiang EXAMPLE: 232*d4a07e70Sfengbojiang xo_set_flags(NULL, XOF_PRETTY | XOF_WARN); 233*d4a07e70Sfengbojiang 234*d4a07e70Sfengbojiang.. index:: Flags; XOF_* 235*d4a07e70Sfengbojiang.. index:: XOF_CLOSE_FP 236*d4a07e70Sfengbojiang.. index:: XOF_COLOR 237*d4a07e70Sfengbojiang.. index:: XOF_COLOR_ALLOWED 238*d4a07e70Sfengbojiang.. index:: XOF_DTRT 239*d4a07e70Sfengbojiang.. index:: XOF_INFO 240*d4a07e70Sfengbojiang.. index:: XOF_KEYS 241*d4a07e70Sfengbojiang.. index:: XOF_NO_ENV 242*d4a07e70Sfengbojiang.. index:: XOF_NO_HUMANIZE 243*d4a07e70Sfengbojiang.. index:: XOF_PRETTY 244*d4a07e70Sfengbojiang.. index:: XOF_UNDERSCORES 245*d4a07e70Sfengbojiang.. index:: XOF_UNITS 246*d4a07e70Sfengbojiang.. index:: XOF_WARN 247*d4a07e70Sfengbojiang.. index:: XOF_WARN_XML 248*d4a07e70Sfengbojiang.. index:: XOF_XPATH 249*d4a07e70Sfengbojiang.. index:: XOF_COLUMNS 250*d4a07e70Sfengbojiang.. index:: XOF_FLUSH 251*d4a07e70Sfengbojiang 252*d4a07e70Sfengbojiang.. _flags: 253*d4a07e70Sfengbojiang 254*d4a07e70SfengbojiangFlags (XOF\_\*) 255*d4a07e70Sfengbojiang+++++++++++++++ 256*d4a07e70Sfengbojiang 257*d4a07e70SfengbojiangThe set of valid flags include: 258*d4a07e70Sfengbojiang 259*d4a07e70Sfengbojiang =================== ========================================= 260*d4a07e70Sfengbojiang Flag Description 261*d4a07e70Sfengbojiang =================== ========================================= 262*d4a07e70Sfengbojiang XOF_CLOSE_FP Close file pointer on `xo_destroy` 263*d4a07e70Sfengbojiang XOF_COLOR Enable color and effects in output 264*d4a07e70Sfengbojiang XOF_COLOR_ALLOWED Allow color/effect for terminal output 265*d4a07e70Sfengbojiang XOF_DTRT Enable "do the right thing" mode 266*d4a07e70Sfengbojiang XOF_INFO Display info data attributes (HTML) 267*d4a07e70Sfengbojiang XOF_KEYS Emit the key attribute (XML) 268*d4a07e70Sfengbojiang XOF_NO_ENV Do not use the :ref:`libxo-options` env var 269*d4a07e70Sfengbojiang XOF_NO_HUMANIZE Display humanization (TEXT, HTML) 270*d4a07e70Sfengbojiang XOF_PRETTY Make "pretty printed" output 271*d4a07e70Sfengbojiang XOF_UNDERSCORES Replaces hyphens with underscores 272*d4a07e70Sfengbojiang XOF_UNITS Display units (XML, HMTL) 273*d4a07e70Sfengbojiang XOF_WARN Generate warnings for broken calls 274*d4a07e70Sfengbojiang XOF_WARN_XML Generate warnings in XML on stdout 275*d4a07e70Sfengbojiang XOF_XPATH Emit XPath expressions (HTML) 276*d4a07e70Sfengbojiang XOF_COLUMNS Force xo_emit to return columns used 277*d4a07e70Sfengbojiang XOF_FLUSH Flush output after each `xo_emit` call 278*d4a07e70Sfengbojiang =================== ========================================= 279*d4a07e70Sfengbojiang 280*d4a07e70SfengbojiangThe `XOF_CLOSE_FP` flag will trigger the call of the *close_func* 281*d4a07e70Sfengbojiang(provided via `xo_set_writer`) when the handle is destroyed. 282*d4a07e70Sfengbojiang 283*d4a07e70SfengbojiangThe `XOF_COLOR` flag enables color and effects in output regardless 284*d4a07e70Sfengbojiangof output device, while the `XOF_COLOR_ALLOWED` flag allows color 285*d4a07e70Sfengbojiangand effects only if the output device is a terminal. 286*d4a07e70Sfengbojiang 287*d4a07e70SfengbojiangThe `XOF_PRETTY` flag requests "pretty printing", which will trigger 288*d4a07e70Sfengbojiangthe addition of indentation and newlines to enhance the readability of 289*d4a07e70SfengbojiangXML, JSON, and HTML output. Text output is not affected. 290*d4a07e70Sfengbojiang 291*d4a07e70SfengbojiangThe `XOF_WARN` flag requests that warnings will trigger diagnostic 292*d4a07e70Sfengbojiangoutput (on standard error) when the library notices errors during 293*d4a07e70Sfengbojiangoperations, or with arguments to functions. Without warnings enabled, 294*d4a07e70Sfengbojiangsuch conditions are ignored. 295*d4a07e70Sfengbojiang 296*d4a07e70SfengbojiangWarnings allow developers to debug their interaction with libxo. 297*d4a07e70SfengbojiangThe function `xo_failure` can used as a breakpoint for a debugger, 298*d4a07e70Sfengbojiangregardless of whether warnings are enabled. 299*d4a07e70Sfengbojiang 300*d4a07e70SfengbojiangIf the style is `XO_STYLE_HTML`, the following additional flags can be 301*d4a07e70Sfengbojiangused: 302*d4a07e70Sfengbojiang 303*d4a07e70Sfengbojiang =============== ========================================= 304*d4a07e70Sfengbojiang Flag Description 305*d4a07e70Sfengbojiang =============== ========================================= 306*d4a07e70Sfengbojiang XOF_XPATH Emit "data-xpath" attributes 307*d4a07e70Sfengbojiang XOF_INFO Emit additional info fields 308*d4a07e70Sfengbojiang =============== ========================================= 309*d4a07e70Sfengbojiang 310*d4a07e70SfengbojiangThe `XOF_XPATH` flag enables the emission of XPath expressions detailing 311*d4a07e70Sfengbojiangthe hierarchy of XML elements used to encode the data field, if the 312*d4a07e70SfengbojiangXPATH style of output were requested. 313*d4a07e70Sfengbojiang 314*d4a07e70SfengbojiangThe `XOF_INFO` flag encodes additional informational fields for HTML 315*d4a07e70Sfengbojiangoutput. See :ref:`field-information` for details. 316*d4a07e70Sfengbojiang 317*d4a07e70SfengbojiangIf the style is `XO_STYLE_XML`, the following additional flags can be 318*d4a07e70Sfengbojiangused: 319*d4a07e70Sfengbojiang 320*d4a07e70Sfengbojiang =============== ========================================= 321*d4a07e70Sfengbojiang Flag Description 322*d4a07e70Sfengbojiang =============== ========================================= 323*d4a07e70Sfengbojiang XOF_KEYS Flag "key" fields for XML 324*d4a07e70Sfengbojiang =============== ========================================= 325*d4a07e70Sfengbojiang 326*d4a07e70SfengbojiangThe `XOF_KEYS` flag adds "key" attribute to the XML encoding for 327*d4a07e70Sfengbojiangfield definitions that use the "k" modifier. The key attribute has 328*d4a07e70Sfengbojiangthe value "key":: 329*d4a07e70Sfengbojiang 330*d4a07e70Sfengbojiang xo_emit("{k:name}", item); 331*d4a07e70Sfengbojiang 332*d4a07e70Sfengbojiang XML: 333*d4a07e70Sfengbojiang <name key="key">truck</name> 334*d4a07e70Sfengbojiang 335*d4a07e70Sfengbojiang.. index:: xo_clear_flags 336*d4a07e70Sfengbojiang 337*d4a07e70Sfengbojiangxo_clear_flags 338*d4a07e70Sfengbojiang++++++++++++++ 339*d4a07e70Sfengbojiang 340*d4a07e70Sfengbojiang.. c:function:: void xo_clear_flags (xo_handle_t *xop, xo_xof_flags_t flags) 341*d4a07e70Sfengbojiang 342*d4a07e70Sfengbojiang :param xop: Handle for modify (or NULL for default handle) 343*d4a07e70Sfengbojiang :type xop: xo_handle_t \* 344*d4a07e70Sfengbojiang :param xo_xof_flags_t flags: Flags to clear for the handle 345*d4a07e70Sfengbojiang :returns: void 346*d4a07e70Sfengbojiang 347*d4a07e70Sfengbojiang Use the `xo_clear_flags` function to turn off the given flags in a 348*d4a07e70Sfengbojiang specific handle. To use the default handle, pass a `NULL` handle. 349*d4a07e70Sfengbojiang 350*d4a07e70Sfengbojiang.. index:: xo_set_options 351*d4a07e70Sfengbojiang 352*d4a07e70Sfengbojiangxo_set_options 353*d4a07e70Sfengbojiang++++++++++++++ 354*d4a07e70Sfengbojiang 355*d4a07e70Sfengbojiang.. c:function:: int xo_set_options (xo_handle_t *xop, const char *input) 356*d4a07e70Sfengbojiang 357*d4a07e70Sfengbojiang :param xop: Handle for modify (or NULL for default handle) 358*d4a07e70Sfengbojiang :type xop: xo_handle_t \* 359*d4a07e70Sfengbojiang :param input: string containing options to set 360*d4a07e70Sfengbojiang :type input: const char * 361*d4a07e70Sfengbojiang :returns: zero for success, non-zero for error 362*d4a07e70Sfengbojiang :rtype: int 363*d4a07e70Sfengbojiang 364*d4a07e70Sfengbojiang The `xo_set_options` function accepts a comma-separated list of 365*d4a07e70Sfengbojiang output styles and modifier flags and enables them for a specific 366*d4a07e70Sfengbojiang handle. The options are identical to those listed in 367*d4a07e70Sfengbojiang :ref:`options`. To use the default handle, pass a `NULL` handle. 368*d4a07e70Sfengbojiang 369*d4a07e70Sfengbojiang.. index:: xo_destroy 370*d4a07e70Sfengbojiang 371*d4a07e70Sfengbojiangxo_destroy 372*d4a07e70Sfengbojiang++++++++++ 373*d4a07e70Sfengbojiang 374*d4a07e70Sfengbojiang.. c:function:: void xo_destroy(xo_handle_t *xop) 375*d4a07e70Sfengbojiang 376*d4a07e70Sfengbojiang :param xop: Handle for modify (or NULL for default handle) 377*d4a07e70Sfengbojiang :type xop: xo_handle_t \* 378*d4a07e70Sfengbojiang :returns: void 379*d4a07e70Sfengbojiang 380*d4a07e70Sfengbojiang The `xo_destroy` function releases a handle and any resources it is 381*d4a07e70Sfengbojiang using. Calling `xo_destroy` with a `NULL` handle will release any 382*d4a07e70Sfengbojiang resources associated with the default handle. 383*d4a07e70Sfengbojiang 384*d4a07e70Sfengbojiang.. index:: xo_emit 385*d4a07e70Sfengbojiang 386*d4a07e70SfengbojiangEmitting Content (xo_emit) 387*d4a07e70Sfengbojiang-------------------------- 388*d4a07e70Sfengbojiang 389*d4a07e70SfengbojiangThe functions in this section are used to emit output. 390*d4a07e70Sfengbojiang 391*d4a07e70SfengbojiangThe "fmt" argument is a string containing field descriptors as 392*d4a07e70Sfengbojiangspecified in :ref:`format-strings`. The use of a handle is optional and 393*d4a07e70Sfengbojiang`NULL` can be passed to access the internal "default" handle. See 394*d4a07e70Sfengbojiang:ref:`handles`. 395*d4a07e70Sfengbojiang 396*d4a07e70SfengbojiangThe remaining arguments to `xo_emit` and `xo_emit_h` are a set of 397*d4a07e70Sfengbojiangarguments corresponding to the fields in the format string. Care must 398*d4a07e70Sfengbojiangbe taken to ensure the argument types match the fields in the format 399*d4a07e70Sfengbojiangstring, since an inappropriate cast can ruin your day. The vap 400*d4a07e70Sfengbojiangargument to `xo_emit_hv` points to a variable argument list that can 401*d4a07e70Sfengbojiangbe used to retrieve arguments via `va_arg`. 402*d4a07e70Sfengbojiang 403*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_emit (const char *fmt, ...) 404*d4a07e70Sfengbojiang 405*d4a07e70Sfengbojiang :param fmt: The format string, followed by zero or more arguments 406*d4a07e70Sfengbojiang :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted 407*d4a07e70Sfengbojiang :rtype: xo_ssize_t 408*d4a07e70Sfengbojiang 409*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_emit_h (xo_handle_t *xop, const char *fmt, ...) 410*d4a07e70Sfengbojiang 411*d4a07e70Sfengbojiang :param xop: Handle for modify (or NULL for default handle) 412*d4a07e70Sfengbojiang :type xop: xo_handle_t \* 413*d4a07e70Sfengbojiang :param fmt: The format string, followed by zero or more arguments 414*d4a07e70Sfengbojiang :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted 415*d4a07e70Sfengbojiang :rtype: xo_ssize_t 416*d4a07e70Sfengbojiang 417*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_emit_hv (xo_handle_t *xop, const char *fmt, va_list vap) 418*d4a07e70Sfengbojiang 419*d4a07e70Sfengbojiang :param xop: Handle for modify (or NULL for default handle) 420*d4a07e70Sfengbojiang :type xop: xo_handle_t \* 421*d4a07e70Sfengbojiang :param fmt: The format string 422*d4a07e70Sfengbojiang :param va_list vap: A set of variadic arguments 423*d4a07e70Sfengbojiang :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted 424*d4a07e70Sfengbojiang :rtype: xo_ssize_t 425*d4a07e70Sfengbojiang 426*d4a07e70Sfengbojiang.. index:: xo_emit_field 427*d4a07e70Sfengbojiang 428*d4a07e70SfengbojiangSingle Field Emitting Functions (xo_emit_field) 429*d4a07e70Sfengbojiang~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 430*d4a07e70Sfengbojiang 431*d4a07e70SfengbojiangThe functions in this section can also make output, but only make a 432*d4a07e70Sfengbojiangsingle field at a time. These functions are intended to avoid the 433*d4a07e70Sfengbojiangscenario where one would otherwise need to compose a format 434*d4a07e70Sfengbojiangdescriptors using `snprintf`. The individual parts of the format 435*d4a07e70Sfengbojiangdescriptor are passed in distinctly. 436*d4a07e70Sfengbojiang 437*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_emit_field (const char *rolmod, const char *contents, const char *fmt, const char *efmt, ...) 438*d4a07e70Sfengbojiang 439*d4a07e70Sfengbojiang :param rolmod: A comma-separated list of field roles and field modifiers 440*d4a07e70Sfengbojiang :type rolmod: const char * 441*d4a07e70Sfengbojiang :param contents: The "contents" portion of the field description string 442*d4a07e70Sfengbojiang :type contents: const char * 443*d4a07e70Sfengbojiang :param fmt: Content format string 444*d4a07e70Sfengbojiang :type fmt: const char * 445*d4a07e70Sfengbojiang :param efmt: Encoding format string, followed by additional arguments 446*d4a07e70Sfengbojiang :type efmt: const char * 447*d4a07e70Sfengbojiang :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted 448*d4a07e70Sfengbojiang :rtype: xo_ssize_t 449*d4a07e70Sfengbojiang 450*d4a07e70Sfengbojiang :: 451*d4a07e70Sfengbojiang 452*d4a07e70Sfengbojiang EXAMPLE:: 453*d4a07e70Sfengbojiang xo_emit_field("T", "Host name is ", NULL, NULL); 454*d4a07e70Sfengbojiang xo_emit_field("V", "host-name", NULL, NULL, host-name); 455*d4a07e70Sfengbojiang 456*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_emit_field_h (xo_handle_t *xop, const char *rolmod, const char *contents, const char *fmt, const char *efmt, ...) 457*d4a07e70Sfengbojiang 458*d4a07e70Sfengbojiang :param xop: Handle for modify (or NULL for default handle) 459*d4a07e70Sfengbojiang :type xop: xo_handle_t \* 460*d4a07e70Sfengbojiang :param rolmod: A comma-separated list of field roles and field modifiers 461*d4a07e70Sfengbojiang :type rolmod: const char * 462*d4a07e70Sfengbojiang :param contents: The "contents" portion of the field description string 463*d4a07e70Sfengbojiang :type contents: const char * 464*d4a07e70Sfengbojiang :param fmt: Content format string 465*d4a07e70Sfengbojiang :type fmt: const char * 466*d4a07e70Sfengbojiang :param efmt: Encoding format string, followed by additional arguments 467*d4a07e70Sfengbojiang :type efmt: const char * 468*d4a07e70Sfengbojiang :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted 469*d4a07e70Sfengbojiang :rtype: xo_ssize_t 470*d4a07e70Sfengbojiang 471*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_emit_field_hv (xo_handle_t *xop, const char *rolmod, const char *contents, const char *fmt, const char *efmt, va_list vap) 472*d4a07e70Sfengbojiang 473*d4a07e70Sfengbojiang :param xop: Handle for modify (or NULL for default handle) 474*d4a07e70Sfengbojiang :type xop: xo_handle_t \* 475*d4a07e70Sfengbojiang :param rolmod: A comma-separated list of field roles and field modifiers 476*d4a07e70Sfengbojiang :type rolmod: const char * 477*d4a07e70Sfengbojiang :param contents: The "contents" portion of the field description string 478*d4a07e70Sfengbojiang :type contents: const char * 479*d4a07e70Sfengbojiang :param fmt: Content format string 480*d4a07e70Sfengbojiang :type fmt: const char * 481*d4a07e70Sfengbojiang :param efmt: Encoding format string 482*d4a07e70Sfengbojiang :type efmt: const char * 483*d4a07e70Sfengbojiang :param va_list vap: A set of variadic arguments 484*d4a07e70Sfengbojiang :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted 485*d4a07e70Sfengbojiang :rtype: xo_ssize_t 486*d4a07e70Sfengbojiang 487*d4a07e70Sfengbojiang.. index:: xo_attr 488*d4a07e70Sfengbojiang.. _xo_attr: 489*d4a07e70Sfengbojiang 490*d4a07e70SfengbojiangAttributes (xo_attr) 491*d4a07e70Sfengbojiang~~~~~~~~~~~~~~~~~~~~ 492*d4a07e70Sfengbojiang 493*d4a07e70SfengbojiangThe functions in this section emit an XML attribute with the given name 494*d4a07e70Sfengbojiangand value. This only affects the XML output style. 495*d4a07e70Sfengbojiang 496*d4a07e70SfengbojiangThe `name` parameter give the name of the attribute to be encoded. The 497*d4a07e70Sfengbojiang`fmt` parameter gives a printf-style format string used to format the 498*d4a07e70Sfengbojiangvalue of the attribute using any remaining arguments, or the vap 499*d4a07e70Sfengbojiangparameter passed to `xo_attr_hv`. 500*d4a07e70Sfengbojiang 501*d4a07e70SfengbojiangAll attributes recorded via `xo_attr` are placed on the next 502*d4a07e70Sfengbojiangcontainer, instance, leaf, or leaf list that is emitted. 503*d4a07e70Sfengbojiang 504*d4a07e70SfengbojiangSince attributes are only emitted in XML, their use should be limited 505*d4a07e70Sfengbojiangto meta-data and additional or redundant representations of data 506*d4a07e70Sfengbojiangalready emitted in other form. 507*d4a07e70Sfengbojiang 508*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_attr (const char *name, const char *fmt, ...) 509*d4a07e70Sfengbojiang 510*d4a07e70Sfengbojiang :param name: Attribute name 511*d4a07e70Sfengbojiang :type name: const char * 512*d4a07e70Sfengbojiang :param fmt: Attribute value, as variadic arguments 513*d4a07e70Sfengbojiang :type fmt: const char * 514*d4a07e70Sfengbojiang :returns: -1 for error, or the number of bytes in the formatted attribute value 515*d4a07e70Sfengbojiang :rtype: xo_ssize_t 516*d4a07e70Sfengbojiang 517*d4a07e70Sfengbojiang :: 518*d4a07e70Sfengbojiang 519*d4a07e70Sfengbojiang EXAMPLE: 520*d4a07e70Sfengbojiang xo_attr("seconds", "%ld", (unsigned long) login_time); 521*d4a07e70Sfengbojiang struct tm *tmp = localtime(login_time); 522*d4a07e70Sfengbojiang strftime(buf, sizeof(buf), "%R", tmp); 523*d4a07e70Sfengbojiang xo_emit("Logged in at {:login-time}\n", buf); 524*d4a07e70Sfengbojiang XML: 525*d4a07e70Sfengbojiang <login-time seconds="1408336270">00:14</login-time> 526*d4a07e70Sfengbojiang 527*d4a07e70Sfengbojiang 528*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_attr_h (xo_handle_t *xop, const char *name, const char *fmt, ...) 529*d4a07e70Sfengbojiang 530*d4a07e70Sfengbojiang :param xop: Handle for modify (or NULL for default handle) 531*d4a07e70Sfengbojiang :type xop: xo_handle_t \* 532*d4a07e70Sfengbojiang 533*d4a07e70Sfengbojiang The `xo_attr_h` function follows the conventions of `xo_attr` but 534*d4a07e70Sfengbojiang adds an explicit libxo handle. 535*d4a07e70Sfengbojiang 536*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_attr_hv (xo_handle_t *xop, const char *name, const char *fmt, va_list vap) 537*d4a07e70Sfengbojiang 538*d4a07e70Sfengbojiang The `xo_attr_h` function follows the conventions of `xo_attr_h` 539*d4a07e70Sfengbojiang but replaced the variadic list with a variadic pointer. 540*d4a07e70Sfengbojiang 541*d4a07e70Sfengbojiang.. index:: xo_flush 542*d4a07e70Sfengbojiang 543*d4a07e70SfengbojiangFlushing Output (xo_flush) 544*d4a07e70Sfengbojiang~~~~~~~~~~~~~~~~~~~~~~~~~~ 545*d4a07e70Sfengbojiang 546*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_flush (void) 547*d4a07e70Sfengbojiang 548*d4a07e70Sfengbojiang :returns: -1 for error, or the number of bytes generated 549*d4a07e70Sfengbojiang :rtype: xo_ssize_t 550*d4a07e70Sfengbojiang 551*d4a07e70Sfengbojiang libxo buffers data, both for performance and consistency, but also 552*d4a07e70Sfengbojiang to allow for the proper function of various advanced features. At 553*d4a07e70Sfengbojiang various times, the caller may wish to flush any data buffered within 554*d4a07e70Sfengbojiang the library. The `xo_flush` call is used for this. 555*d4a07e70Sfengbojiang 556*d4a07e70Sfengbojiang Calling `xo_flush` also triggers the flush function associated with 557*d4a07e70Sfengbojiang the handle. For the default handle, this is equivalent to 558*d4a07e70Sfengbojiang "fflush(stdio);". 559*d4a07e70Sfengbojiang 560*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_flush_h (xo_handle_t *xop) 561*d4a07e70Sfengbojiang 562*d4a07e70Sfengbojiang :param xop: Handle for flush (or NULL for default handle) 563*d4a07e70Sfengbojiang :type xop: xo_handle_t \* 564*d4a07e70Sfengbojiang :returns: -1 for error, or the number of bytes generated 565*d4a07e70Sfengbojiang :rtype: xo_ssize_t 566*d4a07e70Sfengbojiang 567*d4a07e70Sfengbojiang The `xo_flush_h` function follows the conventions of `xo_flush`, 568*d4a07e70Sfengbojiang but adds an explicit libxo handle. 569*d4a07e70Sfengbojiang 570*d4a07e70Sfengbojiang.. index:: xo_finish 571*d4a07e70Sfengbojiang.. index:: xo_finish_atexit 572*d4a07e70Sfengbojiang.. index:: atexit 573*d4a07e70Sfengbojiang 574*d4a07e70SfengbojiangFinishing Output (xo_finish) 575*d4a07e70Sfengbojiang~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 576*d4a07e70Sfengbojiang 577*d4a07e70SfengbojiangWhen the program is ready to exit or close a handle, a call to 578*d4a07e70Sfengbojiang`xo_finish` or `xo_finish_h` is required. This flushes any buffered 579*d4a07e70Sfengbojiangdata, closes open libxo constructs, and completes any pending 580*d4a07e70Sfengbojiangoperations. 581*d4a07e70Sfengbojiang 582*d4a07e70SfengbojiangCalling this function is vital to the proper operation of libxo, 583*d4a07e70Sfengbojiangespecially for the non-TEXT output styles. 584*d4a07e70Sfengbojiang 585*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_finish (void) 586*d4a07e70Sfengbojiang 587*d4a07e70Sfengbojiang :returns: -1 on error, or the number of bytes flushed 588*d4a07e70Sfengbojiang :rtype: xo_ssize_t 589*d4a07e70Sfengbojiang 590*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_finish_h (xo_handle_t *xop) 591*d4a07e70Sfengbojiang 592*d4a07e70Sfengbojiang :param xop: Handle for finish (or NULL for default handle) 593*d4a07e70Sfengbojiang :type xop: xo_handle_t \* 594*d4a07e70Sfengbojiang :returns: -1 on error, or the number of bytes flushed 595*d4a07e70Sfengbojiang :rtype: xo_ssize_t 596*d4a07e70Sfengbojiang 597*d4a07e70Sfengbojiang.. c:function:: void xo_finish_atexit (void) 598*d4a07e70Sfengbojiang 599*d4a07e70Sfengbojiang The `xo_finish_atexit` function is suitable for use with 600*d4a07e70Sfengbojiang :manpage:`atexit(3)` to ensure that `xo_finish` is called 601*d4a07e70Sfengbojiang on the default handle when the application exits. 602*d4a07e70Sfengbojiang 603*d4a07e70Sfengbojiang.. index:: UTF-8 604*d4a07e70Sfengbojiang.. index:: xo_open_container 605*d4a07e70Sfengbojiang.. index:: xo_close_container 606*d4a07e70Sfengbojiang 607*d4a07e70SfengbojiangEmitting Hierarchy 608*d4a07e70Sfengbojiang------------------ 609*d4a07e70Sfengbojiang 610*d4a07e70Sfengbojianglibxo represents two types of hierarchy: containers and lists. A 611*d4a07e70Sfengbojiangcontainer appears once under a given parent where a list consists of 612*d4a07e70Sfengbojianginstances that can appear multiple times. A container is used to hold 613*d4a07e70Sfengbojiangrelated fields and to give the data organization and scope. 614*d4a07e70Sfengbojiang 615*d4a07e70Sfengbojiang.. index:: YANG 616*d4a07e70Sfengbojiang 617*d4a07e70Sfengbojiang.. admonition:: YANG Terminology 618*d4a07e70Sfengbojiang 619*d4a07e70Sfengbojiang libxo uses terminology from YANG (:RFC:`7950`), the data modeling 620*d4a07e70Sfengbojiang language for NETCONF: container, list, leaf, and leaf-list. 621*d4a07e70Sfengbojiang 622*d4a07e70SfengbojiangFor XML and JSON, individual fields appear inside hierarchies which 623*d4a07e70Sfengbojiangprovide context and meaning to the fields. Unfortunately, these 624*d4a07e70Sfengbojiangencoding have a basic disconnect between how lists is similar objects 625*d4a07e70Sfengbojiangare represented. 626*d4a07e70Sfengbojiang 627*d4a07e70SfengbojiangXML encodes lists as set of sequential elements:: 628*d4a07e70Sfengbojiang 629*d4a07e70Sfengbojiang <user>phil</user> 630*d4a07e70Sfengbojiang <user>pallavi</user> 631*d4a07e70Sfengbojiang <user>sjg</user> 632*d4a07e70Sfengbojiang 633*d4a07e70SfengbojiangJSON encodes lists using a single name and square brackets:: 634*d4a07e70Sfengbojiang 635*d4a07e70Sfengbojiang "user": [ "phil", "pallavi", "sjg" ] 636*d4a07e70Sfengbojiang 637*d4a07e70SfengbojiangThis means libxo needs three distinct indications of hierarchy: one 638*d4a07e70Sfengbojiangfor containers of hierarchy appear only once for any specific parent, 639*d4a07e70Sfengbojiangone for lists, and one for each item in a list. 640*d4a07e70Sfengbojiang 641*d4a07e70Sfengbojiang.. index:: Containers 642*d4a07e70Sfengbojiang 643*d4a07e70SfengbojiangContainers 644*d4a07e70Sfengbojiang~~~~~~~~~~ 645*d4a07e70Sfengbojiang 646*d4a07e70SfengbojiangA "*container*" is an element of a hierarchy that appears only once 647*d4a07e70Sfengbojiangunder any specific parent. The container has no value, but serves to 648*d4a07e70Sfengbojiangcontain and organize other nodes. 649*d4a07e70Sfengbojiang 650*d4a07e70SfengbojiangTo open a container, call xo_open_container() or 651*d4a07e70Sfengbojiangxo_open_container_h(). The former uses the default handle and the 652*d4a07e70Sfengbojianglatter accepts a specific handle. To close a level, use the 653*d4a07e70Sfengbojiangxo_close_container() or xo_close_container_h() functions. 654*d4a07e70Sfengbojiang 655*d4a07e70SfengbojiangEach open call must have a matching close call. If the XOF_WARN flag 656*d4a07e70Sfengbojiangis set and the name given does not match the name of the currently open 657*d4a07e70Sfengbojiangcontainer, a warning will be generated. 658*d4a07e70Sfengbojiang 659*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_open_container (const char *name) 660*d4a07e70Sfengbojiang 661*d4a07e70Sfengbojiang :param name: Name of the container 662*d4a07e70Sfengbojiang :type name: const char * 663*d4a07e70Sfengbojiang :returns: -1 on error, or the number of bytes generated 664*d4a07e70Sfengbojiang :rtype: xo_ssize_t 665*d4a07e70Sfengbojiang 666*d4a07e70Sfengbojiang The `name` parameter gives the name of the container, encoded in 667*d4a07e70Sfengbojiang UTF-8. Since ASCII is a proper subset of UTF-8, traditional C 668*d4a07e70Sfengbojiang strings can be used directly. 669*d4a07e70Sfengbojiang 670*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_open_container_h (xo_handle_t *xop, const char *name) 671*d4a07e70Sfengbojiang 672*d4a07e70Sfengbojiang :param xop: Handle to use (or NULL for default handle) 673*d4a07e70Sfengbojiang :type xop: xo_handle_t * 674*d4a07e70Sfengbojiang 675*d4a07e70Sfengbojiang The `xo_open_container_h` function adds a `handle` parameter. 676*d4a07e70Sfengbojiang 677*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_close_container (const char *name) 678*d4a07e70Sfengbojiang 679*d4a07e70Sfengbojiang :param name: Name of the container 680*d4a07e70Sfengbojiang :type name: const char * 681*d4a07e70Sfengbojiang :returns: -1 on error, or the number of bytes generated 682*d4a07e70Sfengbojiang :rtype: xo_ssize_t 683*d4a07e70Sfengbojiang 684*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_close_container_h (xo_handle_t *xop, const char *name) 685*d4a07e70Sfengbojiang 686*d4a07e70Sfengbojiang :param xop: Handle to use (or NULL for default handle) 687*d4a07e70Sfengbojiang :type xop: xo_handle_t * 688*d4a07e70Sfengbojiang 689*d4a07e70Sfengbojiang The `xo_close_container_h` function adds a `handle` parameter. 690*d4a07e70Sfengbojiang 691*d4a07e70SfengbojiangUse the :index:`XOF_WARN` flag to generate a warning if the name given 692*d4a07e70Sfengbojiangon the close does not match the current open container. 693*d4a07e70Sfengbojiang 694*d4a07e70SfengbojiangFor TEXT and HTML output, containers are not rendered into output 695*d4a07e70Sfengbojiangtext, though for HTML they are used to record an XPath value when the 696*d4a07e70Sfengbojiang:index:`XOF_XPATH` flag is set. 697*d4a07e70Sfengbojiang 698*d4a07e70Sfengbojiang:: 699*d4a07e70Sfengbojiang 700*d4a07e70Sfengbojiang EXAMPLE: 701*d4a07e70Sfengbojiang xo_open_container("top"); 702*d4a07e70Sfengbojiang xo_open_container("system"); 703*d4a07e70Sfengbojiang xo_emit("{:host-name/%s%s%s}", hostname, 704*d4a07e70Sfengbojiang domainname ? "." : "", domainname ?: ""); 705*d4a07e70Sfengbojiang xo_close_container("system"); 706*d4a07e70Sfengbojiang xo_close_container("top"); 707*d4a07e70Sfengbojiang TEXT: 708*d4a07e70Sfengbojiang my-host.example.org 709*d4a07e70Sfengbojiang XML: 710*d4a07e70Sfengbojiang <top> 711*d4a07e70Sfengbojiang <system> 712*d4a07e70Sfengbojiang <host-name>my-host.example.org</host-name> 713*d4a07e70Sfengbojiang </system> 714*d4a07e70Sfengbojiang </top> 715*d4a07e70Sfengbojiang JSON: 716*d4a07e70Sfengbojiang "top" : { 717*d4a07e70Sfengbojiang "system" : { 718*d4a07e70Sfengbojiang "host-name": "my-host.example.org" 719*d4a07e70Sfengbojiang } 720*d4a07e70Sfengbojiang } 721*d4a07e70Sfengbojiang HTML: 722*d4a07e70Sfengbojiang <div class="data" 723*d4a07e70Sfengbojiang data-tag="host-name">my-host.example.org</div> 724*d4a07e70Sfengbojiang 725*d4a07e70Sfengbojiang.. index:: xo_open_instance 726*d4a07e70Sfengbojiang.. index:: xo_close_instance 727*d4a07e70Sfengbojiang.. index:: xo_open_list 728*d4a07e70Sfengbojiang.. index:: xo_close_list 729*d4a07e70Sfengbojiang 730*d4a07e70SfengbojiangLists and Instances 731*d4a07e70Sfengbojiang~~~~~~~~~~~~~~~~~~~ 732*d4a07e70Sfengbojiang 733*d4a07e70SfengbojiangA "*list*" is set of one or more instances that appear under the same 734*d4a07e70Sfengbojiangparent. The instances contain details about a specific object. One 735*d4a07e70Sfengbojiangcan think of instances as objects or records. A call is needed to 736*d4a07e70Sfengbojiangopen and close the list, while a distinct call is needed to open and 737*d4a07e70Sfengbojiangclose each instance of the list. 738*d4a07e70Sfengbojiang 739*d4a07e70SfengbojiangThe name given to all calls must be identical, and it is strongly 740*d4a07e70Sfengbojiangsuggested that the name be singular, not plural, as a matter of 741*d4a07e70Sfengbojiangstyle and usage expectations:: 742*d4a07e70Sfengbojiang 743*d4a07e70Sfengbojiang EXAMPLE: 744*d4a07e70Sfengbojiang xo_open_list("item"); 745*d4a07e70Sfengbojiang 746*d4a07e70Sfengbojiang for (ip = list; ip->i_title; ip++) { 747*d4a07e70Sfengbojiang xo_open_instance("item"); 748*d4a07e70Sfengbojiang xo_emit("{L:Item} '{:name/%s}':\n", ip->i_title); 749*d4a07e70Sfengbojiang xo_close_instance("item"); 750*d4a07e70Sfengbojiang } 751*d4a07e70Sfengbojiang 752*d4a07e70Sfengbojiang xo_close_list("item"); 753*d4a07e70Sfengbojiang 754*d4a07e70SfengbojiangGetting the list and instance calls correct is critical to the proper 755*d4a07e70Sfengbojianggeneration of XML and JSON data. 756*d4a07e70Sfengbojiang 757*d4a07e70SfengbojiangOpening Lists 758*d4a07e70Sfengbojiang+++++++++++++ 759*d4a07e70Sfengbojiang 760*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_open_list (const char *name) 761*d4a07e70Sfengbojiang 762*d4a07e70Sfengbojiang :param name: Name of the list 763*d4a07e70Sfengbojiang :type name: const char * 764*d4a07e70Sfengbojiang :returns: -1 on error, or the number of bytes generated 765*d4a07e70Sfengbojiang :rtype: xo_ssize_t 766*d4a07e70Sfengbojiang 767*d4a07e70Sfengbojiang The `xo_open_list` function open a list of instances. 768*d4a07e70Sfengbojiang 769*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_open_list_h (xo_handle_t *xop, const char *name) 770*d4a07e70Sfengbojiang 771*d4a07e70Sfengbojiang :param xop: Handle to use (or NULL for default handle) 772*d4a07e70Sfengbojiang :type xop: xo_handle_t * 773*d4a07e70Sfengbojiang 774*d4a07e70SfengbojiangClosing Lists 775*d4a07e70Sfengbojiang+++++++++++++ 776*d4a07e70Sfengbojiang 777*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_close_list (const char *name) 778*d4a07e70Sfengbojiang 779*d4a07e70Sfengbojiang :param name: Name of the list 780*d4a07e70Sfengbojiang :type name: const char * 781*d4a07e70Sfengbojiang :returns: -1 on error, or the number of bytes generated 782*d4a07e70Sfengbojiang :rtype: xo_ssize_t 783*d4a07e70Sfengbojiang 784*d4a07e70Sfengbojiang The `xo_close_list` function closes a list of instances. 785*d4a07e70Sfengbojiang 786*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_close_list_h (xo_handle_t *xop, const char *name) 787*d4a07e70Sfengbojiang 788*d4a07e70Sfengbojiang :param xop: Handle to use (or NULL for default handle) 789*d4a07e70Sfengbojiang :type xop: xo_handle_t * 790*d4a07e70Sfengbojiang 791*d4a07e70Sfengbojiang The `xo_close_container_h` function adds a `handle` parameter. 792*d4a07e70Sfengbojiang 793*d4a07e70SfengbojiangOpening Instances 794*d4a07e70Sfengbojiang+++++++++++++++++ 795*d4a07e70Sfengbojiang 796*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_open_instance (const char *name) 797*d4a07e70Sfengbojiang 798*d4a07e70Sfengbojiang :param name: Name of the instance (same as the list name) 799*d4a07e70Sfengbojiang :type name: const char * 800*d4a07e70Sfengbojiang :returns: -1 on error, or the number of bytes generated 801*d4a07e70Sfengbojiang :rtype: xo_ssize_t 802*d4a07e70Sfengbojiang 803*d4a07e70Sfengbojiang The `xo_open_instance` function open a single instance. 804*d4a07e70Sfengbojiang 805*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_open_instance_h (xo_handle_t *xop, const char *name) 806*d4a07e70Sfengbojiang 807*d4a07e70Sfengbojiang :param xop: Handle to use (or NULL for default handle) 808*d4a07e70Sfengbojiang :type xop: xo_handle_t * 809*d4a07e70Sfengbojiang 810*d4a07e70Sfengbojiang The `xo_open_instance_h` function adds a `handle` parameter. 811*d4a07e70Sfengbojiang 812*d4a07e70SfengbojiangClosing Instances 813*d4a07e70Sfengbojiang+++++++++++++++++ 814*d4a07e70Sfengbojiang 815*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_close_instance (const char *name) 816*d4a07e70Sfengbojiang 817*d4a07e70Sfengbojiang :param name: Name of the instance 818*d4a07e70Sfengbojiang :type name: const char * 819*d4a07e70Sfengbojiang :returns: -1 on error, or the number of bytes generated 820*d4a07e70Sfengbojiang :rtype: xo_ssize_t 821*d4a07e70Sfengbojiang 822*d4a07e70Sfengbojiang The `xo_close_instance` function closes an open instance. 823*d4a07e70Sfengbojiang 824*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_close_instance_h (xo_handle_t *xop, const char *name) 825*d4a07e70Sfengbojiang 826*d4a07e70Sfengbojiang :param xop: Handle to use (or NULL for default handle) 827*d4a07e70Sfengbojiang :type xop: xo_handle_t * 828*d4a07e70Sfengbojiang 829*d4a07e70Sfengbojiang The `xo_close_instance_h` function adds a `handle` parameter. 830*d4a07e70Sfengbojiang 831*d4a07e70Sfengbojiang :: 832*d4a07e70Sfengbojiang 833*d4a07e70Sfengbojiang EXAMPLE: 834*d4a07e70Sfengbojiang xo_open_list("user"); 835*d4a07e70Sfengbojiang for (i = 0; i < num_users; i++) { 836*d4a07e70Sfengbojiang xo_open_instance("user"); 837*d4a07e70Sfengbojiang xo_emit("{k:name}:{:uid/%u}:{:gid/%u}:{:home}\n", 838*d4a07e70Sfengbojiang pw[i].pw_name, pw[i].pw_uid, 839*d4a07e70Sfengbojiang pw[i].pw_gid, pw[i].pw_dir); 840*d4a07e70Sfengbojiang xo_close_instance("user"); 841*d4a07e70Sfengbojiang } 842*d4a07e70Sfengbojiang xo_close_list("user"); 843*d4a07e70Sfengbojiang TEXT: 844*d4a07e70Sfengbojiang phil:1001:1001:/home/phil 845*d4a07e70Sfengbojiang pallavi:1002:1002:/home/pallavi 846*d4a07e70Sfengbojiang XML: 847*d4a07e70Sfengbojiang <user> 848*d4a07e70Sfengbojiang <name>phil</name> 849*d4a07e70Sfengbojiang <uid>1001</uid> 850*d4a07e70Sfengbojiang <gid>1001</gid> 851*d4a07e70Sfengbojiang <home>/home/phil</home> 852*d4a07e70Sfengbojiang </user> 853*d4a07e70Sfengbojiang <user> 854*d4a07e70Sfengbojiang <name>pallavi</name> 855*d4a07e70Sfengbojiang <uid>1002</uid> 856*d4a07e70Sfengbojiang <gid>1002</gid> 857*d4a07e70Sfengbojiang <home>/home/pallavi</home> 858*d4a07e70Sfengbojiang </user> 859*d4a07e70Sfengbojiang JSON: 860*d4a07e70Sfengbojiang user: [ 861*d4a07e70Sfengbojiang { 862*d4a07e70Sfengbojiang "name": "phil", 863*d4a07e70Sfengbojiang "uid": 1001, 864*d4a07e70Sfengbojiang "gid": 1001, 865*d4a07e70Sfengbojiang "home": "/home/phil", 866*d4a07e70Sfengbojiang }, 867*d4a07e70Sfengbojiang { 868*d4a07e70Sfengbojiang "name": "pallavi", 869*d4a07e70Sfengbojiang "uid": 1002, 870*d4a07e70Sfengbojiang "gid": 1002, 871*d4a07e70Sfengbojiang "home": "/home/pallavi", 872*d4a07e70Sfengbojiang } 873*d4a07e70Sfengbojiang ] 874*d4a07e70Sfengbojiang 875*d4a07e70SfengbojiangMarkers 876*d4a07e70Sfengbojiang~~~~~~~ 877*d4a07e70Sfengbojiang 878*d4a07e70SfengbojiangMarkers are used to protect and restore the state of open hierarchy 879*d4a07e70Sfengbojiangconstructs (containers, lists, or instances). While a marker is open, 880*d4a07e70Sfengbojiangno other open constructs can be closed. When a marker is closed, all 881*d4a07e70Sfengbojiangconstructs open since the marker was opened will be closed. 882*d4a07e70Sfengbojiang 883*d4a07e70SfengbojiangMarkers use names which are not user-visible, allowing the caller to 884*d4a07e70Sfengbojiangchoose appropriate internal names. 885*d4a07e70Sfengbojiang 886*d4a07e70SfengbojiangIn this example, the code whiffles through a list of fish, calling a 887*d4a07e70Sfengbojiangfunction to emit details about each fish. The marker "fish-guts" is 888*d4a07e70Sfengbojiangused to ensure that any constructs opened by the function are closed 889*d4a07e70Sfengbojiangproperly:: 890*d4a07e70Sfengbojiang 891*d4a07e70Sfengbojiang EXAMPLE: 892*d4a07e70Sfengbojiang for (i = 0; fish[i]; i++) { 893*d4a07e70Sfengbojiang xo_open_instance("fish"); 894*d4a07e70Sfengbojiang xo_open_marker("fish-guts"); 895*d4a07e70Sfengbojiang dump_fish_details(i); 896*d4a07e70Sfengbojiang xo_close_marker("fish-guts"); 897*d4a07e70Sfengbojiang } 898*d4a07e70Sfengbojiang 899*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_open_marker(const char *name) 900*d4a07e70Sfengbojiang 901*d4a07e70Sfengbojiang :param name: Name of the instance 902*d4a07e70Sfengbojiang :type name: const char * 903*d4a07e70Sfengbojiang :returns: -1 on error, or the number of bytes generated 904*d4a07e70Sfengbojiang :rtype: xo_ssize_t 905*d4a07e70Sfengbojiang 906*d4a07e70Sfengbojiang The `xo_open_marker` function records the current state of open tags 907*d4a07e70Sfengbojiang in order for `xo_close_marker` to close them at some later point. 908*d4a07e70Sfengbojiang 909*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_open_marker_h(const char *name) 910*d4a07e70Sfengbojiang 911*d4a07e70Sfengbojiang :param xop: Handle to use (or NULL for default handle) 912*d4a07e70Sfengbojiang :type xop: xo_handle_t * 913*d4a07e70Sfengbojiang 914*d4a07e70Sfengbojiang The `xo_open_marker_h` function adds a `handle` parameter. 915*d4a07e70Sfengbojiang 916*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_close_marker(const char *name) 917*d4a07e70Sfengbojiang 918*d4a07e70Sfengbojiang :param name: Name of the instance 919*d4a07e70Sfengbojiang :type name: const char * 920*d4a07e70Sfengbojiang :returns: -1 on error, or the number of bytes generated 921*d4a07e70Sfengbojiang :rtype: xo_ssize_t 922*d4a07e70Sfengbojiang 923*d4a07e70Sfengbojiang The `xo_close_marker` function closes any open containers, lists, or 924*d4a07e70Sfengbojiang instances as needed to return to the state recorded when 925*d4a07e70Sfengbojiang `xo_open_marker` was called with the matching name. 926*d4a07e70Sfengbojiang 927*d4a07e70Sfengbojiang.. c:function:: xo_ssize_t xo_close_marker(const char *name) 928*d4a07e70Sfengbojiang 929*d4a07e70Sfengbojiang :param xop: Handle to use (or NULL for default handle) 930*d4a07e70Sfengbojiang :type xop: xo_handle_t * 931*d4a07e70Sfengbojiang 932*d4a07e70Sfengbojiang The `xo_close_marker_h` function adds a `handle` parameter. 933*d4a07e70Sfengbojiang 934*d4a07e70SfengbojiangDTRT Mode 935*d4a07e70Sfengbojiang~~~~~~~~~ 936*d4a07e70Sfengbojiang 937*d4a07e70SfengbojiangSome users may find tracking the names of open containers, lists, and 938*d4a07e70Sfengbojianginstances inconvenient. libxo offers a "Do The Right Thing" mode, where 939*d4a07e70Sfengbojianglibxo will track the names of open containers, lists, and instances so 940*d4a07e70Sfengbojiangthe close function can be called without a name. To enable DTRT mode, 941*d4a07e70Sfengbojiangturn on the XOF_DTRT flag prior to making any other libxo output:: 942*d4a07e70Sfengbojiang 943*d4a07e70Sfengbojiang xo_set_flags(NULL, XOF_DTRT); 944*d4a07e70Sfengbojiang 945*d4a07e70Sfengbojiang.. index:: XOF_DTRT 946*d4a07e70Sfengbojiang 947*d4a07e70SfengbojiangEach open and close function has a version with the suffix "_d", which 948*d4a07e70Sfengbojiangwill close the open container, list, or instance:: 949*d4a07e70Sfengbojiang 950*d4a07e70Sfengbojiang xo_open_container_d("top"); 951*d4a07e70Sfengbojiang ... 952*d4a07e70Sfengbojiang xo_close_container_d(); 953*d4a07e70Sfengbojiang 954*d4a07e70SfengbojiangThis also works for lists and instances:: 955*d4a07e70Sfengbojiang 956*d4a07e70Sfengbojiang xo_open_list_d("item"); 957*d4a07e70Sfengbojiang for (...) { 958*d4a07e70Sfengbojiang xo_open_instance_d("item"); 959*d4a07e70Sfengbojiang xo_emit(...); 960*d4a07e70Sfengbojiang xo_close_instance_d(); 961*d4a07e70Sfengbojiang } 962*d4a07e70Sfengbojiang xo_close_list_d(); 963*d4a07e70Sfengbojiang 964*d4a07e70Sfengbojiang.. index:: XOF_WARN 965*d4a07e70Sfengbojiang 966*d4a07e70SfengbojiangNote that the XOF_WARN flag will also cause libxo to track open 967*d4a07e70Sfengbojiangcontainers, lists, and instances. A warning is generated when the 968*d4a07e70Sfengbojiangname given to the close function and the name recorded do not match. 969*d4a07e70Sfengbojiang 970*d4a07e70SfengbojiangSupport Functions 971*d4a07e70Sfengbojiang----------------- 972*d4a07e70Sfengbojiang 973*d4a07e70Sfengbojiang.. index:: xo_parse_args 974*d4a07e70Sfengbojiang.. _xo_parse_args: 975*d4a07e70Sfengbojiang 976*d4a07e70SfengbojiangParsing Command-line Arguments (xo_parse_args) 977*d4a07e70Sfengbojiang~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 978*d4a07e70Sfengbojiang 979*d4a07e70Sfengbojiang.. c:function:: int xo_parse_args (int argc, char **argv) 980*d4a07e70Sfengbojiang 981*d4a07e70Sfengbojiang :param int argc: Number of arguments 982*d4a07e70Sfengbojiang :param argv: Array of argument strings 983*d4a07e70Sfengbojiang :return: -1 on error, or the number of remaining arguments 984*d4a07e70Sfengbojiang :rtype: int 985*d4a07e70Sfengbojiang 986*d4a07e70Sfengbojiang The `xo_parse_args` function is used to process a program's 987*d4a07e70Sfengbojiang arguments. libxo-specific options are processed and removed from 988*d4a07e70Sfengbojiang the argument list so the calling application does not need to 989*d4a07e70Sfengbojiang process them. If successful, a new value for argc is returned. On 990*d4a07e70Sfengbojiang failure, a message is emitted and -1 is returned:: 991*d4a07e70Sfengbojiang 992*d4a07e70Sfengbojiang argc = xo_parse_args(argc, argv); 993*d4a07e70Sfengbojiang if (argc < 0) 994*d4a07e70Sfengbojiang exit(EXIT_FAILURE); 995*d4a07e70Sfengbojiang 996*d4a07e70Sfengbojiang Following the call to xo_parse_args, the application can process the 997*d4a07e70Sfengbojiang remaining arguments in a normal manner. See :ref:`options` for a 998*d4a07e70Sfengbojiang description of valid arguments. 999*d4a07e70Sfengbojiang 1000*d4a07e70Sfengbojiang.. index:: xo_set_program 1001*d4a07e70Sfengbojiang 1002*d4a07e70Sfengbojiangxo_set_program 1003*d4a07e70Sfengbojiang~~~~~~~~~~~~~~ 1004*d4a07e70Sfengbojiang 1005*d4a07e70Sfengbojiang.. c:function:: void xo_set_program (const char *name) 1006*d4a07e70Sfengbojiang 1007*d4a07e70Sfengbojiang :param name: Name to use as the program name 1008*d4a07e70Sfengbojiang :type name: const char * 1009*d4a07e70Sfengbojiang :returns: void 1010*d4a07e70Sfengbojiang 1011*d4a07e70Sfengbojiang The `xo_set_program` function sets the name of the program as 1012*d4a07e70Sfengbojiang reported by functions like `xo_failure`, `xo_warn`, `xo_err`, etc. 1013*d4a07e70Sfengbojiang The program name is initialized by `xo_parse_args`, but subsequent 1014*d4a07e70Sfengbojiang calls to `xo_set_program` can override this value:: 1015*d4a07e70Sfengbojiang 1016*d4a07e70Sfengbojiang EXAMPLE: 1017*d4a07e70Sfengbojiang xo_set_program(argv[0]); 1018*d4a07e70Sfengbojiang 1019*d4a07e70Sfengbojiang Note that the value is not copied, so the memory passed to 1020*d4a07e70Sfengbojiang `xo_set_program` (and `xo_parse_args`) must be maintained by the 1021*d4a07e70Sfengbojiang caller. 1022*d4a07e70Sfengbojiang 1023*d4a07e70Sfengbojiang.. index:: xo_set_version 1024*d4a07e70Sfengbojiang 1025*d4a07e70Sfengbojiangxo_set_version 1026*d4a07e70Sfengbojiang~~~~~~~~~~~~~~ 1027*d4a07e70Sfengbojiang 1028*d4a07e70Sfengbojiang.. c:function:: void xo_set_version (const char *version) 1029*d4a07e70Sfengbojiang 1030*d4a07e70Sfengbojiang :param name: Value to use as the version string 1031*d4a07e70Sfengbojiang :type name: const char * 1032*d4a07e70Sfengbojiang :returns: void 1033*d4a07e70Sfengbojiang 1034*d4a07e70Sfengbojiang The `xo_set_version` function records a version number to be emitted 1035*d4a07e70Sfengbojiang as part of the data for encoding styles (XML and JSON). This 1036*d4a07e70Sfengbojiang version number is suitable for tracking changes in the content, 1037*d4a07e70Sfengbojiang allowing a user of the data to discern which version of the data 1038*d4a07e70Sfengbojiang model is in use. 1039*d4a07e70Sfengbojiang 1040*d4a07e70Sfengbojiang.. c:function:: void xo_set_version_h (xo_handle_t *xop, const char *version) 1041*d4a07e70Sfengbojiang 1042*d4a07e70Sfengbojiang :param xop: Handle to use (or NULL for default handle) 1043*d4a07e70Sfengbojiang :type xop: xo_handle_t * 1044*d4a07e70Sfengbojiang 1045*d4a07e70Sfengbojiang The `xo_set_version` function adds a `handle` parameter. 1046*d4a07e70Sfengbojiang 1047*d4a07e70Sfengbojiang.. index:: --libxo 1048*d4a07e70Sfengbojiang.. index:: XOF_INFO 1049*d4a07e70Sfengbojiang.. index:: xo_info_t 1050*d4a07e70Sfengbojiang 1051*d4a07e70Sfengbojiang.. _field-information: 1052*d4a07e70Sfengbojiang 1053*d4a07e70SfengbojiangField Information (xo_info_t) 1054*d4a07e70Sfengbojiang~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1055*d4a07e70Sfengbojiang 1056*d4a07e70SfengbojiangHTML data can include additional information in attributes that 1057*d4a07e70Sfengbojiangbegin with "data-". To enable this, three things must occur: 1058*d4a07e70Sfengbojiang 1059*d4a07e70SfengbojiangFirst the application must build an array of xo_info_t structures, 1060*d4a07e70Sfengbojiangone per tag. The array must be sorted by name, since libxo uses a 1061*d4a07e70Sfengbojiangbinary search to find the entry that matches names from format 1062*d4a07e70Sfengbojianginstructions. 1063*d4a07e70Sfengbojiang 1064*d4a07e70SfengbojiangSecond, the application must inform libxo about this information using 1065*d4a07e70Sfengbojiangthe `xo_set_info` call:: 1066*d4a07e70Sfengbojiang 1067*d4a07e70Sfengbojiang typedef struct xo_info_s { 1068*d4a07e70Sfengbojiang const char *xi_name; /* Name of the element */ 1069*d4a07e70Sfengbojiang const char *xi_type; /* Type of field */ 1070*d4a07e70Sfengbojiang const char *xi_help; /* Description of field */ 1071*d4a07e70Sfengbojiang } xo_info_t; 1072*d4a07e70Sfengbojiang 1073*d4a07e70Sfengbojiang void xo_set_info (xo_handle_t *xop, xo_info_t *infop, int count); 1074*d4a07e70Sfengbojiang 1075*d4a07e70SfengbojiangLike other libxo calls, passing `NULL` for the handle tells libxo to 1076*d4a07e70Sfengbojianguse the default handle. 1077*d4a07e70Sfengbojiang 1078*d4a07e70SfengbojiangIf the count is -1, libxo will count the elements of infop, but there 1079*d4a07e70Sfengbojiangmust be an empty element at the end. More typically, the number is 1080*d4a07e70Sfengbojiangknown to the application:: 1081*d4a07e70Sfengbojiang 1082*d4a07e70Sfengbojiang xo_info_t info[] = { 1083*d4a07e70Sfengbojiang { "in-stock", "number", "Number of items in stock" }, 1084*d4a07e70Sfengbojiang { "name", "string", "Name of the item" }, 1085*d4a07e70Sfengbojiang { "on-order", "number", "Number of items on order" }, 1086*d4a07e70Sfengbojiang { "sku", "string", "Stock Keeping Unit" }, 1087*d4a07e70Sfengbojiang { "sold", "number", "Number of items sold" }, 1088*d4a07e70Sfengbojiang }; 1089*d4a07e70Sfengbojiang int info_count = (sizeof(info) / sizeof(info[0])); 1090*d4a07e70Sfengbojiang ... 1091*d4a07e70Sfengbojiang xo_set_info(NULL, info, info_count); 1092*d4a07e70Sfengbojiang 1093*d4a07e70SfengbojiangThird, the emission of info must be triggered with the `XOF_INFO` flag 1094*d4a07e70Sfengbojiangusing either the `xo_set_flags` function or the "`--libxo=info`" 1095*d4a07e70Sfengbojiangcommand line argument. 1096*d4a07e70Sfengbojiang 1097*d4a07e70SfengbojiangThe type and help values, if present, are emitted as the "data-type" 1098*d4a07e70Sfengbojiangand "data-help" attributes:: 1099*d4a07e70Sfengbojiang 1100*d4a07e70Sfengbojiang <div class="data" data-tag="sku" data-type="string" 1101*d4a07e70Sfengbojiang data-help="Stock Keeping Unit">GRO-000-533</div> 1102*d4a07e70Sfengbojiang 1103*d4a07e70Sfengbojiang.. c:function:: void xo_set_info (xo_handle_t *xop, xo_info_t *infop, int count) 1104*d4a07e70Sfengbojiang 1105*d4a07e70Sfengbojiang :param xop: Handle to use (or NULL for default handle) 1106*d4a07e70Sfengbojiang :type xop: xo_handle_t * 1107*d4a07e70Sfengbojiang :param infop: Array of information structures 1108*d4a07e70Sfengbojiang :type infop: xo_info_t * 1109*d4a07e70Sfengbojiang :returns: void 1110*d4a07e70Sfengbojiang 1111*d4a07e70Sfengbojiang.. index:: xo_set_allocator 1112*d4a07e70Sfengbojiang.. index:: xo_realloc_func_t 1113*d4a07e70Sfengbojiang.. index:: xo_free_func_t 1114*d4a07e70Sfengbojiang 1115*d4a07e70SfengbojiangMemory Allocation 1116*d4a07e70Sfengbojiang~~~~~~~~~~~~~~~~~ 1117*d4a07e70Sfengbojiang 1118*d4a07e70SfengbojiangThe `xo_set_allocator` function allows libxo to be used in 1119*d4a07e70Sfengbojiangenvironments where the standard :manpage:`realloc(3)` and 1120*d4a07e70Sfengbojiang:manpage:`free(3)` functions are not appropriate. 1121*d4a07e70Sfengbojiang 1122*d4a07e70Sfengbojiang.. c:function:: void xo_set_allocator (xo_realloc_func_t realloc_func, xo_free_func_t free_func) 1123*d4a07e70Sfengbojiang 1124*d4a07e70Sfengbojiang :param xo_realloc_func_t realloc_func: Allocation function 1125*d4a07e70Sfengbojiang :param xo_free_func_t free_func: Free function 1126*d4a07e70Sfengbojiang 1127*d4a07e70Sfengbojiang *realloc_func* should expect the same arguments as 1128*d4a07e70Sfengbojiang :manpage:`realloc(3)` and return a pointer to memory following the 1129*d4a07e70Sfengbojiang same convention. *free_func* will receive the same argument as 1130*d4a07e70Sfengbojiang :manpage:`free(3)` and should release it, as appropriate for the 1131*d4a07e70Sfengbojiang environment. 1132*d4a07e70Sfengbojiang 1133*d4a07e70SfengbojiangBy default, the standard :manpage:`realloc(3)` and :manpage:`free(3)` 1134*d4a07e70Sfengbojiangfunctions are used. 1135*d4a07e70Sfengbojiang 1136*d4a07e70Sfengbojiang.. index:: --libxo 1137*d4a07e70Sfengbojiang 1138*d4a07e70Sfengbojiang.. _libxo-options: 1139*d4a07e70Sfengbojiang 1140*d4a07e70SfengbojiangLIBXO_OPTIONS 1141*d4a07e70Sfengbojiang~~~~~~~~~~~~~ 1142*d4a07e70Sfengbojiang 1143*d4a07e70SfengbojiangThe environment variable "LIBXO_OPTIONS" can be set to a subset of 1144*d4a07e70Sfengbojianglibxo options, including: 1145*d4a07e70Sfengbojiang 1146*d4a07e70Sfengbojiang- color 1147*d4a07e70Sfengbojiang- flush 1148*d4a07e70Sfengbojiang- flush-line 1149*d4a07e70Sfengbojiang- no-color 1150*d4a07e70Sfengbojiang- no-humanize 1151*d4a07e70Sfengbojiang- no-locale 1152*d4a07e70Sfengbojiang- no-retain 1153*d4a07e70Sfengbojiang- pretty 1154*d4a07e70Sfengbojiang- retain 1155*d4a07e70Sfengbojiang- underscores 1156*d4a07e70Sfengbojiang- warn 1157*d4a07e70Sfengbojiang 1158*d4a07e70SfengbojiangFor example, warnings can be enabled by:: 1159*d4a07e70Sfengbojiang 1160*d4a07e70Sfengbojiang % env LIBXO_OPTIONS=warn my-app 1161*d4a07e70Sfengbojiang 1162*d4a07e70SfengbojiangSince environment variables are inherited, child processes will have 1163*d4a07e70Sfengbojiangthe same options, which may be undesirable, making the use of the 1164*d4a07e70Sfengbojiang"`--libxo`" command-line option preferable in most situations. 1165*d4a07e70Sfengbojiang 1166*d4a07e70Sfengbojiang.. index:: xo_warn 1167*d4a07e70Sfengbojiang.. index:: xo_err 1168*d4a07e70Sfengbojiang.. index:: xo_errx 1169*d4a07e70Sfengbojiang.. index:: xo_message 1170*d4a07e70Sfengbojiang 1171*d4a07e70SfengbojiangErrors, Warnings, and Messages 1172*d4a07e70Sfengbojiang~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1173*d4a07e70Sfengbojiang 1174*d4a07e70SfengbojiangMany programs make use of the standard library functions 1175*d4a07e70Sfengbojiang:manpage:`err(3)` and :manpage:`warn(3)` to generate errors and 1176*d4a07e70Sfengbojiangwarnings for the user. libxo wants to pass that information via the 1177*d4a07e70Sfengbojiangcurrent output style, and provides compatible functions to allow 1178*d4a07e70Sfengbojiangthis:: 1179*d4a07e70Sfengbojiang 1180*d4a07e70Sfengbojiang void xo_warn (const char *fmt, ...); 1181*d4a07e70Sfengbojiang void xo_warnx (const char *fmt, ...); 1182*d4a07e70Sfengbojiang void xo_warn_c (int code, const char *fmt, ...); 1183*d4a07e70Sfengbojiang void xo_warn_hc (xo_handle_t *xop, int code, 1184*d4a07e70Sfengbojiang const char *fmt, ...); 1185*d4a07e70Sfengbojiang void xo_err (int eval, const char *fmt, ...); 1186*d4a07e70Sfengbojiang void xo_errc (int eval, int code, const char *fmt, ...); 1187*d4a07e70Sfengbojiang void xo_errx (int eval, const char *fmt, ...); 1188*d4a07e70Sfengbojiang 1189*d4a07e70Sfengbojiang:: 1190*d4a07e70Sfengbojiang 1191*d4a07e70Sfengbojiang void xo_message (const char *fmt, ...); 1192*d4a07e70Sfengbojiang void xo_message_c (int code, const char *fmt, ...); 1193*d4a07e70Sfengbojiang void xo_message_hc (xo_handle_t *xop, int code, 1194*d4a07e70Sfengbojiang const char *fmt, ...); 1195*d4a07e70Sfengbojiang void xo_message_hcv (xo_handle_t *xop, int code, 1196*d4a07e70Sfengbojiang const char *fmt, va_list vap); 1197*d4a07e70Sfengbojiang 1198*d4a07e70SfengbojiangThese functions display the program name, a colon, a formatted message 1199*d4a07e70Sfengbojiangbased on the arguments, and then optionally a colon and an error 1200*d4a07e70Sfengbojiangmessage associated with either *errno* or the *code* parameter:: 1201*d4a07e70Sfengbojiang 1202*d4a07e70Sfengbojiang EXAMPLE: 1203*d4a07e70Sfengbojiang if (open(filename, O_RDONLY) < 0) 1204*d4a07e70Sfengbojiang xo_err(1, "cannot open file '%s'", filename); 1205*d4a07e70Sfengbojiang 1206*d4a07e70Sfengbojiang.. index:: xo_error 1207*d4a07e70Sfengbojiang.. index:: xo_error_h 1208*d4a07e70Sfengbojiang.. index:: xo_error_hv 1209*d4a07e70Sfengbojiang.. index:: xo_errorn 1210*d4a07e70Sfengbojiang.. index:: xo_errorn_h 1211*d4a07e70Sfengbojiang.. index:: xo_errorn_hv 1212*d4a07e70Sfengbojiang 1213*d4a07e70Sfengbojiangxo_error 1214*d4a07e70Sfengbojiang~~~~~~~~ 1215*d4a07e70Sfengbojiang 1216*d4a07e70Sfengbojiang.. c:function:: void xo_error (const char *fmt, ...) 1217*d4a07e70Sfengbojiang 1218*d4a07e70Sfengbojiang :param fmt: Format string 1219*d4a07e70Sfengbojiang :type fmt: const char * 1220*d4a07e70Sfengbojiang :returns: void 1221*d4a07e70Sfengbojiang 1222*d4a07e70Sfengbojiang.. c:function:: void xo_error_h (xo_handle_t *xop, const char *fmt, ...) 1223*d4a07e70Sfengbojiang 1224*d4a07e70Sfengbojiang :param xop: libxo handle pointer 1225*d4a07e70Sfengbojiang :type xop: xo_handle_t * 1226*d4a07e70Sfengbojiang :param fmt: Format string 1227*d4a07e70Sfengbojiang :type fmt: const char * 1228*d4a07e70Sfengbojiang :returns: void 1229*d4a07e70Sfengbojiang 1230*d4a07e70Sfengbojiang.. c:function:: void xo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap) 1231*d4a07e70Sfengbojiang 1232*d4a07e70Sfengbojiang :param xop: libxo handle pointer 1233*d4a07e70Sfengbojiang :type xop: xo_handle_t * 1234*d4a07e70Sfengbojiang :param fmt: Format string 1235*d4a07e70Sfengbojiang :type fmt: const char * 1236*d4a07e70Sfengbojiang :param vap: variadic arguments 1237*d4a07e70Sfengbojiang :type xop: va_list 1238*d4a07e70Sfengbojiang :returns: void 1239*d4a07e70Sfengbojiang 1240*d4a07e70Sfengbojiang.. c:function:: void xo_errorn (const char *fmt, ...) 1241*d4a07e70Sfengbojiang 1242*d4a07e70Sfengbojiang :param fmt: Format string 1243*d4a07e70Sfengbojiang :type fmt: const char * 1244*d4a07e70Sfengbojiang :returns: void 1245*d4a07e70Sfengbojiang 1246*d4a07e70Sfengbojiang.. c:function:: void xo_errorn_h (xo_handle_t *xop, const char *fmt, ...) 1247*d4a07e70Sfengbojiang 1248*d4a07e70Sfengbojiang :param xop: libxo handle pointer 1249*d4a07e70Sfengbojiang :type xop: xo_handle_t * 1250*d4a07e70Sfengbojiang :param fmt: Format string 1251*d4a07e70Sfengbojiang :type fmt: const char * 1252*d4a07e70Sfengbojiang :returns: void 1253*d4a07e70Sfengbojiang 1254*d4a07e70Sfengbojiang.. c:function:: void xo_errorn_hv (xo_handle_t *xop, int need_newline, const char *fmt, va_list vap) 1255*d4a07e70Sfengbojiang 1256*d4a07e70Sfengbojiang :param xop: libxo handle pointer 1257*d4a07e70Sfengbojiang :type xop: xo_handle_t * 1258*d4a07e70Sfengbojiang :param need_newline: boolean indicating need for trailing newline 1259*d4a07e70Sfengbojiang :type need_newline: int 1260*d4a07e70Sfengbojiang :param fmt: Format string 1261*d4a07e70Sfengbojiang :type fmt: const char * 1262*d4a07e70Sfengbojiang :param vap: variadic arguments 1263*d4a07e70Sfengbojiang :type xop: va_list 1264*d4a07e70Sfengbojiang :returns: void 1265*d4a07e70Sfengbojiang 1266*d4a07e70Sfengbojiang The `xo_error` function can be used for generic errors that should 1267*d4a07e70Sfengbojiang be reported over the handle, rather than to stderr. The `xo_error` 1268*d4a07e70Sfengbojiang function behaves like `xo_err` for TEXT and HTML output styles, but 1269*d4a07e70Sfengbojiang puts the error into XML or JSON elements:: 1270*d4a07e70Sfengbojiang 1271*d4a07e70Sfengbojiang EXAMPLE:: 1272*d4a07e70Sfengbojiang xo_error("Does not %s", "compute"); 1273*d4a07e70Sfengbojiang XML:: 1274*d4a07e70Sfengbojiang <error><message>Does not compute</message></error> 1275*d4a07e70Sfengbojiang JSON:: 1276*d4a07e70Sfengbojiang "error": { "message": "Does not compute" } 1277*d4a07e70Sfengbojiang 1278*d4a07e70Sfengbojiang The `xo_error_h` and `xo_error_hv` add a handle object and a 1279*d4a07e70Sfengbojiang variadic-ized parameter to the signature, respectively. 1280*d4a07e70Sfengbojiang 1281*d4a07e70Sfengbojiang The `xo_errorn` function supplies a newline at the end the error 1282*d4a07e70Sfengbojiang message if the format string does not include one. The 1283*d4a07e70Sfengbojiang `xo_errorn_h` and `xo_errorn_hv` functions add a handle object and 1284*d4a07e70Sfengbojiang a variadic-ized parameter to the signature, respectively. The 1285*d4a07e70Sfengbojiang `xo_errorn_hv` function also adds a boolean to indicate the need for 1286*d4a07e70Sfengbojiang a trailing newline. 1287*d4a07e70Sfengbojiang 1288*d4a07e70Sfengbojiang.. index:: xo_no_setlocale 1289*d4a07e70Sfengbojiang.. index:: Locale 1290*d4a07e70Sfengbojiang 1291*d4a07e70Sfengbojiangxo_no_setlocale 1292*d4a07e70Sfengbojiang~~~~~~~~~~~~~~~ 1293*d4a07e70Sfengbojiang 1294*d4a07e70Sfengbojiang.. c:function:: void xo_no_setlocale (void) 1295*d4a07e70Sfengbojiang 1296*d4a07e70Sfengbojiang libxo automatically initializes the locale based on setting of the 1297*d4a07e70Sfengbojiang environment variables LC_CTYPE, LANG, and LC_ALL. The first of this 1298*d4a07e70Sfengbojiang list of variables is used and if none of the variables, the locale 1299*d4a07e70Sfengbojiang defaults to "UTF-8". The caller may wish to avoid this behavior, 1300*d4a07e70Sfengbojiang and can do so by calling the `xo_no_setlocale` function. 1301*d4a07e70Sfengbojiang 1302*d4a07e70SfengbojiangEmitting syslog Messages 1303*d4a07e70Sfengbojiang------------------------ 1304*d4a07e70Sfengbojiang 1305*d4a07e70Sfengbojiangsyslog is the system logging facility used throughout the unix world. 1306*d4a07e70SfengbojiangMessages are sent from commands, applications, and daemons to a 1307*d4a07e70Sfengbojianghierarchy of servers, where they are filtered, saved, and forwarded 1308*d4a07e70Sfengbojiangbased on configuration behaviors. 1309*d4a07e70Sfengbojiang 1310*d4a07e70Sfengbojiangsyslog is an older protocol, originally documented only in source 1311*d4a07e70Sfengbojiangcode. By the time :RFC:`3164` published, variation and mutation left the 1312*d4a07e70Sfengbojiangleading "<pri>" string as only common content. :RFC:`5424` defines a new 1313*d4a07e70Sfengbojiangversion (version 1) of syslog and introduces structured data into the 1314*d4a07e70Sfengbojiangmessages. Structured data is a set of name/value pairs transmitted 1315*d4a07e70Sfengbojiangdistinctly alongside the traditional text message, allowing filtering 1316*d4a07e70Sfengbojiangon precise values instead of regular expressions. 1317*d4a07e70Sfengbojiang 1318*d4a07e70SfengbojiangThese name/value pairs are scoped by a two-part identifier; an 1319*d4a07e70Sfengbojiangenterprise identifier names the party responsible for the message 1320*d4a07e70Sfengbojiangcatalog and a name identifying that message. `Enterprise IDs`_ are 1321*d4a07e70Sfengbojiangdefined by IANA, the Internet Assigned Numbers Authority. 1322*d4a07e70Sfengbojiang 1323*d4a07e70Sfengbojiang.. _Enterprise IDs: 1324*d4a07e70Sfengbojiang https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers 1325*d4a07e70Sfengbojiang 1326*d4a07e70SfengbojiangUse the `xo_set_syslog_enterprise_id` function to set the Enterprise 1327*d4a07e70SfengbojiangID, as needed. 1328*d4a07e70Sfengbojiang 1329*d4a07e70SfengbojiangThe message name should follow the conventions in 1330*d4a07e70Sfengbojiang:ref:`good-field-names`\ , as should the fields within the message:: 1331*d4a07e70Sfengbojiang 1332*d4a07e70Sfengbojiang /* Both of these calls are optional */ 1333*d4a07e70Sfengbojiang xo_set_syslog_enterprise_id(32473); 1334*d4a07e70Sfengbojiang xo_open_log("my-program", 0, LOG_DAEMON); 1335*d4a07e70Sfengbojiang 1336*d4a07e70Sfengbojiang /* Generate a syslog message */ 1337*d4a07e70Sfengbojiang xo_syslog(LOG_ERR, "upload-failed", 1338*d4a07e70Sfengbojiang "error <%d> uploading file '{:filename}' " 1339*d4a07e70Sfengbojiang "as '{:target/%s:%s}'", 1340*d4a07e70Sfengbojiang code, filename, protocol, remote); 1341*d4a07e70Sfengbojiang 1342*d4a07e70Sfengbojiang xo_syslog(LOG_INFO, "poofd-invalid-state", 1343*d4a07e70Sfengbojiang "state {:current/%u} is invalid {:connection/%u}", 1344*d4a07e70Sfengbojiang state, conn); 1345*d4a07e70Sfengbojiang 1346*d4a07e70SfengbojiangThe developer should be aware that the message name may be used in the 1347*d4a07e70Sfengbojiangfuture to allow access to further information, including 1348*d4a07e70Sfengbojiangdocumentation. Care should be taken to choose quality, descriptive 1349*d4a07e70Sfengbojiangnames. 1350*d4a07e70Sfengbojiang 1351*d4a07e70Sfengbojiang.. _syslog-details: 1352*d4a07e70Sfengbojiang 1353*d4a07e70SfengbojiangPriority, Facility, and Flags 1354*d4a07e70Sfengbojiang~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1355*d4a07e70Sfengbojiang 1356*d4a07e70SfengbojiangThe `xo_syslog`, `xo_vsyslog`, and `xo_open_log` functions 1357*d4a07e70Sfengbojiangaccept a set of flags which provide the priority of the message, the 1358*d4a07e70Sfengbojiangsource facility, and some additional features. These values are OR'd 1359*d4a07e70Sfengbojiangtogether to create a single integer argument:: 1360*d4a07e70Sfengbojiang 1361*d4a07e70Sfengbojiang xo_syslog(LOG_ERR | LOG_AUTH, "login-failed", 1362*d4a07e70Sfengbojiang "Login failed; user '{:user}' from host '{:address}'", 1363*d4a07e70Sfengbojiang user, addr); 1364*d4a07e70Sfengbojiang 1365*d4a07e70SfengbojiangThese values are defined in <syslog.h>. 1366*d4a07e70Sfengbojiang 1367*d4a07e70SfengbojiangThe priority value indicates the importance and potential impact of 1368*d4a07e70Sfengbojiangeach message: 1369*d4a07e70Sfengbojiang 1370*d4a07e70Sfengbojiang ============= ======================================================= 1371*d4a07e70Sfengbojiang Priority Description 1372*d4a07e70Sfengbojiang ============= ======================================================= 1373*d4a07e70Sfengbojiang LOG_EMERG A panic condition, normally broadcast to all users 1374*d4a07e70Sfengbojiang LOG_ALERT A condition that should be corrected immediately 1375*d4a07e70Sfengbojiang LOG_CRIT Critical conditions 1376*d4a07e70Sfengbojiang LOG_ERR Generic errors 1377*d4a07e70Sfengbojiang LOG_WARNING Warning messages 1378*d4a07e70Sfengbojiang LOG_NOTICE Non-error conditions that might need special handling 1379*d4a07e70Sfengbojiang LOG_INFO Informational messages 1380*d4a07e70Sfengbojiang LOG_DEBUG Developer-oriented messages 1381*d4a07e70Sfengbojiang ============= ======================================================= 1382*d4a07e70Sfengbojiang 1383*d4a07e70SfengbojiangThe facility value indicates the source of message, in fairly generic 1384*d4a07e70Sfengbojiangterms: 1385*d4a07e70Sfengbojiang 1386*d4a07e70Sfengbojiang =============== ======================================================= 1387*d4a07e70Sfengbojiang Facility Description 1388*d4a07e70Sfengbojiang =============== ======================================================= 1389*d4a07e70Sfengbojiang LOG_AUTH The authorization system (e.g. :manpage:`login(1)`) 1390*d4a07e70Sfengbojiang LOG_AUTHPRIV As LOG_AUTH, but logged to a privileged file 1391*d4a07e70Sfengbojiang LOG_CRON The cron daemon: :manpage:`cron(8)` 1392*d4a07e70Sfengbojiang LOG_DAEMON System daemons, not otherwise explicitly listed 1393*d4a07e70Sfengbojiang LOG_FTP The file transfer protocol daemons 1394*d4a07e70Sfengbojiang LOG_KERN Messages generated by the kernel 1395*d4a07e70Sfengbojiang LOG_LPR The line printer spooling system 1396*d4a07e70Sfengbojiang LOG_MAIL The mail system 1397*d4a07e70Sfengbojiang LOG_NEWS The network news system 1398*d4a07e70Sfengbojiang LOG_SECURITY Security subsystems, such as :manpage:`ipfw(4)` 1399*d4a07e70Sfengbojiang LOG_SYSLOG Messages generated internally by :manpage:`syslogd(8)` 1400*d4a07e70Sfengbojiang LOG_USER Messages generated by user processes (default) 1401*d4a07e70Sfengbojiang LOG_UUCP The uucp system 1402*d4a07e70Sfengbojiang LOG_LOCAL0..7 Reserved for local use 1403*d4a07e70Sfengbojiang =============== ======================================================= 1404*d4a07e70Sfengbojiang 1405*d4a07e70SfengbojiangIn addition to the values listed above, xo_open_log accepts a set of 1406*d4a07e70Sfengbojiangaddition flags requesting specific logging behaviors: 1407*d4a07e70Sfengbojiang 1408*d4a07e70Sfengbojiang ============ ==================================================== 1409*d4a07e70Sfengbojiang Flag Description 1410*d4a07e70Sfengbojiang ============ ==================================================== 1411*d4a07e70Sfengbojiang LOG_CONS If syslogd fails, attempt to write to /dev/console 1412*d4a07e70Sfengbojiang LOG_NDELAY Open the connection to :manpage:`syslogd(8)` immediately 1413*d4a07e70Sfengbojiang LOG_PERROR Write the message also to standard error output 1414*d4a07e70Sfengbojiang LOG_PID Log the process id with each message 1415*d4a07e70Sfengbojiang ============ ==================================================== 1416*d4a07e70Sfengbojiang 1417*d4a07e70Sfengbojiang.. index:: xo_syslog 1418*d4a07e70Sfengbojiang 1419*d4a07e70Sfengbojiangxo_syslog 1420*d4a07e70Sfengbojiang~~~~~~~~~ 1421*d4a07e70Sfengbojiang 1422*d4a07e70Sfengbojiang.. c:function:: void xo_syslog (int pri, const char *name, const char *fmt, ...) 1423*d4a07e70Sfengbojiang 1424*d4a07e70Sfengbojiang :param int pri: syslog priority 1425*d4a07e70Sfengbojiang :param name: Name of the syslog event 1426*d4a07e70Sfengbojiang :type name: const char * 1427*d4a07e70Sfengbojiang :param fmt: Format string, followed by arguments 1428*d4a07e70Sfengbojiang :type fmt: const char * 1429*d4a07e70Sfengbojiang :returns: void 1430*d4a07e70Sfengbojiang 1431*d4a07e70Sfengbojiang Use the `xo_syslog` function to generate syslog messages by calling 1432*d4a07e70Sfengbojiang it with a log priority and facility, a message name, a format 1433*d4a07e70Sfengbojiang string, and a set of arguments. The priority/facility argument are 1434*d4a07e70Sfengbojiang discussed above, as is the message name. 1435*d4a07e70Sfengbojiang 1436*d4a07e70Sfengbojiang The format string follows the same conventions as `xo_emit`'s format 1437*d4a07e70Sfengbojiang string, with each field being rendered as an SD-PARAM pair:: 1438*d4a07e70Sfengbojiang 1439*d4a07e70Sfengbojiang xo_syslog(LOG_ERR, "poofd-missing-file", 1440*d4a07e70Sfengbojiang "'{:filename}' not found: {:error/%m}", filename); 1441*d4a07e70Sfengbojiang 1442*d4a07e70Sfengbojiang ... [poofd-missing-file@32473 filename="/etc/poofd.conf" 1443*d4a07e70Sfengbojiang error="Permission denied"] '/etc/poofd.conf' not 1444*d4a07e70Sfengbojiang found: Permission denied 1445*d4a07e70Sfengbojiang 1446*d4a07e70SfengbojiangSupport functions 1447*d4a07e70Sfengbojiang~~~~~~~~~~~~~~~~~ 1448*d4a07e70Sfengbojiang 1449*d4a07e70Sfengbojiang.. index:: xo_vsyslog 1450*d4a07e70Sfengbojiang 1451*d4a07e70Sfengbojiangxo_vsyslog 1452*d4a07e70Sfengbojiang++++++++++ 1453*d4a07e70Sfengbojiang 1454*d4a07e70Sfengbojiang.. c:function:: void xo_vsyslog (int pri, const char *name, const char *fmt, va_list vap) 1455*d4a07e70Sfengbojiang 1456*d4a07e70Sfengbojiang :param int pri: syslog priority 1457*d4a07e70Sfengbojiang :param name: Name of the syslog event 1458*d4a07e70Sfengbojiang :type name: const char * 1459*d4a07e70Sfengbojiang :param fmt: Format string 1460*d4a07e70Sfengbojiang :type fmt: const char * 1461*d4a07e70Sfengbojiang :param va_list vap: Variadic argument list 1462*d4a07e70Sfengbojiang :returns: void 1463*d4a07e70Sfengbojiang 1464*d4a07e70Sfengbojiang xo_vsyslog is identical in function to xo_syslog, but takes the set of 1465*d4a07e70Sfengbojiang arguments using a va_list:: 1466*d4a07e70Sfengbojiang 1467*d4a07e70Sfengbojiang EXAMPLE: 1468*d4a07e70Sfengbojiang void 1469*d4a07e70Sfengbojiang my_log (const char *name, const char *fmt, ...) 1470*d4a07e70Sfengbojiang { 1471*d4a07e70Sfengbojiang va_list vap; 1472*d4a07e70Sfengbojiang va_start(vap, fmt); 1473*d4a07e70Sfengbojiang xo_vsyslog(LOG_ERR, name, fmt, vap); 1474*d4a07e70Sfengbojiang va_end(vap); 1475*d4a07e70Sfengbojiang } 1476*d4a07e70Sfengbojiang 1477*d4a07e70Sfengbojiang.. index:: xo_open_log 1478*d4a07e70Sfengbojiang 1479*d4a07e70Sfengbojiangxo_open_log 1480*d4a07e70Sfengbojiang+++++++++++ 1481*d4a07e70Sfengbojiang 1482*d4a07e70Sfengbojiang.. c:function:: void xo_open_log (const char *ident, int logopt, int facility) 1483*d4a07e70Sfengbojiang 1484*d4a07e70Sfengbojiang :param indent: 1485*d4a07e70Sfengbojiang :type indent: const char * 1486*d4a07e70Sfengbojiang :param int logopt: Bit field containing logging options 1487*d4a07e70Sfengbojiang :param int facility: 1488*d4a07e70Sfengbojiang :returns: void 1489*d4a07e70Sfengbojiang 1490*d4a07e70Sfengbojiang xo_open_log functions similar to :manpage:`openlog(3)`, allowing 1491*d4a07e70Sfengbojiang customization of the program name, the log facility number, and the 1492*d4a07e70Sfengbojiang additional option flags described in :ref:`syslog-details`. 1493*d4a07e70Sfengbojiang 1494*d4a07e70Sfengbojiang.. index:: xo_close_log 1495*d4a07e70Sfengbojiang 1496*d4a07e70Sfengbojiangxo_close_log 1497*d4a07e70Sfengbojiang++++++++++++ 1498*d4a07e70Sfengbojiang 1499*d4a07e70Sfengbojiang.. c:function:: void xo_close_log (void) 1500*d4a07e70Sfengbojiang 1501*d4a07e70Sfengbojiang The `xo_close_log` function is similar to :manpage:`closelog(3)`, 1502*d4a07e70Sfengbojiang closing the log file and releasing any associated resources. 1503*d4a07e70Sfengbojiang 1504*d4a07e70Sfengbojiang.. index:: xo_set_logmask 1505*d4a07e70Sfengbojiang 1506*d4a07e70Sfengbojiangxo_set_logmask 1507*d4a07e70Sfengbojiang++++++++++++++ 1508*d4a07e70Sfengbojiang 1509*d4a07e70Sfengbojiang.. c:function:: int xo_set_logmask (int maskpri) 1510*d4a07e70Sfengbojiang 1511*d4a07e70Sfengbojiang :param int maskpri: the log priority mask 1512*d4a07e70Sfengbojiang :returns: The previous log priority mask 1513*d4a07e70Sfengbojiang 1514*d4a07e70Sfengbojiang The `xo_set_logmask` function is similar to :manpage:`setlogmask(3)`, 1515*d4a07e70Sfengbojiang restricting the set of generated log event to those whose associated 1516*d4a07e70Sfengbojiang bit is set in maskpri. Use `LOG_MASK(pri)` to find the appropriate bit, 1517*d4a07e70Sfengbojiang or `LOG_UPTO(toppri)` to create a mask for all priorities up to and 1518*d4a07e70Sfengbojiang including toppri:: 1519*d4a07e70Sfengbojiang 1520*d4a07e70Sfengbojiang EXAMPLE: 1521*d4a07e70Sfengbojiang setlogmask(LOG_UPTO(LOG_WARN)); 1522*d4a07e70Sfengbojiang 1523*d4a07e70Sfengbojiang.. index:: xo_set_syslog_enterprise_id 1524*d4a07e70Sfengbojiang 1525*d4a07e70Sfengbojiangxo_set_syslog_enterprise_id 1526*d4a07e70Sfengbojiang+++++++++++++++++++++++++++ 1527*d4a07e70Sfengbojiang 1528*d4a07e70Sfengbojiang.. c:function:: void xo_set_syslog_enterprise_id (unsigned short eid) 1529*d4a07e70Sfengbojiang 1530*d4a07e70Sfengbojiang Use the `xo_set_syslog_enterprise_id` to supply a platform- or 1531*d4a07e70Sfengbojiang application-specific enterprise id. This value is used in any future 1532*d4a07e70Sfengbojiang syslog messages. 1533*d4a07e70Sfengbojiang 1534*d4a07e70Sfengbojiang Ideally, the operating system should supply a default value via the 1535*d4a07e70Sfengbojiang "kern.syslog.enterprise_id" sysctl value. Lacking that, the 1536*d4a07e70Sfengbojiang application should provide a suitable value. 1537*d4a07e70Sfengbojiang 1538*d4a07e70SfengbojiangEnterprise IDs are administered by IANA, the Internet Assigned Number 1539*d4a07e70SfengbojiangAuthority. The complete list is EIDs on their web site:: 1540*d4a07e70Sfengbojiang 1541*d4a07e70Sfengbojiang https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers 1542*d4a07e70Sfengbojiang 1543*d4a07e70SfengbojiangNew EIDs can be requested from IANA using the following page:: 1544*d4a07e70Sfengbojiang 1545*d4a07e70Sfengbojiang http://pen.iana.org/pen/PenApplication.page 1546*d4a07e70Sfengbojiang 1547*d4a07e70SfengbojiangEach software development organization that defines a set of syslog 1548*d4a07e70Sfengbojiangmessages should register their own EID and use that value in their 1549*d4a07e70Sfengbojiangsoftware to ensure that messages can be uniquely identified by the 1550*d4a07e70Sfengbojiangcombination of EID + message name. 1551*d4a07e70Sfengbojiang 1552*d4a07e70SfengbojiangCreating Custom Encoders 1553*d4a07e70Sfengbojiang------------------------ 1554*d4a07e70Sfengbojiang 1555*d4a07e70SfengbojiangThe number of encoding schemes in current use is staggering, with new 1556*d4a07e70Sfengbojiangand distinct schemes appearing daily. While libxo provide XML, JSON, 1557*d4a07e70SfengbojiangHMTL, and text natively, there are requirements for other encodings. 1558*d4a07e70Sfengbojiang 1559*d4a07e70SfengbojiangRather than bake support for all possible encoders into libxo, the API 1560*d4a07e70Sfengbojiangallows them to be defined externally. libxo can then interfaces with 1561*d4a07e70Sfengbojiangthese encoding modules using a simplistic API. libxo processes all 1562*d4a07e70Sfengbojiangfunctions calls, handles state transitions, performs all formatting, 1563*d4a07e70Sfengbojiangand then passes the results as operations to a customized encoding 1564*d4a07e70Sfengbojiangfunction, which implements specific encoding logic as required. This 1565*d4a07e70Sfengbojiangmeans your encoder doesn't need to detect errors with unbalanced 1566*d4a07e70Sfengbojiangopen/close operations but can rely on libxo to pass correct data. 1567*d4a07e70Sfengbojiang 1568*d4a07e70SfengbojiangBy making a simple API, libxo internals are not exposed, insulating the 1569*d4a07e70Sfengbojiangencoder and the library from future or internal changes. 1570*d4a07e70Sfengbojiang 1571*d4a07e70SfengbojiangThe three elements of the API are: 1572*d4a07e70Sfengbojiang 1573*d4a07e70Sfengbojiang- loading 1574*d4a07e70Sfengbojiang- initialization 1575*d4a07e70Sfengbojiang- operations 1576*d4a07e70Sfengbojiang 1577*d4a07e70SfengbojiangThe following sections provide details about these topics. 1578*d4a07e70Sfengbojiang 1579*d4a07e70Sfengbojiang.. index:: CBOR 1580*d4a07e70Sfengbojiang 1581*d4a07e70Sfengbojianglibxo source contains an encoder for Concise Binary Object 1582*d4a07e70SfengbojiangRepresentation, aka CBOR (:RFC:`7049`), which can be used as an 1583*d4a07e70Sfengbojiangexample for the API for other encoders. 1584*d4a07e70Sfengbojiang 1585*d4a07e70SfengbojiangLoading Encoders 1586*d4a07e70Sfengbojiang~~~~~~~~~~~~~~~~ 1587*d4a07e70Sfengbojiang 1588*d4a07e70SfengbojiangEncoders can be registered statically or discovered dynamically. 1589*d4a07e70SfengbojiangApplications can choose to call the `xo_encoder_register` function 1590*d4a07e70Sfengbojiangto explicitly register encoders, but more typically they are built as 1591*d4a07e70Sfengbojiangshared libraries, placed in the libxo/extensions directory, and loaded 1592*d4a07e70Sfengbojiangbased on name. libxo looks for a file with the name of the encoder 1593*d4a07e70Sfengbojiangand an extension of ".enc". This can be a file or a symlink to the 1594*d4a07e70Sfengbojiangshared library file that supports the encoder:: 1595*d4a07e70Sfengbojiang 1596*d4a07e70Sfengbojiang % ls -1 lib/libxo/extensions/*.enc 1597*d4a07e70Sfengbojiang lib/libxo/extensions/cbor.enc 1598*d4a07e70Sfengbojiang lib/libxo/extensions/test.enc 1599*d4a07e70Sfengbojiang 1600*d4a07e70SfengbojiangEncoder Initialization 1601*d4a07e70Sfengbojiang~~~~~~~~~~~~~~~~~~~~~~ 1602*d4a07e70Sfengbojiang 1603*d4a07e70SfengbojiangEach encoder must export a symbol used to access the library, which 1604*d4a07e70Sfengbojiangmust have the following signature:: 1605*d4a07e70Sfengbojiang 1606*d4a07e70Sfengbojiang int xo_encoder_library_init (XO_ENCODER_INIT_ARGS); 1607*d4a07e70Sfengbojiang 1608*d4a07e70Sfengbojiang`XO_ENCODER_INIT_ARGS` is a macro defined in "xo_encoder.h" that defines 1609*d4a07e70Sfengbojiangan argument called "arg", a pointer of the type 1610*d4a07e70Sfengbojiang`xo_encoder_init_args_t`. This structure contains two fields: 1611*d4a07e70Sfengbojiang 1612*d4a07e70Sfengbojiang- `xei_version` is the version number of the API as implemented 1613*d4a07e70Sfengbojiang within libxo. This version is currently as 1 using 1614*d4a07e70Sfengbojiang `XO_ENCODER_VERSION`. This number can be checked to ensure 1615*d4a07e70Sfengbojiang compatibility. The working assumption is that all versions should 1616*d4a07e70Sfengbojiang be backward compatible, but each side may need to accurately know 1617*d4a07e70Sfengbojiang the version supported by the other side. `xo_encoder_library_init` 1618*d4a07e70Sfengbojiang can optionally check this value, and must then set it to the version 1619*d4a07e70Sfengbojiang number used by the encoder, allowing libxo to detect version 1620*d4a07e70Sfengbojiang differences and react accordingly. For example, if version 2 adds 1621*d4a07e70Sfengbojiang new operations, then libxo will know that an encoding library that 1622*d4a07e70Sfengbojiang set `xei_version` to 1 cannot be expected to handle those new 1623*d4a07e70Sfengbojiang operations. 1624*d4a07e70Sfengbojiang 1625*d4a07e70Sfengbojiang- xei_handler must be set to a pointer to a function of type 1626*d4a07e70Sfengbojiang `xo_encoder_func_t`, as defined in "xo_encoder.h". This function 1627*d4a07e70Sfengbojiang takes a set of parameters: 1628*d4a07e70Sfengbojiang - xop is a pointer to the opaque `xo_handle_t` structure 1629*d4a07e70Sfengbojiang - op is an integer representing the current operation 1630*d4a07e70Sfengbojiang - name is a string whose meaning differs by operation 1631*d4a07e70Sfengbojiang - value is a string whose meaning differs by operation 1632*d4a07e70Sfengbojiang - private is an opaque structure provided by the encoder 1633*d4a07e70Sfengbojiang 1634*d4a07e70SfengbojiangAdditional arguments may be added in the future, so handler functions 1635*d4a07e70Sfengbojiangshould use the `XO_ENCODER_HANDLER_ARGS` macro. An appropriate 1636*d4a07e70Sfengbojiang"extern" declaration is provided to help catch errors. 1637*d4a07e70Sfengbojiang 1638*d4a07e70SfengbojiangOnce the encoder initialization function has completed processing, it 1639*d4a07e70Sfengbojiangshould return zero to indicate that no error has occurred. A non-zero 1640*d4a07e70Sfengbojiangreturn code will cause the handle initialization to fail. 1641*d4a07e70Sfengbojiang 1642*d4a07e70SfengbojiangOperations 1643*d4a07e70Sfengbojiang~~~~~~~~~~ 1644*d4a07e70Sfengbojiang 1645*d4a07e70SfengbojiangThe encoder API defines a set of operations representing the 1646*d4a07e70Sfengbojiangprocessing model of libxo. Content is formatted within libxo, and 1647*d4a07e70Sfengbojiangcallbacks are made to the encoder's handler function when data is 1648*d4a07e70Sfengbojiangready to be processed: 1649*d4a07e70Sfengbojiang 1650*d4a07e70Sfengbojiang ======================= ======================================= 1651*d4a07e70Sfengbojiang Operation Meaning (Base function) 1652*d4a07e70Sfengbojiang ======================= ======================================= 1653*d4a07e70Sfengbojiang XO_OP_CREATE Called when the handle is created 1654*d4a07e70Sfengbojiang XO_OP_OPEN_CONTAINER Container opened (xo_open_container) 1655*d4a07e70Sfengbojiang XO_OP_CLOSE_CONTAINER Container closed (xo_close_container) 1656*d4a07e70Sfengbojiang XO_OP_OPEN_LIST List opened (xo_open_list) 1657*d4a07e70Sfengbojiang XO_OP_CLOSE_LIST List closed (xo_close_list) 1658*d4a07e70Sfengbojiang XO_OP_OPEN_LEAF_LIST Leaf list opened (xo_open_leaf_list) 1659*d4a07e70Sfengbojiang XO_OP_CLOSE_LEAF_LIST Leaf list closed (xo_close_leaf_list) 1660*d4a07e70Sfengbojiang XO_OP_OPEN_INSTANCE Instance opened (xo_open_instance) 1661*d4a07e70Sfengbojiang XO_OP_CLOSE_INSTANCE Instance closed (xo_close_instance) 1662*d4a07e70Sfengbojiang XO_OP_STRING Field with Quoted UTF-8 string 1663*d4a07e70Sfengbojiang XO_OP_CONTENT Field with content 1664*d4a07e70Sfengbojiang XO_OP_FINISH Finish any pending output 1665*d4a07e70Sfengbojiang XO_OP_FLUSH Flush any buffered output 1666*d4a07e70Sfengbojiang XO_OP_DESTROY Clean up resources 1667*d4a07e70Sfengbojiang XO_OP_ATTRIBUTE An attribute name/value pair 1668*d4a07e70Sfengbojiang XO_OP_VERSION A version string 1669*d4a07e70Sfengbojiang ======================= ======================================= 1670*d4a07e70Sfengbojiang 1671*d4a07e70SfengbojiangFor all the open and close operations, the name parameter holds the 1672*d4a07e70Sfengbojiangname of the construct. For string, content, and attribute operations, 1673*d4a07e70Sfengbojiangthe name parameter is the name of the field and the value parameter is 1674*d4a07e70Sfengbojiangthe value. "string" are differentiated from "content" to allow differing 1675*d4a07e70Sfengbojiangtreatment of true, false, null, and numbers from real strings, though 1676*d4a07e70Sfengbojiangcontent values are formatted as strings before the handler is called. 1677*d4a07e70SfengbojiangFor version operations, the value parameter contains the version. 1678*d4a07e70Sfengbojiang 1679*d4a07e70SfengbojiangAll strings are encoded in UTF-8. 1680