Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
.. index: API

The libxo API
=============

This section gives details about the functions in libxo, how to call
them, and the actions they perform.

.. index:: Handles
.. _handles:

Handles
-------

libxo uses "handles" to control its rendering functionality.  The
handle contains state and buffered data, as well as callback functions
to process data.

Handles give an abstraction for libxo that encapsulates the state of a
stream of output.  Handles have the data type "`xo_handle_t`" and are
opaque to the caller.

The library has a default handle that is automatically initialized.
By default, this handle will send text style output (`XO_STYLE_TEXT`) to
standard output.  The xo_set_style and xo_set_flags functions can be
used to change this behavior.

For the typical command that is generating output on standard output,
there is no need to create an explicit handle, but they are available
when needed, e.g., for daemons that generate multiple streams of
output.

Many libxo functions take a handle as their first parameter; most that
do not use the default handle.  Any function taking a handle can be
passed NULL to access the default handle.  For the convenience of
callers, the libxo library includes handle-less functions that
implicitly use the default handle.

For example, the following are equivalent::

    xo_emit("test");
    xo_emit_h(NULL, "test");

Handles are created using `xo_create` and destroy using
`xo_destroy`. 

.. index:: xo_create

xo_create
~~~~~~~~~

.. c:function:: xo_handle_t *xo_create (xo_style_t style, xo_xof_flags_t flags)

  The `xo_create` function allocates a new handle which can be passed
  to further libxo function calls.  The `xo_handle_t` structure is
  opaque.

  :param xo_style_t style: Output style (XO_STYLE\_*)
  :param xo_xof_flags_t flags: Flags for this handle (XOF\_*)
  :return: New libxo handle
  :rtype: xo_handle_t \*

  ::

    EXAMPLE:
        xo_handle_t *xop = xo_create(XO_STYLE_JSON, XOF_WARN | XOF_PRETTY);
        ....
        xo_emit_h(xop, "testing\n");

  See also :ref:`output-styles` and :ref:`flags`.

.. index:: xo_create_to_file
.. index:: XOF_CLOSE_FP

xo_create_to_file
~~~~~~~~~~~~~~~~~

.. c:function::
  xo_handle_t *xo_create_to_file (FILE *fp, unsigned style, unsigned flags)

  The `xo_create_to_file` function is aconvenience function is
  provided for situations when output should be written to a different
  file, rather than the default of standard output.

  The `XOF_CLOSE_FP` flag can be set on the returned handle to trigger a
  call to fclose() for the FILE pointer when the handle is destroyed,
  avoiding the need for the caller to perform this task.

  :param fp: FILE to use as base for this handle
  :type fp: FILE *
  :param xo_style_t style: Output style (XO_STYLE\_*)
  :param xo_xof_flags_t flags: Flags for this handle (XOF\_*)
  :return: New libxo handle
  :rtype: xo_handle_t \*

.. index:: xo_set_writer
.. index:: xo_write_func_t
.. index:: xo_close_func_t
.. index:: xo_flush_func_t

xo_set_writer
~~~~~~~~~~~~~

.. c:function::
  void xo_set_writer (xo_handle_t *xop, void *opaque, \
  xo_write_func_t write_func, xo_close_func_t close_func, \
  xo_flush_func_t flush_func)

  The `xo_set_writer` function allows custom functions which can
  tailor how libxo writes data.  The `opaque` argument is recorded and
  passed back to the functions, allowing the function to acquire
  context information. The *write_func* function writes data to the
  output stream.  The *close_func* function can release this opaque
  data and any other resources as needed.  The *flush_func* function
  is called to flush buffered data associated with the opaque object.

  :param xop: Handle to modify (or NULL for default handle)
  :type xop: xo_handle_t *
  :param opaque: Pointer to opaque data passed to the given functions
  :type opaque: void *
  :param xo_write_func_t write_func: New write function
  :param xo_close_func_t close_func: New close function
  :param xo_flush_func_t flush_func: New flush function
  :returns: void

.. index:: xo_get_style

xo_get_style
~~~~~~~~~~~~

.. c:function:: xo_style_t xo_get_style(xo_handle_t *xop)

  Use the `xo_get_style` function to find the current output style for
  a given handle.  To use the default handle, pass a `NULL` handle.

  :param xop: Handle to interrogate (or NULL for default handle)
  :type xop: xo_handle_t *
  :returns: Output style (XO_STYLE\_*)
  :rtype: xo_style_t

  ::

    EXAMPLE::
        style = xo_get_style(NULL);

.. index::  XO_STYLE_TEXT
.. index::  XO_STYLE_XML
.. index::  XO_STYLE_JSON
.. index::  XO_STYLE_HTML

.. _output-styles:

Output Styles (XO_STYLE\_\*)
++++++++++++++++++++++++++++

The libxo functions accept a set of output styles:

=============== =========================
 Flag            Description
=============== =========================
 XO_STYLE_TEXT   Traditional text output
 XO_STYLE_XML    XML encoded data
 XO_STYLE_JSON   JSON encoded data
 XO_STYLE_HTML   HTML encoded data
=============== =========================

The "XML", "JSON", and "HTML" output styles all use the UTF-8
character encoding.  "TEXT" using locale-based encoding.

.. index:: xo_set_style

xo_set_style
~~~~~~~~~~~~

.. c:function:: void xo_set_style(xo_handle_t *xop, xo_style_t style)

  The `xo_set_style` function is used to change the output style
  setting for a handle.  To use the default handle, pass a `NULL`
  handle.

  :param xop: Handle to modify
  :type xop: xo_handle_t *
  :param xo_style_t style: Output style (XO_STYLE\_*)
  :returns: void

  ::

    EXAMPLE:
        xo_set_style(NULL, XO_STYLE_XML);

.. index:: xo_set_style_name

xo_set_style_name
~~~~~~~~~~~~~~~~~

.. c:function:: int xo_set_style_name (xo_handle_t *xop, const char *style)

  The `xo_set_style_name` function can be used to set the style based
  on a name encoded as a string: The name can be any of the supported
  styles: "text", "xml", "json", or "html".

  :param xop: Handle for modify (or NULL for default handle)
  :type xop: xo_handle_t \*
  :param style: Text name of the style
  :type style: const char \*
  :returns: zero for success, non-zero for error
  :rtype: int

  ::

    EXAMPLE:
        xo_set_style_name(NULL, "html");

.. index:: xo_set_flags

xo_set_flags
~~~~~~~~~~~~

.. c:function:: void xo_set_flags(xo_handle_t *xop, xo_xof_flags_t flags)

  :param xop: Handle for modify (or NULL for default handle)
  :type xop: xo_handle_t \*
  :param xo_xof_flags_t flags: Flags to add for the handle
  :returns: void

  Use the `xo_set_flags` function to turn on flags for a given libxo
  handle.  To use the default handle, pass a `NULL` handle.

  ::

    EXAMPLE:
        xo_set_flags(NULL, XOF_PRETTY | XOF_WARN);

.. index:: Flags; XOF_*
.. index:: XOF_CLOSE_FP
.. index:: XOF_COLOR
.. index:: XOF_COLOR_ALLOWED
.. index:: XOF_DTRT
.. index:: XOF_INFO
.. index:: XOF_KEYS
.. index:: XOF_NO_ENV
.. index:: XOF_NO_HUMANIZE
.. index:: XOF_PRETTY
.. index:: XOF_UNDERSCORES
.. index:: XOF_UNITS
.. index:: XOF_WARN
.. index:: XOF_WARN_XML
.. index:: XOF_XPATH
.. index:: XOF_COLUMNS
.. index:: XOF_FLUSH

.. _flags:

Flags (XOF\_\*)
+++++++++++++++

The set of valid flags include:

=================== =========================================
 Flag                Description
=================== =========================================
 XOF_CLOSE_FP        Close file pointer on `xo_destroy`
 XOF_COLOR           Enable color and effects in output
 XOF_COLOR_ALLOWED   Allow color/effect for terminal output
 XOF_DTRT            Enable "do the right thing" mode
 XOF_INFO            Display info data attributes (HTML)
 XOF_KEYS            Emit the key attribute (XML)
 XOF_NO_ENV          Do not use the :ref:`libxo-options` env var
 XOF_NO_HUMANIZE     Display humanization (TEXT, HTML)
 XOF_PRETTY          Make "pretty printed" output
 XOF_UNDERSCORES     Replaces hyphens with underscores
 XOF_UNITS           Display units (XML, HMTL)
 XOF_WARN            Generate warnings for broken calls
 XOF_WARN_XML        Generate warnings in XML on stdout
 XOF_XPATH           Emit XPath expressions (HTML)
 XOF_COLUMNS         Force xo_emit to return columns used
 XOF_FLUSH           Flush output after each `xo_emit` call
=================== =========================================

The `XOF_CLOSE_FP` flag will trigger the call of the *close_func*
(provided via `xo_set_writer`) when the handle is destroyed.

The `XOF_COLOR` flag enables color and effects in output regardless
of output device, while the `XOF_COLOR_ALLOWED` flag allows color
and effects only if the output device is a terminal.

The `XOF_PRETTY` flag requests "pretty printing", which will trigger
the addition of indentation and newlines to enhance the readability of
XML, JSON, and HTML output.  Text output is not affected.

The `XOF_WARN` flag requests that warnings will trigger diagnostic
output (on standard error) when the library notices errors during
operations, or with arguments to functions.  Without warnings enabled,
such conditions are ignored.

Warnings allow developers to debug their interaction with libxo.
The function `xo_failure` can used as a breakpoint for a debugger,
regardless of whether warnings are enabled.

If the style is `XO_STYLE_HTML`, the following additional flags can be
used:

=============== =========================================
 Flag            Description
=============== =========================================
 XOF_XPATH       Emit "data-xpath" attributes
 XOF_INFO        Emit additional info fields
=============== =========================================

The `XOF_XPATH` flag enables the emission of XPath expressions detailing
the hierarchy of XML elements used to encode the data field, if the
XPATH style of output were requested.

The `XOF_INFO` flag encodes additional informational fields for HTML
output.  See :ref:`field-information` for details.

If the style is `XO_STYLE_XML`, the following additional flags can be
used:

=============== =========================================
 Flag            Description
=============== =========================================
 XOF_KEYS        Flag "key" fields for XML
=============== =========================================

The `XOF_KEYS` flag adds "key" attribute to the XML encoding for
field definitions that use the "k" modifier.  The key attribute has
the value "key"::

    xo_emit("{k:name}", item);

  XML:
      <name key="key">truck</name>

.. index:: xo_clear_flags

xo_clear_flags
++++++++++++++

.. c:function:: void xo_clear_flags (xo_handle_t *xop, xo_xof_flags_t flags)

  :param xop: Handle for modify (or NULL for default handle)
  :type xop: xo_handle_t \*
  :param xo_xof_flags_t flags: Flags to clear for the handle
  :returns: void

  Use the `xo_clear_flags` function to turn off the given flags in a
  specific handle.  To use the default handle, pass a `NULL` handle.

.. index:: xo_set_options

xo_set_options
++++++++++++++

.. c:function:: int xo_set_options (xo_handle_t *xop, const char *input)

  :param xop: Handle for modify (or NULL for default handle)
  :type xop: xo_handle_t \*
  :param input: string containing options to set
  :type input: const char *
  :returns: zero for success, non-zero for error
  :rtype: int

  The `xo_set_options` function accepts a comma-separated list of
  output styles and modifier flags and enables them for a specific
  handle.  The options are identical to those listed in
  :ref:`options`.  To use the default handle, pass a `NULL` handle.

.. index:: xo_destroy

xo_destroy
++++++++++

.. c:function:: void xo_destroy(xo_handle_t *xop)

  :param xop: Handle for modify (or NULL for default handle)
  :type xop: xo_handle_t \*
  :returns: void  

  The `xo_destroy` function releases a handle and any resources it is
  using.  Calling `xo_destroy` with a `NULL` handle will release any
  resources associated with the default handle.

.. index:: xo_emit

Emitting Content (xo_emit)
--------------------------

The functions in this section are used to emit output.

The "fmt" argument is a string containing field descriptors as
specified in :ref:`format-strings`.  The use of a handle is optional and
`NULL` can be passed to access the internal "default" handle.  See
:ref:`handles`.

The remaining arguments to `xo_emit` and `xo_emit_h` are a set of
arguments corresponding to the fields in the format string.  Care must
be taken to ensure the argument types match the fields in the format
string, since an inappropriate cast can ruin your day.  The vap
argument to `xo_emit_hv` points to a variable argument list that can
be used to retrieve arguments via `va_arg`.

.. c:function:: xo_ssize_t xo_emit (const char *fmt, ...)

  :param fmt: The format string, followed by zero or more arguments
  :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted
  :rtype: xo_ssize_t

.. c:function:: xo_ssize_t xo_emit_h (xo_handle_t *xop, const char *fmt, ...)

  :param xop: Handle for modify (or NULL for default handle)
  :type xop: xo_handle_t \*
  :param fmt: The format string, followed by zero or more arguments
  :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted
  :rtype: xo_ssize_t

.. c:function:: xo_ssize_t xo_emit_hv (xo_handle_t *xop, const char *fmt, va_list vap)

  :param xop: Handle for modify (or NULL for default handle)
  :type xop: xo_handle_t \*
  :param fmt: The format string
  :param va_list vap: A set of variadic arguments
  :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted
  :rtype: xo_ssize_t

.. index:: xo_emit_field

Single Field Emitting Functions (xo_emit_field)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The functions in this section can also make output, but only make a
single field at a time.  These functions are intended to avoid the
scenario where one would otherwise need to compose a format
descriptors using `snprintf`.  The individual parts of the format
descriptor are passed in distinctly.

.. c:function:: xo_ssize_t xo_emit_field (const char *rolmod, const char *contents, const char *fmt, const char *efmt, ...)

  :param rolmod: A comma-separated list of field roles and field modifiers
  :type rolmod: const char *
  :param contents: The "contents" portion of the field description string
  :type contents: const char *
  :param fmt: Content format string
  :type fmt: const char *
  :param efmt: Encoding format string, followed by additional arguments
  :type efmt: const char *
  :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted
  :rtype: xo_ssize_t

  ::

    EXAMPLE::
        xo_emit_field("T", "Host name is ", NULL, NULL);
        xo_emit_field("V", "host-name", NULL, NULL, host-name);

.. 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, ...)

  :param xop: Handle for modify (or NULL for default handle)
  :type xop: xo_handle_t \*
  :param rolmod: A comma-separated list of field roles and field modifiers
  :type rolmod: const char *
  :param contents: The "contents" portion of the field description string
  :type contents: const char *
  :param fmt: Content format string
  :type fmt: const char *
  :param efmt: Encoding format string, followed by additional arguments
  :type efmt: const char *
  :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted
  :rtype: xo_ssize_t

.. 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)

  :param xop: Handle for modify (or NULL for default handle)
  :type xop: xo_handle_t \*
  :param rolmod: A comma-separated list of field roles and field modifiers
  :type rolmod: const char *
  :param contents: The "contents" portion of the field description string
  :type contents: const char *
  :param fmt: Content format string
  :type fmt: const char *
  :param efmt: Encoding format string
  :type efmt: const char *
  :param va_list vap: A set of variadic arguments
  :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted
  :rtype: xo_ssize_t

.. index:: xo_attr
.. _xo_attr:

Attributes (xo_attr)
~~~~~~~~~~~~~~~~~~~~

The functions in this section emit an XML attribute with the given name
and value.  This only affects the XML output style.

The `name` parameter give the name of the attribute to be encoded.  The
`fmt` parameter gives a printf-style format string used to format the
value of the attribute using any remaining arguments, or the vap
parameter passed to `xo_attr_hv`.

All attributes recorded via `xo_attr` are placed on the next
container, instance, leaf, or leaf list that is emitted.

Since attributes are only emitted in XML, their use should be limited
to meta-data and additional or redundant representations of data
already emitted in other form.

.. c:function:: xo_ssize_t xo_attr (const char *name, const char *fmt, ...)

  :param name: Attribute name
  :type name: const char *
  :param fmt: Attribute value, as variadic arguments
  :type fmt: const char *
  :returns: -1 for error, or the number of bytes in the formatted attribute value
  :rtype: xo_ssize_t

  ::

    EXAMPLE:
        xo_attr("seconds", "%ld", (unsigned long) login_time);
        struct tm *tmp = localtime(login_time);
        strftime(buf, sizeof(buf), "%R", tmp);
        xo_emit("Logged in at {:login-time}\n", buf);
    XML:
        <login-time seconds="1408336270">00:14</login-time>


.. c:function:: xo_ssize_t xo_attr_h (xo_handle_t *xop, const char *name, const char *fmt, ...)

  :param xop: Handle for modify (or NULL for default handle)
  :type xop: xo_handle_t \*

  The `xo_attr_h` function follows the conventions of `xo_attr` but
  adds an explicit libxo handle.

.. c:function:: xo_ssize_t xo_attr_hv (xo_handle_t *xop, const char *name, const char *fmt, va_list vap)

  The `xo_attr_h` function follows the conventions of `xo_attr_h`
  but replaced the variadic list with a variadic pointer.

.. index:: xo_flush

Flushing Output (xo_flush)
~~~~~~~~~~~~~~~~~~~~~~~~~~

.. c:function:: xo_ssize_t xo_flush (void)

  :returns: -1 for error, or the number of bytes generated
  :rtype: xo_ssize_t

  libxo buffers data, both for performance and consistency, but also
  to allow for the proper function of various advanced features.  At
  various times, the caller may wish to flush any data buffered within
  the library.  The `xo_flush` call is used for this.

  Calling `xo_flush` also triggers the flush function associated with
  the handle.  For the default handle, this is equivalent to
  "fflush(stdio);".

.. c:function:: xo_ssize_t xo_flush_h (xo_handle_t *xop)

  :param xop: Handle for flush (or NULL for default handle)
  :type xop: xo_handle_t \*
  :returns: -1 for error, or the number of bytes generated
  :rtype: xo_ssize_t

  The `xo_flush_h` function follows the conventions of `xo_flush`,
  but adds an explicit libxo handle.

.. index:: xo_finish
.. index:: xo_finish_atexit
.. index:: atexit

Finishing Output (xo_finish)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

When the program is ready to exit or close a handle, a call to
`xo_finish` or `xo_finish_h` is required.  This flushes any buffered
data, closes open libxo constructs, and completes any pending
operations.

Calling this function is vital to the proper operation of libxo,
especially for the non-TEXT output styles.

.. c:function:: xo_ssize_t xo_finish (void)

  :returns: -1 on error, or the number of bytes flushed
  :rtype: xo_ssize_t

.. c:function:: xo_ssize_t xo_finish_h (xo_handle_t *xop)

  :param xop: Handle for finish (or NULL for default handle)
  :type xop: xo_handle_t \*
  :returns: -1 on error, or the number of bytes flushed
  :rtype: xo_ssize_t

.. c:function:: void xo_finish_atexit (void)

  The `xo_finish_atexit` function is suitable for use with
  :manpage:`atexit(3)` to ensure that `xo_finish` is called
  on the default handle when the application exits.

.. index:: UTF-8
.. index:: xo_open_container
.. index:: xo_close_container

Emitting Hierarchy
------------------

libxo represents two types of hierarchy: containers and lists.  A
container appears once under a given parent where a list consists of
instances that can appear multiple times.  A container is used to hold
related fields and to give the data organization and scope.

.. index:: YANG

.. admonition:: YANG Terminology

  libxo uses terminology from YANG (:RFC:`7950`), the data modeling
  language for NETCONF: container, list, leaf, and leaf-list.

For XML and JSON, individual fields appear inside hierarchies which
provide context and meaning to the fields.  Unfortunately, these
encoding have a basic disconnect between how lists is similar objects
are represented.

XML encodes lists as set of sequential elements::

    <user>phil</user>
    <user>pallavi</user>
    <user>sjg</user>

JSON encodes lists using a single name and square brackets::

    "user": [ "phil", "pallavi", "sjg" ]

This means libxo needs three distinct indications of hierarchy: one
for containers of hierarchy appear only once for any specific parent,
one for lists, and one for each item in a list.

.. index:: Containers

Containers
~~~~~~~~~~

A "*container*" is an element of a hierarchy that appears only once
under any specific parent.  The container has no value, but serves to
contain and organize other nodes.

To open a container, call xo_open_container() or
xo_open_container_h().  The former uses the default handle and the
latter accepts a specific handle.  To close a level, use the
xo_close_container() or xo_close_container_h() functions.

Each open call must have a matching close call.  If the XOF_WARN flag
is set and the name given does not match the name of the currently open
container, a warning will be generated.

.. c:function:: xo_ssize_t xo_open_container (const char *name)

  :param name: Name of the container
  :type name: const char *
  :returns: -1 on error, or the number of bytes generated
  :rtype: xo_ssize_t

  The `name` parameter gives the name of the container, encoded in
  UTF-8.  Since ASCII is a proper subset of UTF-8, traditional C
  strings can be used directly.

.. c:function:: xo_ssize_t xo_open_container_h (xo_handle_t *xop, const char *name)

  :param xop: Handle to use (or NULL for default handle)
  :type xop: xo_handle_t *

  The `xo_open_container_h` function adds a `handle` parameter.

.. c:function:: xo_ssize_t xo_close_container (const char *name)

  :param name: Name of the container
  :type name: const char *
  :returns: -1 on error, or the number of bytes generated
  :rtype: xo_ssize_t

.. c:function:: xo_ssize_t xo_close_container_h (xo_handle_t *xop, const char *name)

  :param xop: Handle to use (or NULL for default handle)
  :type xop: xo_handle_t *

  The `xo_close_container_h` function adds a `handle` parameter.

Use the :index:`XOF_WARN` flag to generate a warning if the name given
on the close does not match the current open container.

For TEXT and HTML output, containers are not rendered into output
text, though for HTML they are used to record an XPath value when the
:index:`XOF_XPATH` flag is set.

::

    EXAMPLE:
        xo_open_container("top");
        xo_open_container("system");
        xo_emit("{:host-name/%s%s%s}", hostname,
                domainname ? "." : "", domainname ?: "");
        xo_close_container("system");
        xo_close_container("top");
    TEXT:
        my-host.example.org
    XML:
        <top>
          <system>
              <host-name>my-host.example.org</host-name>
          </system>
        </top>
    JSON:
        "top" : {
          "system" : {
              "host-name": "my-host.example.org"
          }
        }
    HTML:
        <div class="data"
             data-tag="host-name">my-host.example.org</div>

.. index:: xo_open_instance
.. index:: xo_close_instance
.. index:: xo_open_list
.. index:: xo_close_list

Lists and Instances
~~~~~~~~~~~~~~~~~~~

A "*list*" is set of one or more instances that appear under the same
parent.  The instances contain details about a specific object.  One
can think of instances as objects or records.  A call is needed to
open and close the list, while a distinct call is needed to open and
close each instance of the list.

The name given to all calls must be identical, and it is strongly
suggested that the name be singular, not plural, as a matter of
style and usage expectations::

  EXAMPLE:
      xo_open_list("item");

      for (ip = list; ip->i_title; ip++) {
          xo_open_instance("item");
          xo_emit("{L:Item} '{:name/%s}':\n", ip->i_title);
          xo_close_instance("item");
      }

      xo_close_list("item");

Getting the list and instance calls correct is critical to the proper
generation of XML and JSON data.

Opening Lists
+++++++++++++

.. c:function:: xo_ssize_t xo_open_list (const char *name)

  :param name: Name of the list
  :type name: const char *
  :returns: -1 on error, or the number of bytes generated
  :rtype: xo_ssize_t
		
  The `xo_open_list` function open a list of instances.

.. c:function:: xo_ssize_t xo_open_list_h (xo_handle_t *xop, const char *name)

  :param xop: Handle to use (or NULL for default handle)
  :type xop: xo_handle_t *

Closing Lists
+++++++++++++

.. c:function:: xo_ssize_t xo_close_list (const char *name)

  :param name: Name of the list
  :type name: const char *
  :returns: -1 on error, or the number of bytes generated
  :rtype: xo_ssize_t
		
  The `xo_close_list` function closes a list of instances.

.. c:function:: xo_ssize_t xo_close_list_h (xo_handle_t *xop, const char *name)

  :param xop: Handle to use (or NULL for default handle)
  :type xop: xo_handle_t *

   The `xo_close_container_h` function adds a `handle` parameter.

Opening Instances
+++++++++++++++++

.. c:function:: xo_ssize_t xo_open_instance (const char *name)

  :param name: Name of the instance (same as the list name)
  :type name: const char *
  :returns: -1 on error, or the number of bytes generated
  :rtype: xo_ssize_t
		
  The `xo_open_instance` function open a single instance.

.. c:function:: xo_ssize_t xo_open_instance_h (xo_handle_t *xop, const char *name)

  :param xop: Handle to use (or NULL for default handle)
  :type xop: xo_handle_t *

   The `xo_open_instance_h` function adds a `handle` parameter.

Closing Instances
+++++++++++++++++

.. c:function:: xo_ssize_t xo_close_instance (const char *name)

  :param name: Name of the instance
  :type name: const char *
  :returns: -1 on error, or the number of bytes generated
  :rtype: xo_ssize_t

  The `xo_close_instance` function closes an open instance.

.. c:function:: xo_ssize_t xo_close_instance_h (xo_handle_t *xop, const char *name)

  :param xop: Handle to use (or NULL for default handle)
  :type xop: xo_handle_t *

  The `xo_close_instance_h` function adds a `handle` parameter.

  ::

    EXAMPLE:
        xo_open_list("user");
        for (i = 0; i < num_users; i++) {
            xo_open_instance("user");
            xo_emit("{k:name}:{:uid/%u}:{:gid/%u}:{:home}\n",
                    pw[i].pw_name, pw[i].pw_uid,
                    pw[i].pw_gid, pw[i].pw_dir);
            xo_close_instance("user");
        }
        xo_close_list("user");
    TEXT:
        phil:1001:1001:/home/phil
        pallavi:1002:1002:/home/pallavi
    XML:
        <user>
            <name>phil</name>
            <uid>1001</uid>
            <gid>1001</gid>
            <home>/home/phil</home>
        </user>
        <user>
            <name>pallavi</name>
            <uid>1002</uid>
            <gid>1002</gid>
            <home>/home/pallavi</home>
        </user>
    JSON:
        user: [
            {
                "name": "phil",
                "uid": 1001,
                "gid": 1001,
                "home": "/home/phil",
            },
            {
                "name": "pallavi",
                "uid": 1002,
                "gid": 1002,
                "home": "/home/pallavi",
            }
        ]

Markers
~~~~~~~

Markers are used to protect and restore the state of open hierarchy
constructs (containers, lists, or instances).  While a marker is open,
no other open constructs can be closed.  When a marker is closed, all
constructs open since the marker was opened will be closed.

Markers use names which are not user-visible, allowing the caller to
choose appropriate internal names.

In this example, the code whiffles through a list of fish, calling a
function to emit details about each fish.  The marker "fish-guts" is
used to ensure that any constructs opened by the function are closed
properly::

  EXAMPLE:
      for (i = 0; fish[i]; i++) {
          xo_open_instance("fish");
          xo_open_marker("fish-guts");
          dump_fish_details(i);
          xo_close_marker("fish-guts");
      }

.. c:function:: xo_ssize_t xo_open_marker(const char *name)

  :param name: Name of the instance
  :type name: const char *
  :returns: -1 on error, or the number of bytes generated
  :rtype: xo_ssize_t

  The `xo_open_marker` function records the current state of open tags
  in order for `xo_close_marker` to close them at some later point.

.. c:function:: xo_ssize_t xo_open_marker_h(const char *name)

  :param xop: Handle to use (or NULL for default handle)
  :type xop: xo_handle_t *

  The `xo_open_marker_h` function adds a `handle` parameter.

.. c:function:: xo_ssize_t xo_close_marker(const char *name)

  :param name: Name of the instance
  :type name: const char *
  :returns: -1 on error, or the number of bytes generated
  :rtype: xo_ssize_t

  The `xo_close_marker` function closes any open containers, lists, or
  instances as needed to return to the state recorded when
  `xo_open_marker` was called with the matching name.

.. c:function:: xo_ssize_t xo_close_marker(const char *name)

  :param xop: Handle to use (or NULL for default handle)
  :type xop: xo_handle_t *

  The `xo_close_marker_h` function adds a `handle` parameter.

DTRT Mode
~~~~~~~~~

Some users may find tracking the names of open containers, lists, and
instances inconvenient.  libxo offers a "Do The Right Thing" mode, where
libxo will track the names of open containers, lists, and instances so
the close function can be called without a name.  To enable DTRT mode,
turn on the XOF_DTRT flag prior to making any other libxo output::

    xo_set_flags(NULL, XOF_DTRT);

.. index:: XOF_DTRT

Each open and close function has a version with the suffix "_d", which
will close the open container, list, or instance::

    xo_open_container_d("top");
    ...
    xo_close_container_d();

This also works for lists and instances::

    xo_open_list_d("item");
    for (...) {
        xo_open_instance_d("item");
        xo_emit(...);
        xo_close_instance_d();
    }
    xo_close_list_d();

.. index:: XOF_WARN

Note that the XOF_WARN flag will also cause libxo to track open
containers, lists, and instances.  A warning is generated when the
name given to the close function and the name recorded do not match.

Support Functions
-----------------

.. index:: xo_parse_args
.. _xo_parse_args:

Parsing Command-line Arguments (xo_parse_args)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. c:function:: int xo_parse_args (int argc, char **argv)

  :param int argc: Number of arguments
  :param argv: Array of argument strings
  :return: -1 on error, or the number of remaining arguments
  :rtype: int

  The `xo_parse_args` function is used to process a program's
  arguments.  libxo-specific options are processed and removed from
  the argument list so the calling application does not need to
  process them.  If successful, a new value for argc is returned.  On
  failure, a message is emitted and -1 is returned::

    argc = xo_parse_args(argc, argv);
    if (argc < 0)
        exit(EXIT_FAILURE);

  Following the call to xo_parse_args, the application can process the
  remaining arguments in a normal manner.  See :ref:`options` for a
  description of valid arguments.

.. index:: xo_set_program

xo_set_program
~~~~~~~~~~~~~~

.. c:function:: void xo_set_program (const char *name)

  :param name: Name to use as the program name
  :type name: const char *
  :returns: void

  The `xo_set_program` function sets the name of the program as
  reported by functions like `xo_failure`, `xo_warn`, `xo_err`, etc.
  The program name is initialized by `xo_parse_args`, but subsequent
  calls to `xo_set_program` can override this value::

    EXAMPLE:
        xo_set_program(argv[0]);

  Note that the value is not copied, so the memory passed to
  `xo_set_program` (and `xo_parse_args`) must be maintained by the
  caller.

.. index:: xo_set_version

xo_set_version
~~~~~~~~~~~~~~

.. c:function:: void xo_set_version (const char *version)

  :param name: Value to use as the version string
  :type name: const char *
  :returns: void

  The `xo_set_version` function records a version number to be emitted
  as part of the data for encoding styles (XML and JSON).  This
  version number is suitable for tracking changes in the content,
  allowing a user of the data to discern which version of the data
  model is in use.

.. c:function:: void xo_set_version_h (xo_handle_t *xop, const char *version)

  :param xop: Handle to use (or NULL for default handle)
  :type xop: xo_handle_t *

  The `xo_set_version` function adds a `handle` parameter.

.. index:: --libxo
.. index:: XOF_INFO
.. index:: xo_info_t

.. _field-information:

Field Information (xo_info_t)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

HTML data can include additional information in attributes that
begin with "data-".  To enable this, three things must occur:

First the application must build an array of xo_info_t structures,
one per tag.  The array must be sorted by name, since libxo uses a
binary search to find the entry that matches names from format
instructions.

Second, the application must inform libxo about this information using
the `xo_set_info` call::

    typedef struct xo_info_s {
        const char *xi_name;    /* Name of the element */
        const char *xi_type;    /* Type of field */
        const char *xi_help;    /* Description of field */
    } xo_info_t;

    void xo_set_info (xo_handle_t *xop, xo_info_t *infop, int count);

Like other libxo calls, passing `NULL` for the handle tells libxo to
use the default handle.

If the count is -1, libxo will count the elements of infop, but there
must be an empty element at the end.  More typically, the number is
known to the application::

    xo_info_t info[] = {
        { "in-stock", "number", "Number of items in stock" },
        { "name", "string", "Name of the item" },
        { "on-order", "number", "Number of items on order" },
        { "sku", "string", "Stock Keeping Unit" },
        { "sold", "number", "Number of items sold" },
    };
    int info_count = (sizeof(info) / sizeof(info[0]));
    ...
    xo_set_info(NULL, info, info_count);

Third, the emission of info must be triggered with the `XOF_INFO` flag
using either the `xo_set_flags` function or the "`--libxo=info`"
command line argument.

The type and help values, if present, are emitted as the "data-type"
and "data-help" attributes::

  <div class="data" data-tag="sku" data-type="string"
       data-help="Stock Keeping Unit">GRO-000-533</div>

.. c:function:: void xo_set_info (xo_handle_t *xop, xo_info_t *infop, int count)

  :param xop: Handle to use (or NULL for default handle)
  :type xop: xo_handle_t *
  :param infop: Array of information structures
  :type infop: xo_info_t *
  :returns: void

.. index:: xo_set_allocator
.. index:: xo_realloc_func_t
.. index:: xo_free_func_t

Memory Allocation
~~~~~~~~~~~~~~~~~

The `xo_set_allocator` function allows libxo to be used in
environments where the standard :manpage:`realloc(3)` and
:manpage:`free(3)` functions are not appropriate.

.. c:function:: void xo_set_allocator (xo_realloc_func_t realloc_func, xo_free_func_t free_func)

  :param xo_realloc_func_t realloc_func:  Allocation function
  :param xo_free_func_t free_func: Free function

  *realloc_func* should expect the same arguments as
  :manpage:`realloc(3)` and return a pointer to memory following the
  same convention.  *free_func* will receive the same argument as
  :manpage:`free(3)` and should release it, as appropriate for the
  environment.

By default, the standard :manpage:`realloc(3)` and :manpage:`free(3)`
functions are used.

.. index:: --libxo

.. _libxo-options:

LIBXO_OPTIONS
~~~~~~~~~~~~~

The environment variable "LIBXO_OPTIONS" can be set to a subset of
libxo options, including:

- color
- flush
- flush-line
- no-color
- no-humanize
- no-locale
- no-retain
- pretty
- retain
- underscores
- warn

For example, warnings can be enabled by::

    % env LIBXO_OPTIONS=warn my-app

Since environment variables are inherited, child processes will have
the same options, which may be undesirable, making the use of the
"`--libxo`" command-line option preferable in most situations.

.. index:: xo_warn
.. index:: xo_err
.. index:: xo_errx
.. index:: xo_message

Errors, Warnings, and Messages
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Many programs make use of the standard library functions
:manpage:`err(3)` and :manpage:`warn(3)` to generate errors and
warnings for the user.  libxo wants to pass that information via the
current output style, and provides compatible functions to allow
this::

    void xo_warn (const char *fmt, ...);
    void xo_warnx (const char *fmt, ...);
    void xo_warn_c (int code, const char *fmt, ...);
    void xo_warn_hc (xo_handle_t *xop, int code,
                     const char *fmt, ...);
    void xo_err (int eval, const char *fmt, ...);
    void xo_errc (int eval, int code, const char *fmt, ...);
    void xo_errx (int eval, const char *fmt, ...);

::

    void xo_message (const char *fmt, ...);
    void xo_message_c (int code, const char *fmt, ...);
    void xo_message_hc (xo_handle_t *xop, int code,
                        const char *fmt, ...);
    void xo_message_hcv (xo_handle_t *xop, int code,
                         const char *fmt, va_list vap);

These functions display the program name, a colon, a formatted message
based on the arguments, and then optionally a colon and an error
message associated with either *errno* or the *code* parameter::

    EXAMPLE:
        if (open(filename, O_RDONLY) < 0)
            xo_err(1, "cannot open file '%s'", filename);

.. index:: xo_error

xo_error
~~~~~~~~

.. c:function:: void xo_error (const char *fmt, ...)

  :param fmt: Format string
  :type fmt: const char *
  :returns: void

  The `xo_error` function can be used for generic errors that should
  be reported over the handle, rather than to stderr.  The `xo_error`
  function behaves like `xo_err` for TEXT and HTML output styles, but
  puts the error into XML or JSON elements::

    EXAMPLE::
        xo_error("Does not %s", "compute");
    XML::
        <error><message>Does not compute</message></error>
    JSON::
        "error": { "message": "Does not compute" }

.. index:: xo_no_setlocale
.. index:: Locale

xo_no_setlocale
~~~~~~~~~~~~~~~

.. c:function:: void xo_no_setlocale (void)

  libxo automatically initializes the locale based on setting of the
  environment variables LC_CTYPE, LANG, and LC_ALL.  The first of this
  list of variables is used and if none of the variables, the locale
  defaults to "UTF-8".  The caller may wish to avoid this behavior,
  and can do so by calling the `xo_no_setlocale` function.

Emitting syslog Messages
------------------------

syslog is the system logging facility used throughout the unix world.
Messages are sent from commands, applications, and daemons to a
hierarchy of servers, where they are filtered, saved, and forwarded
based on configuration behaviors.

syslog is an older protocol, originally documented only in source
code.  By the time :RFC:`3164` published, variation and mutation left the
leading "<pri>" string as only common content.  :RFC:`5424` defines a new
version (version 1) of syslog and introduces structured data into the
messages.  Structured data is a set of name/value pairs transmitted
distinctly alongside the traditional text message, allowing filtering
on precise values instead of regular expressions.

These name/value pairs are scoped by a two-part identifier; an
enterprise identifier names the party responsible for the message
catalog and a name identifying that message.  `Enterprise IDs`_ are
defined by IANA, the Internet Assigned Numbers Authority.

.. _Enterprise IDs:
    https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers

Use the `xo_set_syslog_enterprise_id` function to set the Enterprise
ID, as needed.

The message name should follow the conventions in
:ref:`good-field-names`\ , as should the fields within the message::

    /* Both of these calls are optional */
    xo_set_syslog_enterprise_id(32473);
    xo_open_log("my-program", 0, LOG_DAEMON);

    /* Generate a syslog message */
    xo_syslog(LOG_ERR, "upload-failed",
              "error <%d> uploading file '{:filename}' "
              "as '{:target/%s:%s}'",
              code, filename, protocol, remote);

    xo_syslog(LOG_INFO, "poofd-invalid-state",
              "state {:current/%u} is invalid {:connection/%u}",
	      state, conn);

The developer should be aware that the message name may be used in the
future to allow access to further information, including
documentation.  Care should be taken to choose quality, descriptive
names.

.. _syslog-details:

Priority, Facility, and Flags
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The `xo_syslog`, `xo_vsyslog`, and `xo_open_log` functions
accept a set of flags which provide the priority of the message, the
source facility, and some additional features.  These values are OR'd
together to create a single integer argument::

    xo_syslog(LOG_ERR | LOG_AUTH, "login-failed",
             "Login failed; user '{:user}' from host '{:address}'",
             user, addr);

These values are defined in <syslog.h>.

The priority value indicates the importance and potential impact of
each message:

============= =======================================================
 Priority      Description
============= =======================================================
 LOG_EMERG     A panic condition, normally broadcast to all users
 LOG_ALERT     A condition that should be corrected immediately
 LOG_CRIT      Critical conditions
 LOG_ERR       Generic errors
 LOG_WARNING   Warning messages
 LOG_NOTICE    Non-error conditions that might need special handling
 LOG_INFO      Informational messages
 LOG_DEBUG     Developer-oriented messages
============= =======================================================

The facility value indicates the source of message, in fairly generic
terms:

=============== =======================================================
 Facility        Description
=============== =======================================================
 LOG_AUTH        The authorization system (e.g. :manpage:`login(1)`)
 LOG_AUTHPRIV    As LOG_AUTH, but logged to a privileged file
 LOG_CRON        The cron daemon: :manpage:`cron(8)`
 LOG_DAEMON      System daemons, not otherwise explicitly listed
 LOG_FTP         The file transfer protocol daemons
 LOG_KERN        Messages generated by the kernel
 LOG_LPR         The line printer spooling system
 LOG_MAIL        The mail system
 LOG_NEWS        The network news system
 LOG_SECURITY    Security subsystems, such as :manpage:`ipfw(4)`
 LOG_SYSLOG      Messages generated internally by :manpage:`syslogd(8)`
 LOG_USER        Messages generated by user processes (default)
 LOG_UUCP        The uucp system
 LOG_LOCAL0..7   Reserved for local use
=============== =======================================================

In addition to the values listed above, xo_open_log accepts a set of
addition flags requesting specific logging behaviors:

============ ====================================================
 Flag         Description
============ ====================================================
 LOG_CONS     If syslogd fails, attempt to write to /dev/console
 LOG_NDELAY   Open the connection to :manpage:`syslogd(8)` immediately
 LOG_PERROR   Write the message also to standard error output
 LOG_PID      Log the process id with each message
============ ====================================================

.. index:: xo_syslog

xo_syslog
~~~~~~~~~

.. c:function:: void xo_syslog (int pri, const char *name, const char *fmt, ...)

  :param int pri: syslog priority
  :param name: Name of the syslog event
  :type name: const char *
  :param fmt: Format string, followed by arguments
  :type fmt: const char *
  :returns: void

  Use the `xo_syslog` function to generate syslog messages by calling
  it with a log priority and facility, a message name, a format
  string, and a set of arguments.  The priority/facility argument are
  discussed above, as is the message name.

  The format string follows the same conventions as `xo_emit`'s format
  string, with each field being rendered as an SD-PARAM pair::

    xo_syslog(LOG_ERR, "poofd-missing-file",
              "'{:filename}' not found: {:error/%m}", filename);

    ... [poofd-missing-file@32473 filename="/etc/poofd.conf"
          error="Permission denied"] '/etc/poofd.conf' not
          found: Permission denied

Support functions
~~~~~~~~~~~~~~~~~

.. index:: xo_vsyslog

xo_vsyslog
++++++++++

.. c:function:: void xo_vsyslog (int pri, const char *name, const char *fmt, va_list vap)

  :param int pri: syslog priority
  :param name: Name of the syslog event
  :type name: const char *
  :param fmt: Format string
  :type fmt: const char *
  :param va_list vap: Variadic argument list
  :returns: void

  xo_vsyslog is identical in function to xo_syslog, but takes the set of
  arguments using a va_list::

    EXAMPLE:
        void
        my_log (const char *name, const char *fmt, ...)
        {
            va_list vap;
            va_start(vap, fmt);
            xo_vsyslog(LOG_ERR, name, fmt, vap);
            va_end(vap);
        }

.. index:: xo_open_log

xo_open_log
+++++++++++

.. c:function:: void xo_open_log (const char *ident, int logopt, int facility)

  :param indent:
  :type indent: const char *
  :param int logopt: Bit field containing logging options
  :param int facility:
  :returns: void

  xo_open_log functions similar to :manpage:`openlog(3)`, allowing
  customization of the program name, the log facility number, and the
  additional option flags described in :ref:`syslog-details`.

.. index:: xo_close_log

xo_close_log
++++++++++++

.. c:function:: void xo_close_log (void)

  The `xo_close_log` function is similar to :manpage:`closelog(3)`,
  closing the log file and releasing any associated resources.

.. index:: xo_set_logmask

xo_set_logmask
++++++++++++++

.. c:function:: int xo_set_logmask (int maskpri)

  :param int maskpri: the log priority mask
  :returns: The previous log priority mask

  The `xo_set_logmask` function is similar to :manpage:`setlogmask(3)`,
  restricting the set of generated log event to those whose associated
  bit is set in maskpri.  Use `LOG_MASK(pri)` to find the appropriate bit,
  or `LOG_UPTO(toppri)` to create a mask for all priorities up to and
  including toppri::

    EXAMPLE:
        setlogmask(LOG_UPTO(LOG_WARN));

.. index:: xo_set_syslog_enterprise_id

xo_set_syslog_enterprise_id
+++++++++++++++++++++++++++

.. c:function:: void xo_set_syslog_enterprise_id (unsigned short eid)

  Use the `xo_set_syslog_enterprise_id` to supply a platform- or
  application-specific enterprise id.  This value is used in any future
  syslog messages.

  Ideally, the operating system should supply a default value via the
  "kern.syslog.enterprise_id" sysctl value.  Lacking that, the
  application should provide a suitable value.

Enterprise IDs are administered by IANA, the Internet Assigned Number
Authority.  The complete list is EIDs on their web site::

    https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers

New EIDs can be requested from IANA using the following page::

    http://pen.iana.org/pen/PenApplication.page

Each software development organization that defines a set of syslog
messages should register their own EID and use that value in their
software to ensure that messages can be uniquely identified by the
combination of EID + message name.

Creating Custom Encoders
------------------------

The number of encoding schemes in current use is staggering, with new
and distinct schemes appearing daily.  While libxo provide XML, JSON,
HMTL, and text natively, there are requirements for other encodings.

Rather than bake support for all possible encoders into libxo, the API
allows them to be defined externally.  libxo can then interfaces with
these encoding modules using a simplistic API.  libxo processes all
functions calls, handles state transitions, performs all formatting,
and then passes the results as operations to a customized encoding
function, which implements specific encoding logic as required.  This
means your encoder doesn't need to detect errors with unbalanced
open/close operations but can rely on libxo to pass correct data.

By making a simple API, libxo internals are not exposed, insulating the
encoder and the library from future or internal changes.

The three elements of the API are:

- loading
- initialization
- operations

The following sections provide details about these topics.

.. index:: CBOR

libxo source contains an encoder for Concise Binary Object
Representation, aka CBOR (:RFC:`7049`), which can be used as an
example for the API for other encoders.

Loading Encoders
~~~~~~~~~~~~~~~~

Encoders can be registered statically or discovered dynamically.
Applications can choose to call the `xo_encoder_register` function
to explicitly register encoders, but more typically they are built as
shared libraries, placed in the libxo/extensions directory, and loaded
based on name.  libxo looks for a file with the name of the encoder
and an extension of ".enc".  This can be a file or a symlink to the
shared library file that supports the encoder::

    % ls -1 lib/libxo/extensions/*.enc
    lib/libxo/extensions/cbor.enc
    lib/libxo/extensions/test.enc

Encoder Initialization
~~~~~~~~~~~~~~~~~~~~~~

Each encoder must export a symbol used to access the library, which
must have the following signature::

    int xo_encoder_library_init (XO_ENCODER_INIT_ARGS);

`XO_ENCODER_INIT_ARGS` is a macro defined in "xo_encoder.h" that defines
an argument called "arg", a pointer of the type
`xo_encoder_init_args_t`.  This structure contains two fields:

- `xei_version` is the version number of the API as implemented
  within libxo.  This version is currently as 1 using
  `XO_ENCODER_VERSION`.  This number can be checked to ensure
  compatibility.  The working assumption is that all versions should
  be backward compatible, but each side may need to accurately know
  the version supported by the other side.  `xo_encoder_library_init`
  can optionally check this value, and must then set it to the version
  number used by the encoder, allowing libxo to detect version
  differences and react accordingly.  For example, if version 2 adds
  new operations, then libxo will know that an encoding library that
  set `xei_version` to 1 cannot be expected to handle those new
  operations.

- xei_handler must be set to a pointer to a function of type
  `xo_encoder_func_t`, as defined in "xo_encoder.h".  This function
  takes a set of parameters:
  - xop is a pointer to the opaque `xo_handle_t` structure
  - op is an integer representing the current operation
  - name is a string whose meaning differs by operation
  - value is a string whose meaning differs by operation
  - private is an opaque structure provided by the encoder

Additional arguments may be added in the future, so handler functions
should use the `XO_ENCODER_HANDLER_ARGS` macro.  An appropriate
"extern" declaration is provided to help catch errors.

Once the encoder initialization function has completed processing, it
should return zero to indicate that no error has occurred.  A non-zero
return code will cause the handle initialization to fail.

Operations
~~~~~~~~~~

The encoder API defines a set of operations representing the
processing model of libxo.  Content is formatted within libxo, and
callbacks are made to the encoder's handler function when data is
ready to be processed:

======================= =======================================
 Operation               Meaning  (Base function)
======================= =======================================
 XO_OP_CREATE            Called when the handle is created
 XO_OP_OPEN_CONTAINER    Container opened (xo_open_container)
 XO_OP_CLOSE_CONTAINER   Container closed (xo_close_container)
 XO_OP_OPEN_LIST         List opened (xo_open_list)
 XO_OP_CLOSE_LIST        List closed (xo_close_list)
 XO_OP_OPEN_LEAF_LIST    Leaf list opened (xo_open_leaf_list)
 XO_OP_CLOSE_LEAF_LIST   Leaf list closed (xo_close_leaf_list)
 XO_OP_OPEN_INSTANCE     Instance opened (xo_open_instance)
 XO_OP_CLOSE_INSTANCE    Instance closed (xo_close_instance)
 XO_OP_STRING            Field with Quoted UTF-8 string
 XO_OP_CONTENT           Field with content
 XO_OP_FINISH            Finish any pending output
 XO_OP_FLUSH             Flush any buffered output
 XO_OP_DESTROY           Clean up resources
 XO_OP_ATTRIBUTE         An attribute name/value pair
 XO_OP_VERSION           A version string
======================= =======================================

For all the open and close operations, the name parameter holds the
name of the construct.  For string, content, and attribute operations,
the name parameter is the name of the field and the value parameter is
the value.  "string" are differentiated from "content" to allow differing
treatment of true, false, null, and numbers from real strings, though
content values are formatted as strings before the handler is called.
For version operations, the value parameter contains the version.

All strings are encoded in UTF-8.