1zcbor 2===== 3 4zcbor is a low footprint [CBOR](https://en.wikipedia.org/wiki/CBOR) library in the C language (C++ compatible), tailored for use in microcontrollers. 5It comes with a schema-driven script tool that can validate your data, or even generate code. 6The schema language (CDDL) allows creating very advanced and detailed schemas. 7 8The validation and conversion part of the tool works with YAML and JSON data, in addition to CBOR. 9It can for example validate a YAML file against a schema and convert it into CBOR. 10 11The code generation part of the tool generates C code based on the given schema. 12The generated code performs CBOR encoding and decoding using the C library, while also validating the data against all the rules in the schema. 13 14The schema language used by zcbor is CDDL (Consise Data Definition Language) which is a powerful human-readable data description language defined in [IETF RFC 8610](https://datatracker.ietf.org/doc/rfc8610/). 15 16 17Features 18======== 19 20Here are some possible ways zcbor can be used: 21 22 - C code: 23 - As a low-footprint CBOR decoding/encoding library similar to TinyCBOR/QCBOR/NanoCBOR. The library can be used independently of the Python script. ([More information](#cbor-decodingencoding-library)) 24 - To generate C code (using the Python script) for validating and decoding or encoding CBOR, for use in optimized or constrained environments, such as microcontrollers. ([More information](#code-generation)) 25 - Python script and module ([More information](#python-script-and-module)): 26 - Validate a YAML/JSON file and translate it into CBOR e.g. for transmission. 27 - Validate a YAML/JSON/CBOR file before processing it with some other tool 28 - Decode and validate incoming CBOR data into human-readable YAML/JSON. 29 - As part of a python script that processes YAML/JSON/CBOR files. 30 - Uses the same internal representation used by the PyYAML/json/cbor2 libraries. 31 - Do validation against a CDDL schema. 32 - Create a read-only representation via named tuples (with names taken from the CDDL schema). 33 34 35Getting started 36=============== 37 38There are samples in the [samples](samples) directory that demonstrate different ways to use zcbor, both the script tool and the C code. 39 401. The [hello_world sample](samples/hello_world/README.md) is a minimum examples of encoding and decoding using the C library. 412. The [pet sample](samples/pet/README.md) shows a how to use the C library together with generated code, and how to use the script tool to do code generation and data conversion. 42 43The [tests](tests) also demonstrate how to use zcbor in different ways. The [encoding](tests/encode), [decoding](tests/decode), and [unit](tests/unit) tests run using [Zephyr](https://github.com/zephyrproject-rtos/zephyr) (the samples do not use Zephyr). 44 45Should I use code generation or the library directly? 46----------------------------------------------------- 47 48The benefit of using code generation is greater for decoding than encoding. 49This is because decoding is generally more complex than encoding, since when decoding you have to gracefully handle all possible payloads. 50The code generation will provide a number of checks that are tedious to write manually. 51These checks ensure that the payload is well-formed. 52 53 54CBOR decoding/encoding library 55============================== 56 57The CBOR library can be found in [include/](include) and [src/](src) and can be used directly, by including the files in your project. 58If using zcbor with Zephyr, the library will be available when the [CONFIG_ZCBOR](https://docs.zephyrproject.org/latest/kconfig.html#CONFIG_ZCBOR) config is enabled. 59 60The library is also used by generated code. See the the [Code generation](#code-generation) section for more info about code generation. 61 62The C library is C++ compatible. 63 64The zcbor state object 65---------------------- 66 67To do encoding or decoding with the library, instantiate a `zcbor_state_t` object, which is most easily done using the `ZCBOR_STATE_*()` macros, look below or in the [hello_world](samples/hello_world/src/main.c) sample for example code. 68 69The `elem_count` member refers to the number of encoded objects in the current list or map. 70`elem_count` starts again when entering a nested list or map, and is restored when exiting. 71 72`elem_count` is one reason for needing "backup" states (the other is to allow rollback of the payload). 73Backups are needed for _decoding_ if there are any lists, maps, or CBOR-encoded strings (`zcbor_bstr_*_decode`) in the data. 74Backups are needed for _encoding_ if there are any lists or maps *and* you are using canonical encoding (`ZCBOR_CANONICAL`), or when using the `zcbor_bstr_*_encode` functions. 75 76```c 77/** Initialize a decoding state (could include an array of backup states). 78 * After calling this, decode_state[0] is ready to be used with the decoding APIs. */ 79ZCBOR_STATE_D(decode_state, n, payload, payload_len, elem_count); 80 81/** Initialize an encoding state (could include an array of backup states). 82 * After calling this, encode_state[0] is ready to be used with the encoding APIs. */ 83ZCBOR_STATE_E(encode_state, n, payload, payload_len, 0); 84``` 85 86Configuration 87------------- 88 89The C library has a few compile-time configuration options. 90These configuration options can be enabled by adding them as compile definitions to the build. 91If using zcbor with Zephyr, use the [Kconfig options](https://github.com/zephyrproject-rtos/zephyr/blob/main/modules/zcbor/Kconfig) instead. 92 93Name | Description 94------------------------- | ----------- 95`ZCBOR_CANONICAL` | When encoding lists and maps, do not use indefinite length encoding. Enabling `ZCBOR_CANONICAL` increases code size and makes the encoding library more often use state backups. 96`ZCBOR_VERBOSE` | Print messages on encoding/decoding errors (`zcbor_print()`), and also a trace message (`zcbor_trace()`) for each decoded value, and in each generated function (when using code generation). Requires `printk` as found in Zephyr. 97`ZCBOR_ASSERTS` | Enable asserts (`zcbor_assert()`). When they fail, the assert statements instruct the current function to return a `ZCBOR_ERR_ASSERTION` error. If `ZCBOR_VERBOSE` is enabled, a message is printed. 98`ZCBOR_STOP_ON_ERROR` | Enable the `stop_on_error` functionality. This makes all functions abort their execution if called when an error has already happened. 99`ZCBOR_BIG_ENDIAN` | All decoded values are returned as big-endian. The default is little-endian. 100 101 102Python script and module 103======================== 104 105The zcbor.py script can directly read CBOR, YAML, or JSON data and validate it against a CDDL description. 106It can also freely convert the data between CBOR/YAML/JSON. 107It can also output the data to a C file formatted as a byte array. 108 109Invoking zcbor.py from the command line 110--------------------------------------- 111 112zcbor.py can be installed via [`pip`](https://pypi.org/project/zcbor/), or alternatively invoked directly from its location in this repo. 113 114Following are some generalized examples for validating, and for converting (which also validates) data from the command line. 115The script infers the data format from the file extension, but the format can also be specified explicitly. 116See `zcbor validate --help` and `zcbor convert --help` for more information. 117 118```sh 119zcbor validate -c <CDDL description file> -t <which CDDL type to expect> -i <input data file> 120zcbor convert -c <CDDL description file> -t <which CDDL type to expect> -i <input data file> -o <output data file> 121``` 122 123Or directly from within the repo. 124 125```sh 126python3 <zcbor base>/zcbor/zcbor.py validate -c <CDDL description file> -t <which CDDL type to expect> -i <input data file> 127python3 <zcbor base>/zcbor/zcbor.py convert -c <CDDL description file> -t <which CDDL type to expect> -i <input data file> -o <output data file> 128``` 129 130You can see an example of the conversions in [tests/cases/yaml_compatibility.yaml](tests/cases/yaml_compatibility.yaml) and its CDDL file [tests/cases/yaml_compatibility.cddl](tests/cases/yaml_compatibility.cddl). 131 132Importing zcbor in a Python script 133---------------------------------- 134 135Importing zcbor gives access to the DataTranslator class which is used to implement the command line conversion features. 136DataTranslator can be used to programmatically perform the translations, or to manipulate the data. 137When accessing the data, you can choose between two internal formats: 138 139 1. The format provided by the [cbor2](https://pypi.org/project/cbor2/), [yaml (PyYAML)](https://pypi.org/project/PyYAML/), and [json](https://docs.python.org/3/library/json.html) packages. 140 This is a format where the serialization types (map, list, string, number etc.) are mapped directly to the corresponding Python types. 141 This format is common between these packages, which makes translation very simple. 142 When returning this format, DataTranslator hides the idiomatic representations for bytestrings, tags, and non-text keys described above. 143 2. A custom format which allows accessing the data via the names from the CDDL description file. 144 This format is implemented using named tuples, and is immutable, meaning that it can be used for inspecting data, but not for changing or creating data. 145 146Making CBOR YAML-/JSON-compatible 147--------------------------------- 148 149Since CBOR supports more data types than YAML and JSON, zcbor can optionally use a bespoke format when converting to/from YAML/JSON. 150This is controlled with the `--yaml-compatibility` option to `convert` and `validate`. 151This is relevant when handling YAML/JSON conversions of data that uses the unsupported features. 152The following data types are supported by CBOR, but not by YAML (or JSON which is a subset of YAML): 153 154 1. bytestrings: YAML supports only text strings. In YAML, bytestrings are represented as `{"zcbor_bstr": "<hex-formatted bytestring>"}`, or as `{"zcbor_bstr": <any type>}` if the CBOR bytestring contains CBOR-formatted data, in which the data is decoded into `<any type>`. 155 2. map keys other than text string: In YAML, such key value pairs are represented as `{"zcbor_keyval<unique int>": {"key": <key, not text>, "val": <value>}}`. 156 3. tags: In cbor2, tags are represented by a special type, `cbor2.CBORTag`. In YAML, these are represented as `{"zcbor_tag": <tag number>, "zcbor_tag_val": <tagged data>}`. 157 4. undefined: In cbor2, undefined has its own value `cbor2.types.undefined`. In YAML, undefined is represented as: `["zcbor_undefined"]`. 158 159You can see an example of the conversions in [tests/cases/yaml_compatibility.yaml](tests/cases/yaml_compatibility.yaml) and its CDDL file [tests/cases/yaml_compatibility.cddl](tests/cases/yaml_compatibility.cddl). 160 161 162Code generation 163=============== 164 165Code generation is invoked with the `zcbor code` command: 166 167```sh 168zcbor code <--decode or --encode or both> -c <CDDL description file(s)> -t <which CDDL type(s) to expose in the API> --output-cmake <path to place the generated CMake file at> 169zcbor code <--decode or --encode or both> -c <CDDL description file(s)> -t <which CDDL type(s) to expose in the API> --oc <path to the generated C file> --oh <path to the generated header file> --oht <path to the generated types header> 170``` 171 172When you call this, zcbor reads the CDDL files and creates C struct types to match the types described in the CDDL. 173It then creates code that uses the C library to decode CBOR data into the structs, and/or encode CBOR from the data in the structs. 174Finally, it takes the "entry types" (`-t`) and creates a public API function for each of them. 175While doing these things, it will make a number of optimizations, e.g. inlining code for small types and removing ununsed functions. 176It outputs the generated code into header and source files and optionally creates a CMake file to build them. 177 178The `zcbor code` command reads one or more CDDL file(s) and generates some or all of these files: 179 - A header file with types (always) 180 - A header file with declarations for decoding functions (if `--decode`/`-d` is specified) 181 - A C file with decoding functions (if `--decode`/`-d` is specified) 182 - A header file with declarations for encoding functions (if `--encode`/`-e` is specified) 183 - A C file with encoding functions (if `--encode`/`-e` is specified) 184 - A CMake file that creates a library with the generated code and the C library (if `--output-cmake` is specified). 185 186CDDL allows placing restrictions on the members of your data. 187Restrictions can be on type (int/string/list/bool etc.), on content (e.g. values/sizes of ints or strings), and repetition (e.g. the number of members in a list). 188The generated code will validate the input, which means that it will check all the restriction set in the CDDL description, and fail if a restriction is broken. 189 190There are tests for the code generation in [tests/decode](tests/decode) and [tests/encode](tests/encode). 191The tests require [Zephyr](https://github.com/zephyrproject-rtos/zephyr) (if your system is set up to build Zephyr samples, the tests should also build). 192 193The generated C code is C++ compatible. 194 195Build system 196------------ 197 198When calling zcbor with the argument `--output-cmake <file path>`, a CMake file will be created at that location. 199The generated CMake file creates a target library and adds the generated and non-generated source files as well as required include directories to it. 200This CMake file can then be included in your project's `CMakeLists.txt` file, and the target can be linked into your project. 201This is demonstrated in the tests, e.g. at [tests/decode/test3_simple/CMakeLists.txt](tests/decode/test3_simple/CMakeLists.txt). 202zcbor can be instructed to copy the non-generated sources to the same location as the generated sources with `--copy-sources`. 203 204 205Usage Example 206============= 207 208There are buildable examples in the [samples](samples) directory. 209 210To see how to use the C library directly, see the (hello_world)[samples/hello_world/src/main.c] sample, or the (pet)[samples/pet/src/main.c] sample (look for calls to functions prefixed with `zcbor_`). 211 212To see how to use code generation, see the (pet)[samples/pet/src/main.c] sample. 213 214Look at the (CMakeLists.txt)[samples/pet/CMakeLists.txt] file to see how zcbor is invoked for code generation (and for conversion). 215 216To see how to do conversion, see the (pet)[samples/pet/CMakeLists.txt] sample. 217 218Below are some additional examples of how to invoke zcbor for code generation and for converting/validating 219 220Code generation 221--------------- 222 223```sh 224python3 <zcbor base>/zcbor/zcbor.py code -c pet.cddl -d -t Pet --oc pet_decode.c --oh pet_decode.h 225# or 226zcbor code -c pet.cddl -d -t Pet --oc pet_decode.c --oh pet_decode.h 227``` 228 229Converting 230---------- 231 232Here is an example call for converting from YAML to CBOR: 233 234```sh 235python3 <zcbor base>/zcbor/zcbor.py convert -c pet.cddl -t Pet -i mypet.yaml -o mypet.cbor 236# or 237zcbor convert -c pet.cddl -t Pet -i mypet.yaml -o mypet.cbor 238``` 239 240Which takes a yaml structure from mypet.yaml, validates it against the Pet type in the CDDL description in pet.cddl, and writes binary CBOR data to mypet.cbor. 241 242Validating 243---------- 244 245Here is an example call for validating a JSON file: 246 247```sh 248python3 <zcbor base>/zcbor/zcbor.py validate -c pet.cddl -t Pet --yaml-compatibility -i mypet.json 249# or 250zcbor validate -c pet.cddl -t Pet --yaml-compatibility -i mypet.json 251``` 252 253Which takes the json structure in mypet.json, converts any [yaml-compatible](#making-cbor-yaml-json-compatible) values to their original form, and validates that against the Pet type in the CDDL description in pet.cddl. 254 255 256Running tests 257============= 258 259The tests for the generated code are based on the Zephyr ztest library. 260These tests can be found in [tests/decode](tests/decode) and [tests/encode](tests/encode). 261To set up the environment to run the ztest tests, follow [Zephyr's Getting Started Guide](https://docs.zephyrproject.org/latest/getting_started/index.html), or see the workflow in the [`.github`](.github) directory. 262 263Tests for `convert` and `verify` are implemented with the unittest module. 264These tests can be found in [tests/scripts/test_zcbor.py](tests/scripts/test_zcbor.py). 265In this file there are also tests for code style of all python scripts, using the `pycodestyle` library. 266 267Tests for the docs, samples, etc. can be found in [tests/scripts/test_repo_files.py](tests/scripts/test_repo_files.py). 268 269For running the tests locally, there is [`tests/test.sh`](tests/test.sh) which runs all above tests. 270 271 272Introduction to CDDL 273==================== 274 275In CDDL you define types from other types. 276Types can be defined from base types, or from other types you define. 277Types are declared with '`=`', e.g. `Foo = int` which declares the type `Foo` to be an integer, analogous to `typedef int Foo;` in C. 278CDDL defines the following base types (this is not an exhaustive list): 279 280 - `int`: Positive or negative integer 281 - `uint`: Positive integer 282 - `bstr`: Byte string 283 - `tstr`: Text string 284 - `bool`: Boolean 285 - `nil`: Nil/Null value 286 - `float`: Floating point value 287 - `any`: Any single element 288 289CDDL allows creating aggregate types: 290 291 - `[]`: List. Elements don't need to have the same type. 292 - `{}`: Map. Key/value pairs as are declared as `<key> => <value>` or `<key>: <value>`. Note that `:` is also used for labels. 293 - `()`: Groups. Grouping with no enclosing type, which means that e.g. `Foo = [(int, bstr)]` is equivalent to `Foo = [int, bstr]`. 294 - `/`: Unions. Analogous to unions in C. E.g. `Foo = int/bstr/Bar` where Foo is either an int, a bstr, or Bar (some custom type). 295 296Literals can be used instead of the base type names: 297 298 - Number: `Foo = 3`, where Foo is a uint with the additional requirement that it must have the value 3. 299 - Number range: `Foo = -100..100`, where Foo is an int with value between -100 and 100. 300 - Text string: `Foo = "hello"`, where Foo is a tstr with the requirement that it must be "hello". 301 - True/False: `Foo = false`, where Foo is a bool which is always false. 302 303Base types can also be restricted in other ways: 304 305 - `.size`: Works for integers and strings. E.g. `Foo = uint .size 4` where Foo is a uint exactly 4 bytes long. 306 - `.cbor`/`.cborseq`: E.g. `Foo = bstr .cbor Bar` where Foo is a bstr whose contents must be CBOR data decodeable as the Bar type. 307 308An element can be repeated: 309 310 - `?`: 0 or 1 time. E.g. `Foo = [int, ?bstr]`, where Foo is a list with an int possibly followed by a bstr. 311 - `*`: 0 or more times. E.g. `Foo = [*tstr]`, where Foo is a list containing 0 or more tstrs. 312 - `+`: 1 or more times. E.g. `Foo = [+Bar]`. 313 - `x*y`: Between x and y times, inclusive. E.g. `Foo = {4*8(int => bstr)}` where Foo is a map with 4 to 8 key/value pairs where each key is an int and each value is a bstr. 314 315Note that in the zcbor script and its generated code, the number of entries supported via `*` and `+` is affected by the default_max_qty value. 316 317Any element can be labeled with `:`. 318The label is only for readability and does not impact the data structure in any way. 319E.g. `Foo = [name: tstr, age: uint]` is equivalent to `Foo = [tstr, uint]`. 320 321See [pet.cddl](tests/cases/pet.cddl) for CDDL example code. 322 323 324Introduction to CBOR 325==================== 326 327CBOR's format is described well on [Wikipedia](https://en.wikipedia.org/wiki/CBOR), but here's a synopsis: 328 329Encoded CBOR data elements look like this. 330 331``` 332| Header | Value | Payload | 333| 1 byte | 0, 1, 2, 4, or 8 bytes | 0 - 2^64-1 bytes/elements | 334| 3 bits | 5 bits | 335| Major Type | Additional Info | 336``` 337 338The available major types can be seen in `zcbor_major_type_t`. 339 340For all major types, Values 0-23 are encoded directly in the _Additional info_, meaning that the _Value_ field is 0 bytes long. 341If _Additional info_ is 24, 25, 26, or 27, the _Value_ field is 1, 2, 4, or 8 bytes long, respectively. 342 343Major types `pint` (0), `nint` (1), `tag` (6), and `simple` (7) elements have no payload, only _Value_. 344 345 * `pint`: Interpret the _Value_ as a positive integer. 346 * `nint`: Interpret the _Value_ as a positive integer, then multiply by -1 and subtract 1. 347 * `tag`: The _Value_ says something about the next non-tag element. 348 See the [CBOR tag documentation](https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml) for details. 349 * `simple`: Different _Additional info_ mean different things: 350 * 0-19: Unassigned simple values. 351 * 20: `false` simple value 352 * 21: `true` simple value 353 * 22: `null` simple value 354 * 23: `undefined` simple value 355 * 24: Interpret the _Value_ as a 1 byte simple value. These simple values are currently unassigned. 356 * 25: Interpret the _Value_ as an IEEE 754 float16. 357 * 26: Interpret the _Value_ as an IEEE 754 float32. 358 * 27: Interpret the _Value_ as an IEEE 754 float64. 359 * 31: End of an indefinite-length `list` or `map`. 360 361For `bstr` (2), `tstr` (3), `list` (4), and `map` (5), the _Value_ describes the length of the _Payload_. 362For `bstr` and `tstr`, the length is in bytes, for `list`, the length is in number of elements, and for `map`, the length is in number of key/value element pairs. 363 364For `list` and `map`, sub elements are regular CBOR elements with their own _Header_, _Value_ and _Payload_. `list`s and `map`s can be recursively encoded. 365If a `list` or `map` has _Additional info_ 31, it is "indefinite-length", which means it has an "unknown" number of elements. 366Instead, its end is marked by a `simple` with _Additional info_ 31 (byte value 0xFF). 367 368 369History 370======= 371 372zcbor (then "cddl-gen") was initially conceived as a code generation project. 373It was inspired by the need to securely decode the complex manifest data structures in the [IETF SUIT specification](https://datatracker.ietf.org/doc/draft-ietf-suit-manifest/). 374This is reflected in the fact that there are multiple zcbor tests that use the CDDL and examples from various revisions of that specification. 375Decoding/deserializing data securely requires doing some quite repetitive checks on each data element, to be sure that you are not decoding gibberish. 376This is where code generation could pull a lot of weight. 377Later it was discovered that the CBOR library that was designed to used by generated code could be useful by itself. 378The script was also expanded so it could directly manipulate CBOR data. 379Since CBOR, YAML, and JSON are all represented in roughly the same way internally in Python, it was easy to expand that data manipulation to support YAML and JSON. 380 381Some places where zcbor is currently used: 382- [MCUboot's serial recovery mechanism](https://github.com/mcu-tools/mcuboot/blob/main/boot/boot_serial/src/boot_serial.c) 383- [Zephyr's mcumgr](https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c) 384- [Zephyr's LwM2M SenML](https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c) 385- [nRF Connect SDK's full modem update mechanism](https://github.com/nrfconnect/sdk-nrf/blob/main/subsys/mgmt/fmfu/src/fmfu_mgmt.c) 386- [nRF Connect SDK's nrf_rpc](https://github.com/nrfconnect/sdk-nrfxlib/blob/main/nrf_rpc/nrf_rpc_cbor.c) 387 388 389Command line documentation 390========================== 391 392Added via `add_helptext.py` 393 394zcbor --help 395------------ 396 397``` 398usage: zcbor [-h] [--version] {code,validate,convert} ... 399 400Parse a CDDL file and validate/convert between YAML, JSON, and CBOR. Can also 401generate C code for validation/encoding/decoding of CBOR. 402 403positional arguments: 404 {code,validate,convert} 405 406options: 407 -h, --help show this help message and exit 408 --version show program's version number and exit 409 410``` 411 412zcbor code --help 413----------------- 414 415``` 416usage: zcbor code [-h] -c CDDL [--no-prelude] [-v] 417 [--default-max-qty DEFAULT_MAX_QTY] [--output-c OUTPUT_C] 418 [--output-h OUTPUT_H] [--output-h-types OUTPUT_H_TYPES] 419 [--copy-sources] [--output-cmake OUTPUT_CMAKE] -t 420 ENTRY_TYPES [ENTRY_TYPES ...] [-d] [-e] [--time-header] 421 [--git-sha-header] [-b {32,64}] 422 [--include-prefix INCLUDE_PREFIX] [-s] 423 [--file-header FILE_HEADER] 424 425Parse a CDDL file and produce C code that validates and xcodes CBOR. 426The output from this script is a C file and a header file. The header file 427contains typedefs for all the types specified in the cddl input file, as well 428as declarations to xcode functions for the types designated as entry types when 429running the script. The c file contains all the code for decoding and validating 430the types in the CDDL input file. All types are validated as they are xcoded. 431 432Where a `bstr .cbor <Type>` is specified in the CDDL, AND the Type is an entry 433type, the xcoder will not xcode the string, only provide a pointer into the 434payload buffer. This is useful to reduce the size of typedefs, or to break up 435decoding. Using this mechanism is necessary when the CDDL contains self- 436referencing types, since the C type cannot be self referencing. 437 438This script requires 'regex' for lookaround functionality not present in 're'. 439 440options: 441 -h, --help show this help message and exit 442 -c CDDL, --cddl CDDL Path to one or more input CDDL file(s). Passing 443 multiple files is equivalent to concatenating them. 444 --no-prelude Exclude the standard CDDL prelude from the build. The 445 prelude can be viewed at zcbor/cddl/prelude.cddl in 446 the repo, or together with the script. 447 -v, --verbose Print more information while parsing CDDL and 448 generating code. 449 --default-max-qty DEFAULT_MAX_QTY, --dq DEFAULT_MAX_QTY 450 Default maximum number of repetitions when no maximum 451 is specified. This is needed to construct complete C 452 types. The default_max_qty can usually be set to a 453 text symbol if desired, to allow it to be configurable 454 when building the code. This is not always possible, 455 as sometimes the value is needed for internal 456 computations. If so, the script will raise an 457 exception. 458 --output-c OUTPUT_C, --oc OUTPUT_C 459 Path to output C file. If both --decode and --encode 460 are specified, _decode and _encode will be appended to 461 the filename when creating the two files. If not 462 specified, the path and name will be based on the 463 --output-cmake file. A 'src' directory will be created 464 next to the cmake file, and the C file will be placed 465 there with the same name (except the file extension) 466 as the cmake file. 467 --output-h OUTPUT_H, --oh OUTPUT_H 468 Path to output header file. If both --decode and 469 --encode are specified, _decode and _encode will be 470 appended to the filename when creating the two files. 471 If not specified, the path and name will be based on 472 the --output-cmake file. An 'include' directory will 473 be created next to the cmake file, and the C file will 474 be placed there with the same name (except the file 475 extension) as the cmake file. 476 --output-h-types OUTPUT_H_TYPES, --oht OUTPUT_H_TYPES 477 Path to output header file with typedefs (shared 478 between decode and encode). If not specified, the path 479 and name will be taken from the output header file 480 (--output-h), with '_types' added to the file name. 481 --copy-sources Copy the non-generated source files (zcbor_*.c/h) into 482 the same directories as the generated files. 483 --output-cmake OUTPUT_CMAKE 484 Path to output CMake file. The filename of the CMake 485 file without '.cmake' is used as the name of the CMake 486 target in the file. The CMake file defines a CMake 487 target with the zcbor source files and the generated 488 file as sources, and the zcbor header files' and 489 generated header files' folders as 490 include_directories. Add it to your project via 491 include() in your CMakeLists.txt file, and link the 492 target to your program. This option works with or 493 without the --copy-sources option. 494 -t ENTRY_TYPES [ENTRY_TYPES ...], --entry-types ENTRY_TYPES [ENTRY_TYPES ...] 495 Names of the types which should have their xcode 496 functions exposed. 497 -d, --decode Generate decoding code. Either --decode or --encode or 498 both must be specified. 499 -e, --encode Generate encoding code. Either --decode or --encode or 500 both must be specified. 501 --time-header Put the current time in a comment in the generated 502 files. 503 --git-sha-header Put the current git sha of zcbor in a comment in the 504 generated files. 505 -b {32,64}, --default-bit-size {32,64} 506 Default bit size of integers in code. When integers 507 have no explicit bounds, assume they have this bit 508 width. Should follow the bit width of the architecture 509 the code will be running on. 510 --include-prefix INCLUDE_PREFIX 511 When #include'ing generated files, add this path 512 prefix to the filename. 513 -s, --short-names Attempt to make most generated struct member names 514 shorter. This might make some names identical which 515 will cause a compile error. If so, tweak the CDDL 516 labels or layout, or disable this option. This might 517 also make enum names different from the corresponding 518 union members. 519 --file-header FILE_HEADER 520 Header to be included in the comment at the top of 521 generated C files, e.g. copyright. 522 523``` 524 525zcbor validate --help 526--------------------- 527 528``` 529usage: zcbor validate [-h] -c CDDL [--no-prelude] [-v] -i INPUT 530 [--input-as {yaml,json,cbor,cborhex}] -t ENTRY_TYPE 531 [--default-max-qty DEFAULT_MAX_QTY] 532 [--yaml-compatibility] 533 534Read CBOR, YAML, or JSON data from file or stdin and validate it against a 535CDDL schema file. 536 537options: 538 -h, --help show this help message and exit 539 -c CDDL, --cddl CDDL Path to one or more input CDDL file(s). Passing 540 multiple files is equivalent to concatenating them. 541 --no-prelude Exclude the standard CDDL prelude from the build. The 542 prelude can be viewed at zcbor/cddl/prelude.cddl in 543 the repo, or together with the script. 544 -v, --verbose Print more information while parsing CDDL and 545 generating code. 546 -i INPUT, --input INPUT 547 Input data file. The option --input-as specifies how 548 to interpret the contents. Use "-" to indicate stdin. 549 --input-as {yaml,json,cbor,cborhex} 550 Which format to interpret the input file as. If 551 omitted, the format is inferred from the file name. 552 .yaml, .yml => YAML, .json => JSON, .cborhex => CBOR 553 as hex string, everything else => CBOR 554 -t ENTRY_TYPE, --entry-type ENTRY_TYPE 555 Name of the type (from the CDDL) to interpret the data 556 as. 557 --default-max-qty DEFAULT_MAX_QTY, --dq DEFAULT_MAX_QTY 558 Default maximum number of repetitions when no maximum 559 is specified. It is only relevant when handling data 560 that will be decoded by generated code. If omitted, a 561 large number will be used. 562 --yaml-compatibility Whether to convert CBOR-only values to YAML-compatible 563 ones (when converting from CBOR), or vice versa (when 564 converting to CBOR). When this is enabled, all CBOR 565 data is guaranteed to convert into YAML/JSON. JSON and 566 YAML do not support all data types that CBOR/CDDL 567 supports. bytestrings (BSTR), tags, undefined, and 568 maps with non-text keys need special handling. See the 569 zcbor README for more information. 570 571``` 572 573zcbor convert --help 574-------------------- 575 576``` 577usage: zcbor convert [-h] -c CDDL [--no-prelude] [-v] -i INPUT 578 [--input-as {yaml,json,cbor,cborhex}] -t ENTRY_TYPE 579 [--default-max-qty DEFAULT_MAX_QTY] 580 [--yaml-compatibility] -o OUTPUT 581 [--output-as {yaml,json,cbor,cborhex,c_code}] 582 [--c-code-var-name C_CODE_VAR_NAME] 583 [--c-code-columns C_CODE_COLUMNS] 584 585Parse a CDDL file and validate/convert between CBOR and YAML/JSON. The script 586decodes the CBOR/YAML/JSON data from a file or stdin and verifies that it 587conforms to the CDDL description. The script fails if the data does not 588conform. 'zcbor validate' can be used if only validate is needed. 589 590options: 591 -h, --help show this help message and exit 592 -c CDDL, --cddl CDDL Path to one or more input CDDL file(s). Passing 593 multiple files is equivalent to concatenating them. 594 --no-prelude Exclude the standard CDDL prelude from the build. The 595 prelude can be viewed at zcbor/cddl/prelude.cddl in 596 the repo, or together with the script. 597 -v, --verbose Print more information while parsing CDDL and 598 generating code. 599 -i INPUT, --input INPUT 600 Input data file. The option --input-as specifies how 601 to interpret the contents. Use "-" to indicate stdin. 602 --input-as {yaml,json,cbor,cborhex} 603 Which format to interpret the input file as. If 604 omitted, the format is inferred from the file name. 605 .yaml, .yml => YAML, .json => JSON, .cborhex => CBOR 606 as hex string, everything else => CBOR 607 -t ENTRY_TYPE, --entry-type ENTRY_TYPE 608 Name of the type (from the CDDL) to interpret the data 609 as. 610 --default-max-qty DEFAULT_MAX_QTY, --dq DEFAULT_MAX_QTY 611 Default maximum number of repetitions when no maximum 612 is specified. It is only relevant when handling data 613 that will be decoded by generated code. If omitted, a 614 large number will be used. 615 --yaml-compatibility Whether to convert CBOR-only values to YAML-compatible 616 ones (when converting from CBOR), or vice versa (when 617 converting to CBOR). When this is enabled, all CBOR 618 data is guaranteed to convert into YAML/JSON. JSON and 619 YAML do not support all data types that CBOR/CDDL 620 supports. bytestrings (BSTR), tags, undefined, and 621 maps with non-text keys need special handling. See the 622 zcbor README for more information. 623 -o OUTPUT, --output OUTPUT 624 Output data file. The option --output-as specifies how 625 to interpret the contents. Use "-" to indicate stdout. 626 --output-as {yaml,json,cbor,cborhex,c_code} 627 Which format to interpret the output file as. If 628 omitted, the format is inferred from the file name. 629 .yaml, .yml => YAML, .json => JSON, .c, .h => C code, 630 .cborhex => CBOR as hex string, everything else => 631 CBOR 632 --c-code-var-name C_CODE_VAR_NAME 633 Only relevant together with '--output-as c_code' or .c 634 files. 635 --c-code-columns C_CODE_COLUMNS 636 Only relevant together with '--output-as c_code' or .c 637 files. The number of bytes per line in the variable 638 instantiation. If omitted, the entire declaration is a 639 single line. 640 641``` 642