xref: /f-stack/tools/libxo/doc/api.rst (revision d4a07e70)
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