bt-ctfirtg
bt-ctfirtg is a command-line utility which generates C code to create CTF IR field types out of a YAML configuration file.
Installing
sudo pip3 install bt-ctfirtg
Using
See bt-ctfirtg --help
for command-line options.
Simple example:
bt-ctfirtg my-config.yaml
Creation code only with assertions:
bt-ctfirtg --creation --asserts my-config.yaml
Declaration code only with one indentation level:
bt-ctfirtg --declaration --indent 1 my-config.yaml
YAML configuration
bt-ctfirtg expects a type object as the root element of a YAML configuration file. The YAML structure is the same as barectf configuration files.
Example showing all types:
# structure
class: struct
fields:
# integer
faller:
class: int
size: 23
signed: true
align: 4
# floating point number
palladic:
class: float
size:
exp: 8
mant: 24
byte-order: be
# enumeration
kamaloka:
class: enum
value-type:
class: int
size: 12
members:
- ZERO
- ONE
- label: FOUR
value: 4
- FIVE
- label: A HUNDRED TO A THOUSAND
value: [100, 1000]
- A THOUSAND AND ONE
# string
jellylike:
class: string
encoding: ascii
# array
franglais:
class: array
length: 78
element-type:
class: struct
min-align: 64
fields:
kamaloka:
class: int
size: 17
kroon:
class: string
# sequence (variable-length array)
sestertia:
class: array
length: trace.packet.header.previous.stuff
element-type:
class: float
size:
exp: 11
mant: 53
align: 64
# variant
dramamine:
class: var
tag: kamaloka
types:
sauger:
class: int
size: 64
signed: true
bud:
class: string
unenacted:
# empty structure
class: struct
This will generate the following C code (declarations, creation, and put references) when enabling assertions:
struct bt_ctf_field_type *root = NULL;
struct bt_ctf_field_type *root_faller = NULL;
struct bt_ctf_field_type *root_palladic = NULL;
struct bt_ctf_field_type *root_kamaloka = NULL;
struct bt_ctf_field_type *root_kamaloka_int = NULL;
struct bt_ctf_field_type *root_jellylike = NULL;
struct bt_ctf_field_type *root_franglais = NULL;
struct bt_ctf_field_type *root_franglais_elem = NULL;
struct bt_ctf_field_type *root_franglais_elem_kamaloka = NULL;
struct bt_ctf_field_type *root_franglais_elem_kroon = NULL;
struct bt_ctf_field_type *root_sestertia = NULL;
struct bt_ctf_field_type *root_sestertia_elem = NULL;
struct bt_ctf_field_type *root_dramamine = NULL;
struct bt_ctf_field_type *root_dramamine_sauger = NULL;
struct bt_ctf_field_type *root_dramamine_bud = NULL;
struct bt_ctf_field_type *root_dramamine_unenacted = NULL;
int ret;
root = bt_ctf_field_type_structure_create();
assert(root);
ret = bt_ctf_field_type_set_alignment(root, 64);
assert(ret == 0);
root_faller = bt_ctf_field_type_integer_create(23);
assert(root_faller);
ret = bt_ctf_field_type_integer_set_signed(root_faller, 1);
assert(ret == 0);
ret = bt_ctf_field_type_integer_set_base(root_faller, 10);
assert(ret == 0);
ret = bt_ctf_field_type_integer_set_encoding(root_faller, CTF_STRING_NONE);
assert(ret == 0);
ret = bt_ctf_field_type_set_byte_order(root_faller, BT_CTF_BYTE_ORDER_LITTLE_ENDIAN);
assert(ret == 0);
ret = bt_ctf_field_type_set_alignment(root_faller, 4);
assert(ret == 0);
ret = bt_ctf_field_type_structure_add_field(root, root_faller, "faller");
assert(ret == 0);
root_palladic = bt_ctf_field_type_floating_point_create();
assert(root_palladic);
ret = bt_ctf_field_type_floating_point_set_exponent_digits(root_palladic, 8);
assert(ret == 0);
ret = bt_ctf_field_type_floating_point_set_mantissa_digits(root_palladic, 24);
assert(ret == 0);
ret = bt_ctf_field_type_set_byte_order(root_palladic, BT_CTF_BYTE_ORDER_BIG_ENDIAN);
assert(ret == 0);
ret = bt_ctf_field_type_set_alignment(root_palladic, 8);
assert(ret == 0);
ret = bt_ctf_field_type_structure_add_field(root, root_palladic, "palladic");
assert(ret == 0);
root_kamaloka_int = bt_ctf_field_type_integer_create(12);
assert(root_kamaloka_int);
ret = bt_ctf_field_type_integer_set_signed(root_kamaloka_int, 0);
assert(ret == 0);
ret = bt_ctf_field_type_integer_set_base(root_kamaloka_int, 10);
assert(ret == 0);
ret = bt_ctf_field_type_integer_set_encoding(root_kamaloka_int, CTF_STRING_NONE);
assert(ret == 0);
ret = bt_ctf_field_type_set_byte_order(root_kamaloka_int, BT_CTF_BYTE_ORDER_LITTLE_ENDIAN);
assert(ret == 0);
ret = bt_ctf_field_type_set_alignment(root_kamaloka_int, 1);
assert(ret == 0);
root_kamaloka = bt_ctf_field_type_enumeration_create(root_kamaloka_int);
assert(root_kamaloka);
ret = bt_ctf_field_type_enumeration_add_mapping(root_kamaloka, "ZERO", 0, 0);
assert(ret == 0);
ret = bt_ctf_field_type_enumeration_add_mapping(root_kamaloka, "ONE", 1, 1);
assert(ret == 0);
ret = bt_ctf_field_type_enumeration_add_mapping(root_kamaloka, "FOUR", 4, 4);
assert(ret == 0);
ret = bt_ctf_field_type_enumeration_add_mapping(root_kamaloka, "FIVE", 5, 5);
assert(ret == 0);
ret = bt_ctf_field_type_enumeration_add_mapping(root_kamaloka, "A HUNDRED TO A THOUSAND", 100, 1000);
assert(ret == 0);
ret = bt_ctf_field_type_enumeration_add_mapping(root_kamaloka, "A THOUSAND AND ONE", 1001, 1001);
assert(ret == 0);
ret = bt_ctf_field_type_structure_add_field(root, root_kamaloka, "kamaloka");
assert(ret == 0);
root_jellylike = bt_ctf_field_type_string_create();
assert(root_jellylike);
ret = bt_ctf_field_type_string_set_encoding(root_jellylike, CTF_STRING_ASCII);
assert(ret == 0);
ret = bt_ctf_field_type_structure_add_field(root, root_jellylike, "jellylike");
assert(ret == 0);
root_franglais_elem = bt_ctf_field_type_structure_create();
assert(root_franglais_elem);
ret = bt_ctf_field_type_set_alignment(root_franglais_elem, 64);
assert(ret == 0);
root_franglais_elem_kamaloka = bt_ctf_field_type_integer_create(17);
assert(root_franglais_elem_kamaloka);
ret = bt_ctf_field_type_integer_set_signed(root_franglais_elem_kamaloka, 0);
assert(ret == 0);
ret = bt_ctf_field_type_integer_set_base(root_franglais_elem_kamaloka, 10);
assert(ret == 0);
ret = bt_ctf_field_type_integer_set_encoding(root_franglais_elem_kamaloka, CTF_STRING_NONE);
assert(ret == 0);
ret = bt_ctf_field_type_set_byte_order(root_franglais_elem_kamaloka, BT_CTF_BYTE_ORDER_LITTLE_ENDIAN);
assert(ret == 0);
ret = bt_ctf_field_type_set_alignment(root_franglais_elem_kamaloka, 1);
assert(ret == 0);
ret = bt_ctf_field_type_structure_add_field(root_franglais_elem, root_franglais_elem_kamaloka, "kamaloka");
assert(ret == 0);
root_franglais_elem_kroon = bt_ctf_field_type_string_create();
assert(root_franglais_elem_kroon);
ret = bt_ctf_field_type_string_set_encoding(root_franglais_elem_kroon, CTF_STRING_UTF8);
assert(ret == 0);
ret = bt_ctf_field_type_structure_add_field(root_franglais_elem, root_franglais_elem_kroon, "kroon");
assert(ret == 0);
root_franglais = bt_ctf_field_type_array_create(root_franglais_elem, 78);
assert(root_franglais);
ret = bt_ctf_field_type_structure_add_field(root, root_franglais, "franglais");
assert(ret == 0);
root_sestertia_elem = bt_ctf_field_type_floating_point_create();
assert(root_sestertia_elem);
ret = bt_ctf_field_type_floating_point_set_exponent_digits(root_sestertia_elem, 11);
assert(ret == 0);
ret = bt_ctf_field_type_floating_point_set_mantissa_digits(root_sestertia_elem, 53);
assert(ret == 0);
ret = bt_ctf_field_type_set_byte_order(root_sestertia_elem, BT_CTF_BYTE_ORDER_LITTLE_ENDIAN);
assert(ret == 0);
ret = bt_ctf_field_type_set_alignment(root_sestertia_elem, 64);
assert(ret == 0);
root_sestertia = bt_ctf_field_type_sequence_create(root_sestertia_elem, "trace.packet.header.previous.stuff");
assert(root_sestertia);
ret = bt_ctf_field_type_structure_add_field(root, root_sestertia, "sestertia");
assert(ret == 0);
root_dramamine = bt_ctf_field_type_variant_create(NULL, "kamaloka");
assert(root_dramamine);
root_dramamine_sauger = bt_ctf_field_type_integer_create(64);
assert(root_dramamine_sauger);
ret = bt_ctf_field_type_integer_set_signed(root_dramamine_sauger, 1);
assert(ret == 0);
ret = bt_ctf_field_type_integer_set_base(root_dramamine_sauger, 10);
assert(ret == 0);
ret = bt_ctf_field_type_integer_set_encoding(root_dramamine_sauger, CTF_STRING_NONE);
assert(ret == 0);
ret = bt_ctf_field_type_set_byte_order(root_dramamine_sauger, BT_CTF_BYTE_ORDER_LITTLE_ENDIAN);
assert(ret == 0);
ret = bt_ctf_field_type_set_alignment(root_dramamine_sauger, 8);
assert(ret == 0);
ret = bt_ctf_field_type_variant_add_field(root_dramamine, root_dramamine_sauger, "sauger");
assert(ret == 0);
root_dramamine_bud = bt_ctf_field_type_string_create();
assert(root_dramamine_bud);
ret = bt_ctf_field_type_string_set_encoding(root_dramamine_bud, CTF_STRING_UTF8);
assert(ret == 0);
ret = bt_ctf_field_type_variant_add_field(root_dramamine, root_dramamine_bud, "bud");
assert(ret == 0);
root_dramamine_unenacted = bt_ctf_field_type_structure_create();
assert(root_dramamine_unenacted);
ret = bt_ctf_field_type_set_alignment(root_dramamine_unenacted, 1);
assert(ret == 0);
ret = bt_ctf_field_type_variant_add_field(root_dramamine, root_dramamine_unenacted, "unenacted");
assert(ret == 0);
ret = bt_ctf_field_type_structure_add_field(root, root_dramamine, "dramamine");
assert(ret == 0);
bt_ctf_field_type_put(root);
bt_ctf_field_type_put(root_faller);
bt_ctf_field_type_put(root_palladic);
bt_ctf_field_type_put(root_kamaloka);
bt_ctf_field_type_put(root_kamaloka_int);
bt_ctf_field_type_put(root_jellylike);
bt_ctf_field_type_put(root_franglais);
bt_ctf_field_type_put(root_franglais_elem);
bt_ctf_field_type_put(root_franglais_elem_kamaloka);
bt_ctf_field_type_put(root_franglais_elem_kroon);
bt_ctf_field_type_put(root_sestertia);
bt_ctf_field_type_put(root_sestertia_elem);
bt_ctf_field_type_put(root_dramamine);
bt_ctf_field_type_put(root_dramamine_sauger);
bt_ctf_field_type_put(root_dramamine_bud);
bt_ctf_field_type_put(root_dramamine_unenacted);