Deleted Added
full compact
libxo.txt (287111) libxo.txt (298083)
1#
2# Copyright (c) 2014, Juniper Networks, Inc.
3# All rights reserved.
4# This SOFTWARE is licensed under the LICENSE provided in the
5# ../Copyright file. By downloading, installing, copying, or
6# using the SOFTWARE, you agree to be bound by the terms of that
7# LICENSE.
8# Phil Shafer, July 2014

--- 685 unchanged lines hidden (view full) ---

694Widths over 8k are considered probable errors and not supported. If
695XOF_WARN is set, a warning will be generated.
696
697*** Field Modifiers
698
699Field modifiers are flags which modify the way content emitted for
700particular output styles:
701
1#
2# Copyright (c) 2014, Juniper Networks, Inc.
3# All rights reserved.
4# This SOFTWARE is licensed under the LICENSE provided in the
5# ../Copyright file. By downloading, installing, copying, or
6# using the SOFTWARE, you agree to be bound by the terms of that
7# LICENSE.
8# Phil Shafer, July 2014

--- 685 unchanged lines hidden (view full) ---

694Widths over 8k are considered probable errors and not supported. If
695XOF_WARN is set, a warning will be generated.
696
697*** Field Modifiers
698
699Field modifiers are flags which modify the way content emitted for
700particular output styles:
701
702|---+---------------+-------------------------------------------------|
703| M | Name | Description |
704|---+---------------+-------------------------------------------------|
705| c | colon | A colon (":") is appended after the label |
706| d | display | Only emit field for display styles (text/HTML) |
707| e | encoding | Only emit for encoding styles (XML/JSON) |
708| g | gettext | Call gettext on field's render content |
709| h | humanize (hn) | Format large numbers in human-readable style |
710| | hn-space | Humanize: Place space between numeric and unit |
711| | hn-decimal | Humanize: Add a decimal digit, if number < 10 |
712| | hn-1000 | Humanize: Use 1000 as divisor instead of 1024 |
713| k | key | Field is a key, suitable for XPath predicates |
714| l | leaf-list | Field is a leaf-list |
715| n | no-quotes | Do not quote the field when using JSON style |
716| p | plural | Gettext: Use comma-separated plural form |
717| q | quotes | Quote the field when using JSON style |
718| t | trim | Trim leading and trailing whitespace |
719| w | white | A blank (" ") is appended after the label |
720|---+---------------+-------------------------------------------------|
702|---+---------------+--------------------------------------------------|
703| M | Name | Description |
704|---+---------------+--------------------------------------------------|
705| a | argument | The content appears as a 'const char *' argument |
706| c | colon | A colon (":") is appended after the label |
707| d | display | Only emit field for display styles (text/HTML) |
708| e | encoding | Only emit for encoding styles (XML/JSON) |
709| g | gettext | Call gettext on field's render content |
710| h | humanize (hn) | Format large numbers in human-readable style |
711| | hn-space | Humanize: Place space between numeric and unit |
712| | hn-decimal | Humanize: Add a decimal digit, if number < 10 |
713| | hn-1000 | Humanize: Use 1000 as divisor instead of 1024 |
714| k | key | Field is a key, suitable for XPath predicates |
715| l | leaf-list | Field is a leaf-list |
716| n | no-quotes | Do not quote the field when using JSON style |
717| p | plural | Gettext: Use comma-separated plural form |
718| q | quotes | Quote the field when using JSON style |
719| t | trim | Trim leading and trailing whitespace |
720| w | white | A blank (" ") is appended after the label |
721|---+---------------+--------------------------------------------------|
721
722Roles and modifiers can also use more verbose names, when preceeded by
723a comma. For example, the modifier string "Lwc" (or "L,white,colon")
724means the field has a label role (text that describes the next field)
725and should be followed by a colon ('c') and a space ('w'). The
726modifier string "Vkq" (or ":key,quote") means the field has a value
727role (the default role), that it is a key for the current instance,
728and that the value should be quoted when encoded for JSON.
729
722
723Roles and modifiers can also use more verbose names, when preceeded by
724a comma. For example, the modifier string "Lwc" (or "L,white,colon")
725means the field has a label role (text that describes the next field)
726and should be followed by a colon ('c') and a space ('w'). The
727modifier string "Vkq" (or ":key,quote") means the field has a value
728role (the default role), that it is a key for the current instance,
729and that the value should be quoted when encoded for JSON.
730
731**** The Argument Modifier ({a:})
732
733The argument modifier indicates that the content of the field
734descriptor will be placed as a UTF-8 string (const char *) argument
735within the xo_emit parameters.
736
737 EXAMPLE:
738 xo_emit("{La:} {a:}\n", "Label text", "label", "value");
739 TEXT:
740 Label text value
741 JSON:
742 "label": "value"
743 XML:
744 <label>value</label>
745
746The argument modifier allows field names for value fields to be passed
747on the stack, avoiding the need to build a field descriptor using
748snprintf. For many field roles, the argument modifier is not needed,
749since those roles have specific mechanisms for arguments, such as
750"{C:fg-%s}".
751
730**** The Colon Modifier ({c:})
731
732The colon modifier appends a single colon to the data value:
733
734 EXAMPLE:
735 xo_emit("{Lc:Name}{:name}\n", "phil");
736 TEXT:
737 Name:phil

--- 164 unchanged lines hidden (view full) ---

902xo_emit applies a simple heuristic to determine whether quotes are
903needed, but often this needs to be controlled by the caller.
904
905 EXAMPLE:
906 xo_emit("{q:time/%d}", 2014);
907 JSON:
908 "year": "2014"
909
752**** The Colon Modifier ({c:})
753
754The colon modifier appends a single colon to the data value:
755
756 EXAMPLE:
757 xo_emit("{Lc:Name}{:name}\n", "phil");
758 TEXT:
759 Name:phil

--- 164 unchanged lines hidden (view full) ---

924xo_emit applies a simple heuristic to determine whether quotes are
925needed, but often this needs to be controlled by the caller.
926
927 EXAMPLE:
928 xo_emit("{q:time/%d}", 2014);
929 JSON:
930 "year": "2014"
931
932The heuristic is based on the format; if the format uses any of the
933following conversion specifiers, then no quotes are used:
934
935 d i o u x X D O U e E f F g G a A c C p
936
937**** The Trim Modifier ({t:})
938
939The trim modifier removes any leading or trailing whitespace from
940the value.
941
942 EXAMPLE:
943 xo_emit("{t:description}", " some input ");
944 JSON:
945 "description": "some input"
946
910**** The White Space Modifier ({w:})
911
912The white space modifier appends a single space to the data value:
913
914 EXAMPLE:
915 xo_emit("{Lw:Name}{:name}\n", "phil");
916 TEXT:
917 Name phil

--- 106 unchanged lines hidden (view full) ---

1024ASCII data, a normal 7-bit ASCII string can be used. '%ls' expects a
1025'wchar_t *' pointer to a wide-character string, encoded as a 32-bit
1026Unicode values. '%hs' expects a 'char *' pointer to a multi-byte
1027string encoded with the current locale, as given by the LC_CTYPE,
1028LANG, or LC_ALL environment varibles. The first of this list of
1029variables is used and if none of the variables are set, the locale
1030defaults to "UTF-8".
1031
947**** The White Space Modifier ({w:})
948
949The white space modifier appends a single space to the data value:
950
951 EXAMPLE:
952 xo_emit("{Lw:Name}{:name}\n", "phil");
953 TEXT:
954 Name phil

--- 106 unchanged lines hidden (view full) ---

1061ASCII data, a normal 7-bit ASCII string can be used. '%ls' expects a
1062'wchar_t *' pointer to a wide-character string, encoded as a 32-bit
1063Unicode values. '%hs' expects a 'char *' pointer to a multi-byte
1064string encoded with the current locale, as given by the LC_CTYPE,
1065LANG, or LC_ALL environment varibles. The first of this list of
1066variables is used and if none of the variables are set, the locale
1067defaults to "UTF-8".
1068
1069libxo will convert these arguments as needed to either UTF-8 (for XML,
1070JSON, and HTML styles) or locale-based strings for display in text
1071style.
1072
1073 xo_emit("Alll strings are utf-8 content {:tag/%ls}",
1074 L"except for wide strings");
1075
1076"%S" is equivalent to "%ls".
1077
1078|--------+-----------------+-------------------------------|
1079| Format | Argument Type | Argument Contents |
1080|--------+-----------------+-------------------------------|
1081| %s | const char * | UTF-8 string |
1082| %S | const char * | UTF-8 string (alias for '%s') |
1083| %ls | const wchar_t * | Wide character UNICODE string |
1084| %hs | const char * | locale-based string |
1085|--------+-----------------+-------------------------------|
1086
1032For example, a function is passed a locale-base name, a hat size,
1033and a time value. The hat size is formatted in a UTF-8 (ASCII)
1034string, and the time value is formatted into a wchar_t string.
1035
1036 void print_order (const char *name, int size,
1037 struct tm *timep) {
1038 char buf[32];
1039 const char *size_val = "unknown";

--- 118 unchanged lines hidden (view full) ---

1158| xo_emit_warn_c | xo_emit_warn_cp |
1159| xo_emit_warn | xo_emit_warn_p |
1160| xo_emit_warnx_ | xo_emit_warnx_p |
1161| xo_emit_err | xo_emit_err_p |
1162| xo_emit_errx | xo_emit_errx_p |
1163| xo_emit_errc | xo_emit_errc_p |
1164|------------------+------------------------|
1165
1087For example, a function is passed a locale-base name, a hat size,
1088and a time value. The hat size is formatted in a UTF-8 (ASCII)
1089string, and the time value is formatted into a wchar_t string.
1090
1091 void print_order (const char *name, int size,
1092 struct tm *timep) {
1093 char buf[32];
1094 const char *size_val = "unknown";

--- 118 unchanged lines hidden (view full) ---

1213| xo_emit_warn_c | xo_emit_warn_cp |
1214| xo_emit_warn | xo_emit_warn_p |
1215| xo_emit_warnx_ | xo_emit_warnx_p |
1216| xo_emit_err | xo_emit_err_p |
1217| xo_emit_errx | xo_emit_errx_p |
1218| xo_emit_errc | xo_emit_errc_p |
1219|------------------+------------------------|
1220
1221*** Retaining Parsed Format Information @retain@
1222
1223libxo can retain the parsed internal information related to the given
1224format string, allowing subsequent xo_emit calls, the retained
1225information is used, avoiding repetitive parsing of the format string.
1226
1227 SYNTAX:
1228 int xo_emit_f(xo_emit_flags_t flags, const char fmt, ...);
1229 EXAMPLE:
1230 xo_emit_f(XOEF_RETAIN, "{:some/%02d}{:thing/%-6s}{:fancy}\n",
1231 some, thing, fancy);
1232
1233To retain parsed format information, use the XOEF_RETAIN flag to the
1234xo_emit_f() function. A complete set of xo_emit_f functions exist to
1235match all the xo_emit function signatures (with handles, varadic
1236argument, and printf-like flags):
1237
1238|------------------+------------------------|
1239| Function | Flags Equivalent |
1240|------------------+------------------------|
1241| xo_emit_hv | xo_emit_hvf |
1242| xo_emit_h | xo_emit_hf |
1243| xo_emit | xo_emit_f |
1244| xo_emit_hvp | xo_emit_hvfp |
1245| xo_emit_hp | xo_emit_hfp |
1246| xo_emit_p | xo_emit_fp |
1247|------------------+------------------------|
1248
1249The format string must be immutable across multiple calls to xo_emit_f(),
1250since the library retains the string. Typically this is done by using
1251static constant strings, such as string literals. If the string is not
1252immutable, the XOEF_RETAIN flag must not be used.
1253
1254The functions xo_retain_clear() and xo_retain_clear_all() release
1255internal information on either a single format string or all format
1256strings, respectively. Neither is required, but the library will
1257retain this information until it is cleared or the process exits.
1258
1259 const char *fmt = "{:name} {:count/%d}\n";
1260 for (i = 0; i < 1000; i++) {
1261 xo_open_instance("item");
1262 xo_emit_f(XOEF_RETAIN, fmt, name[i], count[i]);
1263 }
1264 xo_retain_clear(fmt);
1265
1266The retained information is kept as thread-specific data.
1267
1166*** Example
1167
1168In this example, the value for the number of items in stock is emitted:
1169
1170 xo_emit("{P: }{Lwc:In stock}{:in-stock/%u}\n",
1171 instock);
1172
1173This call will generate the following output:

--- 17 unchanged lines hidden (view full) ---

1191not include XOF_XPATH or XOF_INFO data, which would expand the
1192penultimate line to:
1193
1194 <div class="data" data-tag="in-stock"
1195 data-xpath="/top/data/item/in-stock"
1196 data-type="number"
1197 data-help="Number of items in stock">144</div>
1198
1268*** Example
1269
1270In this example, the value for the number of items in stock is emitted:
1271
1272 xo_emit("{P: }{Lwc:In stock}{:in-stock/%u}\n",
1273 instock);
1274
1275This call will generate the following output:

--- 17 unchanged lines hidden (view full) ---

1293not include XOF_XPATH or XOF_INFO data, which would expand the
1294penultimate line to:
1295
1296 <div class="data" data-tag="in-stock"
1297 data-xpath="/top/data/item/in-stock"
1298 data-type="number"
1299 data-help="Number of items in stock">144</div>
1300
1199** Command-line Arguments
1200
1201libxo uses command line options to trigger rendering behavior. The
1202following options are recognised:
1203
1204- --libxo <options>
1205- --libxo=<options>
1206- --libxo:<brief-options>
1207
1208Options is a comma-separated list of tokens that correspond to output
1209styles, flags, or features:
1210
1211|-------------+-------------------------------------------------------|
1212| Token | Action |
1213|-------------+-------------------------------------------------------|
1214| color | Enable colors/effects for display styles (TEXT, HTML) |
1215| dtrt | Enable "Do The Right Thing" mode |
1216| html | Emit HTML output |
1217| indent=xx | Set the indentation level |
1218| info | Add info attributes (HTML) |
1219| json | Emit JSON output |
1220| keys | Emit the key attribute for keys (XML) |
1221| log-gettext | Log (via stderr) each gettext(3) string lookup |
1222| log-syslog | Log (via stderr) each syslog message (via xo_syslog) |
1223| no-humanize | Ignore the {h:} modifier (TEXT, HTML) |
1224| no-locale | Do not initialize the locale setting |
1225| no-top | Do not emit a top set of braces (JSON) |
1226| not-first | Pretend the 1st output item was not 1st (JSON) |
1227| pretty | Emit pretty-printed output |
1228| text | Emit TEXT output |
1229| underscores | Replace XML-friendly "-"s with JSON friendly "_"s e |
1230| units | Add the 'units' (XML) or 'data-units (HTML) attribute |
1231| warn | Emit warnings when libxo detects bad calls |
1232| warn-xml | Emit warnings in XML |
1233| xml | Emit XML output |
1234| xpath | Add XPath expressions (HTML) |
1235|-------------+-------------------------------------------------------|
1236
1237The brief options are detailed in ^LIBXO_OPTIONS^.
1238
1239** Representing Hierarchy
1240
1241For XML and JSON, individual fields appear inside hierarchies which
1242provide context and meaning to the fields. Unfortunately, these
1243encoding have a basic disconnect between how lists is similar objects
1244are represented.
1245
1246XML encodes lists as set of sequential elements:

--- 130 unchanged lines hidden (view full) ---

1377
1378 for (i = 0; fish[i]; i++) {
1379 xo_open_instance("fish");
1380 xo_open_marker("fish-guts");
1381 dump_fish_details(i);
1382 xo_close_marker("fish-guts");
1383 }
1384
1301** Representing Hierarchy
1302
1303For XML and JSON, individual fields appear inside hierarchies which
1304provide context and meaning to the fields. Unfortunately, these
1305encoding have a basic disconnect between how lists is similar objects
1306are represented.
1307
1308XML encodes lists as set of sequential elements:

--- 130 unchanged lines hidden (view full) ---

1439
1440 for (i = 0; fish[i]; i++) {
1441 xo_open_instance("fish");
1442 xo_open_marker("fish-guts");
1443 dump_fish_details(i);
1444 xo_close_marker("fish-guts");
1445 }
1446
1385** Handles @handles@
1447** Command-line Arguments
1386
1448
1387libxo uses "handles" to control its rendering functionality. The
1388handle contains state and buffered data, as well as callback functions
1389to process data.
1449libxo uses command line options to trigger rendering behavior. The
1450following options are recognised:
1390
1451
1391A default handle is used when a NULL is passed to functions accepting
1392a handle. This handle is initialized to write its data to stdout
1393using the default style of text (XO_STYLE_TEXT).
1452- --libxo <options>
1453- --libxo=<options>
1454- --libxo:<brief-options>
1394
1455
1395For the convenience of callers, the libxo library includes handle-less
1396functions that implicitly use the default handle. Any function that
1397takes a handle will use the default handle is a value of NULL is
1398passed in place of a valid handle.
1456Programs using libxo are expecting to call the xo_parse_args function
1457to parse these arguments. See ^xo_parse_args^ for details.
1399
1458
1400For example, the following are equivalent:
1459Options is a comma-separated list of tokens that correspond to output
1460styles, flags, or features:
1401
1461
1402 xo_emit("test");
1403 xo_emit_h(NULL, "test");
1462|-------------+-------------------------------------------------------|
1463| Token | Action |
1464|-------------+-------------------------------------------------------|
1465| color | Enable colors/effects for display styles (TEXT, HTML) |
1466| dtrt | Enable "Do The Right Thing" mode |
1467| html | Emit HTML output |
1468| indent=xx | Set the indentation level |
1469| info | Add info attributes (HTML) |
1470| json | Emit JSON output |
1471| keys | Emit the key attribute for keys (XML) |
1472| log-gettext | Log (via stderr) each gettext(3) string lookup |
1473| log-syslog | Log (via stderr) each syslog message (via xo_syslog) |
1474| no-humanize | Ignore the {h:} modifier (TEXT, HTML) |
1475| no-locale | Do not initialize the locale setting |
1476| no-retain | Prevent retaining formatting information |
1477| no-top | Do not emit a top set of braces (JSON) |
1478| not-first | Pretend the 1st output item was not 1st (JSON) |
1479| pretty | Emit pretty-printed output |
1480| retain | Force retaining formatting information |
1481| text | Emit TEXT output |
1482| underscores | Replace XML-friendly "-"s with JSON friendly "_"s e |
1483| units | Add the 'units' (XML) or 'data-units (HTML) attribute |
1484| warn | Emit warnings when libxo detects bad calls |
1485| warn-xml | Emit warnings in XML |
1486| xml | Emit XML output |
1487| xpath | Add XPath expressions (HTML) |
1488|-------------+-------------------------------------------------------|
1404
1489
1405Handles are created using xo_create() and destroy using xo_destroy().
1490The brief options are detailed in ^LIBXO_OPTIONS^.
1406
1491
1407** UTF-8
1408
1409All strings for libxo must be UTF-8. libxo will handle turning them
1410into locale-based strings for display to the user.
1411
1412The only exception is argument formatted using the "%ls" format, which
1413require a wide character string (wchar_t *) as input. libxo will
1414convert these arguments as needed to either UTF-8 (for XML, JSON, and
1415HTML styles) or locale-based strings for display in text style.
1416
1417 xo_emit("Alll strings are utf-8 content {:tag/%ls}",
1418 L"except for wide strings");
1419
1420"%S" is equivalent to "%ls".
1421
1422* The libxo API
1423
1424This section gives details about the functions in libxo, how to call
1425them, and the actions they perform.
1426
1492* The libxo API
1493
1494This section gives details about the functions in libxo, how to call
1495them, and the actions they perform.
1496
1427** Handles
1497** Handles @handles@
1428
1498
1499libxo uses "handles" to control its rendering functionality. The
1500handle contains state and buffered data, as well as callback functions
1501to process data.
1502
1429Handles give an abstraction for libxo that encapsulates the state of a
1430stream of output. Handles have the data type "xo_handle_t" and are
1431opaque to the caller.
1432
1433The library has a default handle that is automatically initialized.
1503Handles give an abstraction for libxo that encapsulates the state of a
1504stream of output. Handles have the data type "xo_handle_t" and are
1505opaque to the caller.
1506
1507The library has a default handle that is automatically initialized.
1434By default, this handle will send text style output to standard output.
1435The xo_set_style and xo_set_flags functions can be used to change this
1436behavior.
1508By default, this handle will send text style output (XO_STYLE_TEXT) to
1509standard output. The xo_set_style and xo_set_flags functions can be
1510used to change this behavior.
1437
1511
1438Many libxo functions take a handle as their first parameter; most that
1439do not use the default handle. Any function taking a handle can
1440be passed NULL to access the default handle.
1441
1442For the typical command that is generating output on standard output,
1443there is no need to create an explicit handle, but they are available
1444when needed, e.g., for daemons that generate multiple streams of
1445output.
1446
1512For the typical command that is generating output on standard output,
1513there is no need to create an explicit handle, but they are available
1514when needed, e.g., for daemons that generate multiple streams of
1515output.
1516
1517Many libxo functions take a handle as their first parameter; most that
1518do not use the default handle. Any function taking a handle can be
1519passed NULL to access the default handle. For the convenience of
1520callers, the libxo library includes handle-less functions that
1521implicitly use the default handle.
1522
1523For example, the following are equivalent:
1524
1525 xo_emit("test");
1526 xo_emit_h(NULL, "test");
1527
1528Handles are created using xo_create() and destroy using xo_destroy().
1529
1447*** xo_create
1448
1449A handle can be allocated using the xo_create() function:
1450
1451 xo_handle_t *xo_create (unsigned style, unsigned flags);
1452
1453 Example:
1454 xo_handle_t *xop = xo_create(XO_STYLE_JSON, XOF_WARN);

--- 193 unchanged lines hidden (view full) ---

1648
1649The remaining arguments to xo_emit() and xo_emit_h() are a set of
1650arguments corresponding to the fields in the format string. Care must
1651be taken to ensure the argument types match the fields in the format
1652string, since an inappropriate cast can ruin your day. The vap
1653argument to xo_emit_hv() points to a variable argument list that can
1654be used to retrieve arguments via va_arg().
1655
1530*** xo_create
1531
1532A handle can be allocated using the xo_create() function:
1533
1534 xo_handle_t *xo_create (unsigned style, unsigned flags);
1535
1536 Example:
1537 xo_handle_t *xop = xo_create(XO_STYLE_JSON, XOF_WARN);

--- 193 unchanged lines hidden (view full) ---

1731
1732The remaining arguments to xo_emit() and xo_emit_h() are a set of
1733arguments corresponding to the fields in the format string. Care must
1734be taken to ensure the argument types match the fields in the format
1735string, since an inappropriate cast can ruin your day. The vap
1736argument to xo_emit_hv() points to a variable argument list that can
1737be used to retrieve arguments via va_arg().
1738
1739*** Single Field Emitting Functions (xo_emit_field) @xo_emit_field@
1740
1741The following functions can also make output, but only make a single
1742field at a time:
1743
1744 int xo_emit_field_hv (xo_handle_t *xop, const char *rolmod,
1745 const char *contents, const char *fmt,
1746 const char *efmt, va_list vap);
1747
1748 int xo_emit_field_h (xo_handle_t *xop, const char *rolmod,
1749 const char *contents, const char *fmt,
1750 const char *efmt, ...);
1751
1752 int xo_emit_field (const char *rolmod, const char *contents,
1753 const char *fmt, const char *efmt, ...);
1754
1755These functions are intended to avoid the scenario where one
1756would otherwise need to compose a format descriptors using
1757snprintf(). The individual parts of the format descriptor are
1758passed in distinctly.
1759
1760 xo_emit("T", "Host name is ", NULL, NULL);
1761 xo_emit("V", "host-name", NULL, NULL, host-name);
1762
1656*** Attributes (xo_attr) @xo_attr@
1657
1658The xo_attr() function emits attributes for the XML output style.
1659
1763*** Attributes (xo_attr) @xo_attr@
1764
1765The xo_attr() function emits attributes for the XML output style.
1766
1660
1661 int xo_attr (const char *name, const char *fmt, ...);
1662 int xo_attr_h (xo_handle_t *xop, const char *name,
1663 const char *fmt, ...);
1664 int xo_attr_hv (xo_handle_t *xop, const char *name,
1665 const char *fmt, va_list vap);
1666
1667The name parameter give the name of the attribute to be encoded. The
1668fmt parameter gives a printf-style format string used to format the

--- 881 unchanged lines hidden (view full) ---

2550** General
2551
2552*** Can you share the history of libxo?
2553
2554In 2001, we added an XML API to the JUNOS operating system, which is
2555built on top of FreeBSD. Eventually this API became standardized as
2556the NETCONF API (RFC 6241). As part of this effort, we modified many
2557FreeBSD utilities to emit XML, typically via a "-X" switch. The
1767 int xo_attr (const char *name, const char *fmt, ...);
1768 int xo_attr_h (xo_handle_t *xop, const char *name,
1769 const char *fmt, ...);
1770 int xo_attr_hv (xo_handle_t *xop, const char *name,
1771 const char *fmt, va_list vap);
1772
1773The name parameter give the name of the attribute to be encoded. The
1774fmt parameter gives a printf-style format string used to format the

--- 881 unchanged lines hidden (view full) ---

2656** General
2657
2658*** Can you share the history of libxo?
2659
2660In 2001, we added an XML API to the JUNOS operating system, which is
2661built on top of FreeBSD. Eventually this API became standardized as
2662the NETCONF API (RFC 6241). As part of this effort, we modified many
2663FreeBSD utilities to emit XML, typically via a "-X" switch. The
2558results were mixed. The cost of maintaining this code, updating it
2664results were mixed. The cost of maintaining this code, updating it,
2559and carrying it were non-trivial, and contributed to our expense (and
2560the associated delay) with upgrading the version of FreeBSD on which
2561each release of JUNOS is based.
2562
2563A recent (2014) effort within JUNOS aims at removing our modifications
2564to the underlying FreeBSD code as a means of reducing the expense and
2665and carrying it were non-trivial, and contributed to our expense (and
2666the associated delay) with upgrading the version of FreeBSD on which
2667each release of JUNOS is based.
2668
2669A recent (2014) effort within JUNOS aims at removing our modifications
2670to the underlying FreeBSD code as a means of reducing the expense and
2565delay. JUNOS is structured to have system components generate XML
2566that is rendered by the CLI (think: login shell) into human-readable
2567text. This allows the API to use the same plumbing as the CLI, and
2568ensures that all components emit XML, and that it is emitted with
2569knowledge of the consumer of that XML, yielding an API that have no
2570incremental cost or feature delay.
2671delay in tracking HEAD. JUNOS is structured to have system components
2672generate XML that is rendered by the CLI (think: login shell) into
2673human-readable text. This allows the API to use the same plumbing as
2674the CLI, and ensures that all components emit XML, and that it is
2675emitted with knowledge of the consumer of that XML, yielding an API
2676that have no incremental cost or feature delay.
2571
2572libxo is an effort to mix the best aspects of the JUNOS strategy into
2573FreeBSD in a seemless way, allowing commands to make printf-like
2677
2678libxo is an effort to mix the best aspects of the JUNOS strategy into
2679FreeBSD in a seemless way, allowing commands to make printf-like
2574output calls without needing to care how the output is rendered.
2680output calls with a single code path.
2575
2576*** Did the complex semantics of format strings evolve over time?
2577
2578The history is both long and short: libxo's functionality is based
2579on what JUNOS does in a data modeling language called ODL (output
2580definition language). In JUNOS, all subcomponents generate XML,
2581which is feed to the CLI, where data from the ODL files tell is
2582how to render that XML into text. ODL might had a set of tags

--- 1175 unchanged lines hidden ---
2681
2682*** Did the complex semantics of format strings evolve over time?
2683
2684The history is both long and short: libxo's functionality is based
2685on what JUNOS does in a data modeling language called ODL (output
2686definition language). In JUNOS, all subcomponents generate XML,
2687which is feed to the CLI, where data from the ODL files tell is
2688how to render that XML into text. ODL might had a set of tags

--- 1175 unchanged lines hidden ---