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