Replace runic XSLT with a python script and tidy cbordump code

Filters records on having value < 256, or an RFC, previously hacked
into the XSLT to produce the last update, with a bit of hand-editing.
Using a python script makes it easier to control the formatting and
other details; for example, severl entries previously had descriptions
that mentioned their RFC, with specific section, to which the XSLT was
adding a redundant mention of the RFC. It is also possible to exploit
C++ string juxtaposition to get tidily-presented string literals,
without having to resort to raw strings.

Task-number: QTBUG-111228
Change-Id: Ibd1c93dc1c88689e78b2b13a6bcb59a003f4df0f
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Edward Welbourne 2023-03-28 15:09:37 +02:00
parent 4fcb348154
commit 55fe3ee5e7
3 changed files with 276 additions and 201 deletions

View File

@ -0,0 +1,188 @@
#!/bin/env python3
# Copyright (C) 2023 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
"""Digest cbor-tags.xml file into code for insertion into main.cpp
See main.cpp's comment on how to regenerate its GENERATED CODE.
See ./cbortag.py --help for further details on how to invoke.
You can import this is a module without invoking the script.
"""
def firstChild(parent, tag):
"""Return parent's first child element with the given tag."""
return next(node for node in parent.childNodes
if node.nodeType == parent.ELEMENT_NODE and node.nodeName == tag)
def nodeAttrIs(node, attr, seek):
"""Checks whether the node has a given value for an attribute
Takes the node to check, the name of the attribute and the value
to check against. Returns true if the node does have that value
for the named attribute."""
if node.nodeType != node.ELEMENT_NODE:
return False
if node.attributes is None or attr not in node.attributes:
return False
return node.attributes[attr].value == seek
def getRfcValue(node):
"""Extract RFC reference from an <xref type="rfc" ...> element
Some of these have a reference including section details as the
body of the element, otherwise the data attribute should identify
the RFC. If neither is found, an empty string is returned."""
if node.childNodes:
return node.childNodes[0].nodeValue # Maybe accumulate several children ?
if node.attributes is None or 'data' not in node.attributes:
return ''
return node.attributes['data'].value
def readRegistry(filename):
"""Handles the XML parsing and returns the relevant parts.
Single argument is the path to the cbor-tags.xml file; returns a
twople of the title element's text and an interator over the
record nodes. Checks some things are as expected while doing so."""
from xml.dom.minidom import parse
doc = parse(filename).documentElement
assert nodeAttrIs(doc, 'id', 'cbor-tags')
title = firstChild(doc, 'title').childNodes[0].nodeValue
registry = firstChild(doc, 'registry')
assert nodeAttrIs(registry, 'id', 'tags')
records = (node for node in registry.childNodes if node.nodeName == 'record')
return title, records
def digest(record):
"""Digest a single record from cbor-tags.xml
If the record is not of interest, returns the twople (None, None).
For records of interest, returns (n, t) where n is the numeric tag
code of the record and t is a text describing it. If the record,
or its semantics field, has an xref child with type="rfc", the RFC
mentioned there is included with the text of the semantics; such a
record is of interest, provided it has a semantics field and no
dash in its value. Records with a value field containing a dash
(indicating a range) are not of interest. Records with a value of
256 or above are only of interest if they include an RFC."""
data = {}
for kid in record.childNodes:
if kid.nodeName == 'xref':
if not nodeAttrIs(kid, 'type', 'rfc'):
continue
rfc = getRfcValue(kid)
if rfc:
# Potentially stomping one taken from semantics
data['rfc'] = rfc
elif kid.nodeName == 'semantics':
text = rfc = ''
for part in kid.childNodes:
if part.nodeType == kid.TEXT_NODE:
text += part.nodeValue
elif part.nodeType == kid.ELEMENT_NODE:
if part.nodeName != 'xref' or not nodeAttrIs(part, 'type', 'rfc'):
continue # potentially append content to text
assert not rfc, ('Duplicate RFC ?', rfc, part)
rfc = getRfcValue(part)
if rfc:
if text.endswith('()'):
text = text[:-2].rstrip()
if 'rfc' not in data:
data['rfc'] = rfc
data['semantics'] = ' '.join(text.split())
elif kid.nodeName == 'value':
data['value'] = kid.childNodes[0].nodeValue
text = data.get('semantics')
if not text or 'value' not in data or '-' in data['value']:
return None, None
value = int(data['value'])
if 'rfc' in data:
rfc = data["rfc"].replace('rfc', 'RFC')
text = f'{text} [{rfc}]'
elif value >= 256:
return None, None
return value, text
def entries(records):
"""Digest each record of interest into a value and text.
The value and text form the raw material of the tagDescriptions
array in main.cpp; see digest for which records are retained."""
for record in records:
value, text = digest(record)
if value is not None:
yield value, text
def marginBound(text, prior, left, right):
"""Split up a string literal for tidy display.
The first parameter, text, is the content of the string literal;
quotes shall be added. It may be split into several fragments,
each quoted, so as to abide by line length constraints.
The remaining parameters are integers: prior is the text already
present on the line before text is to be added; left is the width
of the left margin for all subsequent lines; and right is the
right margin to stay within, where possible. The returned string
is either a space with the whole quoted text following, to fit on
the line already started to length prior, or a sequence of quoted
strings, each preceded by a newline and indent of width left."""
if prior + 3 + len(text) < right: # 1 for space, 2 for quotes
return f' "{text}"'
width = right - left - 2 # 2 for the quotes
words = iter(text.split(' '))
lines, current = [''], [next(words)]
for word in words:
if len(word) + sum(len(w) + 1 for w in current) > width:
line = ' '.join(current)
lines.append(f'"{line}"')
current = ['', word]
else:
current.append(word)
line = ' '.join(current)
lines.append(f'"{line}"')
return ('\n' + ' ' * left).join(lines)
def main(argv, speak):
"""Takes care of driving the process.
Takes the command-line argument list (whose first entry is the
name of this script) and standard output (or compatible stream of
your choosing) to which to write data. If the --out option is
specified in the arguments, the file it names is used in place of
this output stream."""
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
parser = ArgumentParser(
description='Digest cbor-tags.xml into code to insert in main.cpp',
formatter_class=ArgumentDefaultsHelpFormatter)
parser.add_argument('path', help='path of the cbor-tags.xml file',
default='cbor-tags.xml')
parser.add_argument('--out', help='file to write instead of standard output')
args = parser.parse_args(argv[1:])
emit = (open(args.out) if args.out else speak).write
title, records = readRegistry(args.path)
emit(f"""\
struct CborTagDescription
{{
QCborTag tag;
const char *description; // with space and parentheses
}};
// {title}
static const CborTagDescription tagDescriptions[] = {{
// from https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml
""")
for value, text in sorted(entries(records)):
prior = f' {{ QCborTag({value}),'
body = marginBound(f' ({text})', len(prior), 6, 96)
emit(f"{prior}{body} }},\n")
emit("""\
{ QCborTag(-1), nullptr }
};
""")
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv, sys.stdout))

View File

@ -17,18 +17,12 @@
/*
* To regenerate:
* curl -O https://www.iana.org/assignments/cbor-tags/cbor-tags.xml
* xsltproc tag-transform.xslt cbor-tags.xml
* ./cbortag.py cbor-tags.xml
*
* The XHTML URL mentioned in the comment below is a human-readable version of
* the same resource.
*/
/* TODO (if possible): fix XSLT to replace each newline and surrounding space in
a semantics entry with a single space, instead of using a raw string to wrap
each, propagating the spacing from the XML to the output of cbordump. Also
auto-purge dangling spaces from the ends of generated lines.
*/
// GENERATED CODE
struct CborTagDescription
{
@ -36,180 +30,101 @@ struct CborTagDescription
const char *description; // with space and parentheses
};
// CBOR Tags
// Concise Binary Object Representation (CBOR) Tags
static const CborTagDescription tagDescriptions[] = {
// from https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml
{ QCborTag(0),
R"r( (Standard date/time string; see Section 3.4.1 [RFC8949]))r" },
{ QCborTag(1),
R"r( (Epoch-based date/time; see Section 3.4.2 [RFC8949]))r" },
{ QCborTag(2),
R"r( (Positive bignum; see Section 3.4.3 [RFC8949]))r" },
{ QCborTag(3),
R"r( (Negative bignum; see Section 3.4.3 [RFC8949]))r" },
{ QCborTag(4),
R"r( (Decimal fraction; see Section 3.4.4 [RFC8949]))r" },
{ QCborTag(5),
R"r( (Bigfloat; see Section 3.4.4 [RFC8949]))r" },
{ QCborTag(16),
R"r( (COSE Single Recipient Encrypted Data Object [RFC9052]))r" },
{ QCborTag(17),
R"r( (COSE Mac w/o Recipients Object [RFC9052]))r" },
{ QCborTag(18),
R"r( (COSE Single Signer Data Object [RFC9052]))r" },
{ QCborTag(19),
R"r( (COSE standalone V2 countersignature [RFC9338]))r" },
{ QCborTag(0), " (Standard date/time string; see Section 3.4.1 [RFC8949])" },
{ QCborTag(1), " (Epoch-based date/time; see Section 3.4.2 [RFC8949])" },
{ QCborTag(2), " (Positive bignum; see Section 3.4.3 [RFC8949])" },
{ QCborTag(3), " (Negative bignum; see Section 3.4.3 [RFC8949])" },
{ QCborTag(4), " (Decimal fraction; see Section 3.4.4 [RFC8949])" },
{ QCborTag(5), " (Bigfloat; see Section 3.4.4 [RFC8949])" },
{ QCborTag(16), " (COSE Single Recipient Encrypted Data Object [RFC9052])" },
{ QCborTag(17), " (COSE Mac w/o Recipients Object [RFC9052])" },
{ QCborTag(18), " (COSE Single Signer Data Object [RFC9052])" },
{ QCborTag(19), " (COSE standalone V2 countersignature [RFC9338])" },
{ QCborTag(21),
R"r( (Expected conversion to base64url encoding; see Section 3.4.5.2 [RFC8949]))r" },
{ QCborTag(22),
R"r( (Expected conversion to base64 encoding; see Section 3.4.5.2 [RFC8949]))r" },
{ QCborTag(23),
R"r( (Expected conversion to base16 encoding; see Section 3.4.5.2 [RFC8949]))r" },
{ QCborTag(24),
R"r( (Encoded CBOR data item; see Section 3.4.5.1 [RFC8949]))r" },
{ QCborTag(25),
R"r( (reference the nth previously seen string))r" },
{ QCborTag(26),
R"r( (Serialised Perl object with classname and constructor arguments))r" },
" (Expected conversion to base64url encoding; see Section 3.4.5.2 [RFC8949])" },
{ QCborTag(22), " (Expected conversion to base64 encoding; see Section 3.4.5.2 [RFC8949])" },
{ QCborTag(23), " (Expected conversion to base16 encoding; see Section 3.4.5.2 [RFC8949])" },
{ QCborTag(24), " (Encoded CBOR data item; see Section 3.4.5.1 [RFC8949])" },
{ QCborTag(25), " (reference the nth previously seen string)" },
{ QCborTag(26), " (Serialised Perl object with classname and constructor arguments)" },
{ QCborTag(27),
R"r( (Serialised language-independent object with type name and constructor arguments))r" },
{ QCborTag(28),
R"r( (mark value as (potentially) shared))r" },
{ QCborTag(29),
R"r( (reference nth marked value))r" },
{ QCborTag(30),
R"r( (Rational number))r" },
{ QCborTag(31),
R"r( (Absent value in a CBOR Array))r" },
{ QCborTag(32),
R"r( (URI; see Section 3.4.5.3 [RFC8949]))r" },
{ QCborTag(33),
R"r( (base64url; see Section 3.4.5.3 [RFC8949]))r" },
{ QCborTag(34),
R"r( (base64; see Section 3.4.5.3 [RFC8949]))r" },
{ QCborTag(35),
R"r( (Regular expression; see Section 2.4.4.3 [RFC7049]))r" },
{ QCborTag(36),
R"r( (MIME message; see Section 3.4.5.3 [RFC8949]))r" },
{ QCborTag(37),
R"r( (Binary UUID (RFC4122, Section 4.1.2)))r" },
{ QCborTag(38),
R"r( (Language-tagged string [RFC9290]))r" },
{ QCborTag(39),
R"r( (Identifier))r" },
{ QCborTag(40),
R"r( (Multi-dimensional Array, row-major order [RFC8746]))r" },
{ QCborTag(41),
R"r( (Homogeneous Array [RFC8746]))r" },
{ QCborTag(42),
R"r( (IPLD content identifier))r" },
{ QCborTag(43),
R"r( (YANG bits datatype; see Section 6.7. [RFC9254]))r" },
{ QCborTag(44),
R"r( (YANG enumeration datatype; see Section 6.6. [RFC9254]))r" },
{ QCborTag(45),
R"r( (YANG identityref datatype; see Section 6.10. [RFC9254]))r" },
{ QCborTag(46),
R"r( (YANG instance-identifier datatype; see Section 6.13. [RFC9254]))r" },
{ QCborTag(47),
R"r( (YANG Schema Item iDentifier (sid); see Section 3.2. [RFC9254]))r" },
{ QCborTag(52),
R"r( (IPv4, [prefixlen,IPv4], [IPv4,prefixpart] [RFC9164]))r" },
{ QCborTag(54),
R"r( (IPv6, [prefixlen,IPv6], [IPv6,prefixpart] [RFC9164]))r" },
{ QCborTag(61),
R"r( (CBOR Web Token (CWT) [RFC8392]))r" },
{ QCborTag(63),
R"r( (Encoded CBOR Sequence ))r" },
{ QCborTag(64),
R"r( (uint8 Typed Array [RFC8746]))r" },
{ QCborTag(65),
R"r( (uint16, big endian, Typed Array [RFC8746]))r" },
{ QCborTag(66),
R"r( (uint32, big endian, Typed Array [RFC8746]))r" },
{ QCborTag(67),
R"r( (uint64, big endian, Typed Array [RFC8746]))r" },
{ QCborTag(68),
R"r( (uint8 Typed Array, clamped arithmetic [RFC8746]))r" },
{ QCborTag(69),
R"r( (uint16, little endian, Typed Array [RFC8746]))r" },
{ QCborTag(70),
R"r( (uint32, little endian, Typed Array [RFC8746]))r" },
{ QCborTag(71),
R"r( (uint64, little endian, Typed Array [RFC8746]))r" },
{ QCborTag(72),
R"r( (sint8 Typed Array [RFC8746]))r" },
{ QCborTag(73),
R"r( (sint16, big endian, Typed Array [RFC8746]))r" },
{ QCborTag(74),
R"r( (sint32, big endian, Typed Array [RFC8746]))r" },
{ QCborTag(75),
R"r( (sint64, big endian, Typed Array [RFC8746]))r" },
{ QCborTag(76),
R"r( ((reserved) [RFC8746]))r" },
{ QCborTag(77),
R"r( (sint16, little endian, Typed Array [RFC8746]))r" },
{ QCborTag(78),
R"r( (sint32, little endian, Typed Array [RFC8746]))r" },
{ QCborTag(79),
R"r( (sint64, little endian, Typed Array [RFC8746]))r" },
{ QCborTag(80),
R"r( (IEEE 754 binary16, big endian, Typed Array [RFC8746]))r" },
{ QCborTag(81),
R"r( (IEEE 754 binary32, big endian, Typed Array [RFC8746]))r" },
{ QCborTag(82),
R"r( (IEEE 754 binary64, big endian, Typed Array [RFC8746]))r" },
{ QCborTag(83),
R"r( (IEEE 754 binary128, big endian, Typed Array [RFC8746]))r" },
{ QCborTag(84),
R"r( (IEEE 754 binary16, little endian, Typed Array [RFC8746]))r" },
{ QCborTag(85),
R"r( (IEEE 754 binary32, little endian, Typed Array [RFC8746]))r" },
{ QCborTag(86),
R"r( (IEEE 754 binary64, little endian, Typed Array [RFC8746]))r" },
{ QCborTag(87),
R"r( (IEEE 754 binary128, little endian, Typed Array [RFC8746]))r" },
{ QCborTag(96),
R"r( (COSE Encrypted Data Object [RFC9052]))r" },
{ QCborTag(97),
R"r( (COSE MACed Data Object [RFC9052]))r" },
{ QCborTag(98),
R"r( (COSE Signed Data Object [RFC9052]))r" },
{ QCborTag(100),
R"r( (Number of days since the epoch date 1970-01-01 [RFC8943]))r" },
{ QCborTag(101),
R"r( (alternatives as given by the uint + 128; see Section 9.1))r" },
{ QCborTag(103),
R"r( (Geographic Coordinates))r" },
{ QCborTag(104),
R"r( (Geographic Coordinate Reference System WKT or EPSG number))r" },
{ QCborTag(110),
R"r( (relative object identifier (BER encoding); SDNV sequence [RFC9090]))r" },
{ QCborTag(111),
R"r( (object identifier (BER encoding) [RFC9090]))r" },
{ QCborTag(112),
R"r( (object identifier (BER encoding), relative to 1.3.6.1.4.1 [RFC9090]))r" },
{ QCborTag(120),
R"r( (Internet of Things Data Point))r" },
" (Serialised language-independent object with type name and constructor arguments)" },
{ QCborTag(28), " (mark value as (potentially) shared)" },
{ QCborTag(29), " (reference nth marked value)" },
{ QCborTag(30), " (Rational number)" },
{ QCborTag(31), " (Absent value in a CBOR Array)" },
{ QCborTag(32), " (URI; see Section 3.4.5.3 [RFC8949])" },
{ QCborTag(33), " (base64url; see Section 3.4.5.3 [RFC8949])" },
{ QCborTag(34), " (base64; see Section 3.4.5.3 [RFC8949])" },
{ QCborTag(35), " (Regular expression; see Section 2.4.4.3 [RFC7049])" },
{ QCborTag(36), " (MIME message; see Section 3.4.5.3 [RFC8949])" },
{ QCborTag(37), " (Binary UUID [RFC4122, Section 4.1.2])" },
{ QCborTag(38), " (Language-tagged string [RFC9290, Appendix A])" },
{ QCborTag(39), " (Identifier)" },
{ QCborTag(40), " (Multi-dimensional Array, row-major order [RFC8746])" },
{ QCborTag(41), " (Homogeneous Array [RFC8746])" },
{ QCborTag(42), " (IPLD content identifier)" },
{ QCborTag(43), " (YANG bits datatype; see Section 6.7. [RFC9254])" },
{ QCborTag(44), " (YANG enumeration datatype; see Section 6.6. [RFC9254])" },
{ QCborTag(45), " (YANG identityref datatype; see Section 6.10. [RFC9254])" },
{ QCborTag(46), " (YANG instance-identifier datatype; see Section 6.13. [RFC9254])" },
{ QCborTag(47), " (YANG Schema Item iDentifier (sid); see Section 3.2. [RFC9254])" },
{ QCborTag(52), " (IPv4, [prefixlen,IPv4], [IPv4,prefixpart] [RFC9164])" },
{ QCborTag(54), " (IPv6, [prefixlen,IPv6], [IPv6,prefixpart] [RFC9164])" },
{ QCborTag(61), " (CBOR Web Token (CWT) [RFC8392])" },
{ QCborTag(63), " (Encoded CBOR Sequence [RFC8742])" },
{ QCborTag(64), " (uint8 Typed Array [RFC8746])" },
{ QCborTag(65), " (uint16, big endian, Typed Array [RFC8746])" },
{ QCborTag(66), " (uint32, big endian, Typed Array [RFC8746])" },
{ QCborTag(67), " (uint64, big endian, Typed Array [RFC8746])" },
{ QCborTag(68), " (uint8 Typed Array, clamped arithmetic [RFC8746])" },
{ QCborTag(69), " (uint16, little endian, Typed Array [RFC8746])" },
{ QCborTag(70), " (uint32, little endian, Typed Array [RFC8746])" },
{ QCborTag(71), " (uint64, little endian, Typed Array [RFC8746])" },
{ QCborTag(72), " (sint8 Typed Array [RFC8746])" },
{ QCborTag(73), " (sint16, big endian, Typed Array [RFC8746])" },
{ QCborTag(74), " (sint32, big endian, Typed Array [RFC8746])" },
{ QCborTag(75), " (sint64, big endian, Typed Array [RFC8746])" },
{ QCborTag(76), " ((reserved) [RFC8746])" },
{ QCborTag(77), " (sint16, little endian, Typed Array [RFC8746])" },
{ QCborTag(78), " (sint32, little endian, Typed Array [RFC8746])" },
{ QCborTag(79), " (sint64, little endian, Typed Array [RFC8746])" },
{ QCborTag(80), " (IEEE 754 binary16, big endian, Typed Array [RFC8746])" },
{ QCborTag(81), " (IEEE 754 binary32, big endian, Typed Array [RFC8746])" },
{ QCborTag(82), " (IEEE 754 binary64, big endian, Typed Array [RFC8746])" },
{ QCborTag(83), " (IEEE 754 binary128, big endian, Typed Array [RFC8746])" },
{ QCborTag(84), " (IEEE 754 binary16, little endian, Typed Array [RFC8746])" },
{ QCborTag(85), " (IEEE 754 binary32, little endian, Typed Array [RFC8746])" },
{ QCborTag(86), " (IEEE 754 binary64, little endian, Typed Array [RFC8746])" },
{ QCborTag(87), " (IEEE 754 binary128, little endian, Typed Array [RFC8746])" },
{ QCborTag(96), " (COSE Encrypted Data Object [RFC9052])" },
{ QCborTag(97), " (COSE MACed Data Object [RFC9052])" },
{ QCborTag(98), " (COSE Signed Data Object [RFC9052])" },
{ QCborTag(100), " (Number of days since the epoch date 1970-01-01 [RFC8943])" },
{ QCborTag(101), " (alternatives as given by the uint + 128; see Section 9.1)" },
{ QCborTag(103), " (Geographic Coordinates)" },
{ QCborTag(104), " (Geographic Coordinate Reference System WKT or EPSG number)" },
{ QCborTag(110), " (relative object identifier (BER encoding); SDNV sequence [RFC9090])" },
{ QCborTag(111), " (object identifier (BER encoding) [RFC9090])" },
{ QCborTag(112), " (object identifier (BER encoding), relative to 1.3.6.1.4.1 [RFC9090])" },
{ QCborTag(120), " (Internet of Things Data Point)" },
{ QCborTag(260),
R"r( (Network Address (IPv4 or IPv6 or MAC Address) (DEPRECATED in favor of 52 and 54
for IP addresses) [http://www.employees.oRg/~RaviR/CboR-netwoRk.txt]))r" },
" (Network Address (IPv4 or IPv6 or MAC Address) (DEPRECATED in favor of 52 and 54 for IP"
" addresses) [RFC9164])" },
{ QCborTag(261),
R"r( (Network Address Prefix (IPv4 or IPv6 Address + Mask Length) (DEPRECATED in favor of 52 and 54
for IP addresses) [https://github.Com/toRaviR/CBOR-Tag-SpeCs/blob/masteR/netwoRkPReFix.md]))r" },
" (Network Address Prefix (IPv4 or IPv6 Address + Mask Length) (DEPRECATED in favor of 52"
" and 54 for IP addresses) [RFC9164])" },
{ QCborTag(271),
R"r( (DDoS Open Threat Signaling (DOTS) signal channel object,
as defined in [RFC9132]))r" },
{ QCborTag(1004),
R"r( ( full-date string [RFC8943]))r" },
{ QCborTag(1040),
R"r( (Multi-dimensional Array, column-major order [RFC8746]))r" },
{ QCborTag(55799),
R"r( (Self-described CBOR; see Section 3.4.6 [RFC8949]))r" },
{ QCborTag(55800),
R"r( (indicates that the file contains CBOR Sequences [RFC9277]))r" },
" (DDoS Open Threat Signaling (DOTS) signal channel object, as defined in [RFC9132])" },
{ QCborTag(1004), " (full-date string [RFC8943])" },
{ QCborTag(1040), " (Multi-dimensional Array, column-major order [RFC8746])" },
{ QCborTag(55799), " (Self-described CBOR; see Section 3.4.6 [RFC8949])" },
{ QCborTag(55800), " (indicates that the file contains CBOR Sequences [RFC9277])" },
{ QCborTag(55801),
R"r( (indicates that the file starts with a CBOR-Labeled Non-CBOR Data label. [RFC9277]))r" },
" (indicates that the file starts with a CBOR-Labeled Non-CBOR Data label. [RFC9277])" },
{ QCborTag(-1), nullptr }
};
// END GENERATED CODE

View File

@ -1,28 +0,0 @@
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:a="http://www.iana.org/assignments" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="no" method="text"/>
<xsl:template match="/a:registry[@id='cbor-tags']">struct CborTagDescription
{
QCborTag tag;
const char *description; // with space and parentheses
};
// <xsl:value-of select="a:registry/a:title"/>
static const CborTagDescription tagDescriptions[] = {
// from https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml
<xsl:for-each select="a:registry/a:record">
<xsl:sort select="a:value" data-type="number"/>
<xsl:if test="a:semantics != ''">
<xsl:call-template name="row"/>
</xsl:if>
</xsl:for-each> { QCborTag(-1), nullptr }
};
</xsl:template>
<xsl:template name="row"> { QCborTag(<xsl:value-of select="a:value"/>),
R"r( (<xsl:value-of select="a:semantics"/> <xsl:call-template name="xref"/>))r" },
</xsl:template><!-- fn:replace(a:semantics, '\s+', ' ') -->
<xsl:template name="xref"><xsl:if test="a:xref/@type = 'rfc'"> [<xsl:value-of
select="translate(a:xref/@data,'rfc','RFC')"/>]</xsl:if>
</xsl:template>
</xsl:stylesheet>