From b011f6b0d77e0a93fffa1b47ee32e1b07dd16a8a Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Mon, 8 Feb 2016 17:56:15 -0500 Subject: [PATCH] ir: add public bt_ctf_field_path object MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Proulx Signed-off-by: Jérémie Galarneau --- formats/ctf/ir/Makefile.am | 1 + formats/ctf/ir/event-types.c | 142 ++++++----------- formats/ctf/ir/field-path.c | 146 ++++++++++++++++++ formats/ctf/ir/resolve.c | 49 +++--- include/Makefile.am | 2 + .../babeltrace/ctf-ir/event-types-internal.h | 46 +----- include/babeltrace/ctf-ir/event-types.h | 38 +++++ .../babeltrace/ctf-ir/field-path-internal.h | 57 +++++++ include/babeltrace/ctf-ir/field-path.h | 81 ++++++++++ tests/lib/test_bt_ctf_field_type_validation.c | 25 ++- 10 files changed, 405 insertions(+), 182 deletions(-) create mode 100644 formats/ctf/ir/field-path.c create mode 100644 include/babeltrace/ctf-ir/field-path-internal.h create mode 100644 include/babeltrace/ctf-ir/field-path.h diff --git a/formats/ctf/ir/Makefile.am b/formats/ctf/ir/Makefile.am index b08643b1..e9dc96ef 100644 --- a/formats/ctf/ir/Makefile.am +++ b/formats/ctf/ir/Makefile.am @@ -8,6 +8,7 @@ libctf_ir_la_SOURCES = \ event.c \ event-fields.c \ event-types.c \ + field-path.c \ stream.c \ stream-class.c \ trace.c \ diff --git a/formats/ctf/ir/event-types.c b/formats/ctf/ir/event-types.c index 4e845f0e..f4ac0ecf 100644 --- a/formats/ctf/ir/event-types.c +++ b/formats/ctf/ir/event-types.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -2360,65 +2361,6 @@ end: return copy; } -BT_HIDDEN -struct bt_ctf_field_path *bt_ctf_field_path_create(void) -{ - struct bt_ctf_field_path *field_path = NULL; - - field_path = g_new0(struct bt_ctf_field_path, 1); - if (!field_path) { - goto end; - } - - field_path->root = CTF_NODE_UNKNOWN; - field_path->path_indexes = g_array_new(TRUE, FALSE, sizeof(int)); - if (!field_path->path_indexes) { - bt_ctf_field_path_destroy(field_path); - field_path = NULL; - } -end: - return field_path; -} - -BT_HIDDEN -void bt_ctf_field_path_clear(struct bt_ctf_field_path *field_path) -{ - if (field_path->path_indexes->len > 0) { - g_array_remove_range(field_path->path_indexes, 0, - field_path->path_indexes->len); - } -} - -BT_HIDDEN -struct bt_ctf_field_path *bt_ctf_field_path_copy( - struct bt_ctf_field_path *path) -{ - struct bt_ctf_field_path *new_path = bt_ctf_field_path_create(); - - if (!new_path) { - goto end; - } - - new_path->root = path->root; - g_array_insert_vals(new_path->path_indexes, 0, - path->path_indexes->data, path->path_indexes->len); -end: - return new_path; -} - -BT_HIDDEN -void bt_ctf_field_path_destroy(struct bt_ctf_field_path *path) -{ - if (!path) { - return; - } - - if (path->path_indexes) { - g_array_free(path->path_indexes, TRUE); - } - g_free(path); -} - BT_HIDDEN int bt_ctf_field_type_structure_get_field_name_index( struct bt_ctf_field_type *type, const char *name) @@ -2529,26 +2471,12 @@ int bt_ctf_field_type_sequence_set_length_field_path( sequence = container_of(type, struct bt_ctf_field_type_sequence, parent); - if (sequence->length_field_path) { - bt_ctf_field_path_destroy(sequence->length_field_path); - } - sequence->length_field_path = path; + bt_get(path); + BT_MOVE(sequence->length_field_path, path); end: return ret; } -BT_HIDDEN -struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_field_path( - struct bt_ctf_field_type *type) -{ - struct bt_ctf_field_type_sequence *sequence; - - sequence = container_of(type, struct bt_ctf_field_type_sequence, - parent); - - return sequence->length_field_path; -} - BT_HIDDEN int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type, struct bt_ctf_field_path *path) @@ -2563,26 +2491,12 @@ int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type, variant = container_of(type, struct bt_ctf_field_type_variant, parent); - if (variant->tag_path) { - bt_ctf_field_path_destroy(variant->tag_path); - } - variant->tag_path = path; + bt_get(path); + BT_MOVE(variant->tag_field_path, path); end: return ret; } -BT_HIDDEN -struct bt_ctf_field_path *bt_ctf_field_type_variant_get_tag_field_path( - struct bt_ctf_field_type *type) -{ - struct bt_ctf_field_type_variant *variant; - - variant = container_of(type, struct bt_ctf_field_type_variant, - parent); - - return variant->tag_path; -} - BT_HIDDEN int bt_ctf_field_type_variant_set_tag_field_type(struct bt_ctf_field_type *type, struct bt_ctf_field_type *tag) @@ -2708,7 +2622,7 @@ void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *type) g_hash_table_destroy(variant->field_name_to_index); g_string_free(variant->tag_name, TRUE); bt_put(&variant->tag->parent); - bt_ctf_field_path_destroy(variant->tag_path); + BT_PUT(variant->tag_field_path); g_free(variant); } @@ -2738,7 +2652,7 @@ void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *type) bt_put(sequence->element_type); g_string_free(sequence->length_field_name, TRUE); - bt_ctf_field_path_destroy(sequence->length_field_path); + BT_PUT(sequence->length_field_path); g_free(sequence); } @@ -3562,10 +3476,10 @@ struct bt_ctf_field_type *bt_ctf_field_type_variant_copy( } copy_variant->declaration = variant->declaration; - if (variant->tag_path) { - copy_variant->tag_path = bt_ctf_field_path_copy( - variant->tag_path); - if (!copy_variant->tag_path) { + if (variant->tag_field_path) { + copy_variant->tag_field_path = bt_ctf_field_path_copy( + variant->tag_field_path); + if (!copy_variant->tag_field_path) { goto error; } } @@ -4146,3 +4060,37 @@ int bt_ctf_field_type_get_field_index(struct bt_ctf_field_type *field_type, return field_index; } + +struct bt_ctf_field_path *bt_ctf_field_type_variant_get_tag_field_path( + struct bt_ctf_field_type *type) +{ + struct bt_ctf_field_path *field_path = NULL; + struct bt_ctf_field_type_variant *variant; + + if (!type || !bt_ctf_field_type_is_variant(type)) { + goto end; + } + + variant = container_of(type, struct bt_ctf_field_type_variant, + parent); + field_path = bt_get(variant->tag_field_path); +end: + return field_path; +} + +struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_field_path( + struct bt_ctf_field_type *type) +{ + struct bt_ctf_field_path *field_path = NULL; + struct bt_ctf_field_type_sequence *sequence; + + if (!type || !bt_ctf_field_type_is_sequence(type)) { + goto end; + } + + sequence = container_of(type, struct bt_ctf_field_type_sequence, + parent); + field_path = bt_get(sequence->length_field_path); +end: + return field_path; +} diff --git a/formats/ctf/ir/field-path.c b/formats/ctf/ir/field-path.c new file mode 100644 index 00000000..183a8579 --- /dev/null +++ b/formats/ctf/ir/field-path.c @@ -0,0 +1,146 @@ +/* + * field-path.c + * + * Babeltrace CTF IR - Field path + * + * Copyright 2013, 2014 Jérémie Galarneau + * Copyright 2016 Philippe Proulx + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include + +static +void field_path_destroy(struct bt_object *obj) +{ + struct bt_ctf_field_path *field_path = (struct bt_ctf_field_path *) obj; + + if (!field_path) { + return; + } + + if (field_path->indexes) { + g_array_free(field_path->indexes, TRUE); + } + g_free(field_path); +} + +BT_HIDDEN +struct bt_ctf_field_path *bt_ctf_field_path_create(void) +{ + struct bt_ctf_field_path *field_path = NULL; + + field_path = g_new0(struct bt_ctf_field_path, 1); + if (!field_path) { + goto error; + } + + bt_object_init(field_path, field_path_destroy); + field_path->root = CTF_NODE_UNKNOWN; + field_path->indexes = g_array_new(TRUE, FALSE, sizeof(int)); + if (!field_path->indexes) { + goto error; + } + + return field_path; + +error: + BT_PUT(field_path); + return NULL; +} + +BT_HIDDEN +void bt_ctf_field_path_clear(struct bt_ctf_field_path *field_path) +{ + if (field_path->indexes->len > 0) { + g_array_remove_range(field_path->indexes, 0, + field_path->indexes->len); + } +} + +BT_HIDDEN +struct bt_ctf_field_path *bt_ctf_field_path_copy( + struct bt_ctf_field_path *path) +{ + struct bt_ctf_field_path *new_path = bt_ctf_field_path_create(); + + if (!new_path) { + goto end; + } + + new_path->root = path->root; + g_array_insert_vals(new_path->indexes, 0, + path->indexes->data, path->indexes->len); +end: + return new_path; +} + +enum bt_ctf_node bt_ctf_field_path_get_root( + const struct bt_ctf_field_path *field_path) +{ + enum bt_ctf_scope scope = CTF_NODE_UNKNOWN; + + if (!field_path) { + goto end; + } + + scope = field_path->root; + +end: + return scope; +} + +int bt_ctf_field_path_get_index_count( + const struct bt_ctf_field_path *field_path) +{ + int ret = -1; + + if (!field_path) { + goto end; + } + + ret = field_path->indexes->len; + +end: + return ret; +} + +int bt_ctf_field_path_get_index(const struct bt_ctf_field_path *field_path, + int index) +{ + int ret = INT_MIN; + + if (!field_path || index < 0) { + goto end; + } + + if (index >= field_path->indexes->len) { + goto end; + } + + ret = g_array_index(field_path->indexes, int, index); + +end: + return ret; +} diff --git a/formats/ctf/ir/resolve.c b/formats/ctf/ir/resolve.c index fe2e3859..330bf81e 100644 --- a/formats/ctf/ir/resolve.c +++ b/formats/ctf/ir/resolve.c @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include #include #include @@ -423,7 +425,7 @@ int ptokens_to_field_path(GList *ptokens, struct bt_ctf_field_path *field_path, } /* Create new field path entry */ - g_array_append_val(field_path->path_indexes, child_index); + g_array_append_val(field_path->indexes, child_index); /* Get child field type */ child_type = bt_ctf_field_type_get_field_at_index(type, @@ -522,7 +524,7 @@ int relative_ptokens_to_field_path(GList *ptokens, /* Found: stitch tail field path to head field path */ int i = 0; int tail_field_path_len = - tail_field_path->path_indexes->len; + tail_field_path->indexes->len; while (true) { struct bt_ctf_field_type *cur_type = @@ -534,17 +536,17 @@ int relative_ptokens_to_field_path(GList *ptokens, break; } - g_array_append_val(field_path->path_indexes, + g_array_append_val(field_path->indexes, index); i++; } for (i = 0; i < tail_field_path_len; i++) { int index = g_array_index( - tail_field_path->path_indexes, + tail_field_path->indexes, int, i); - g_array_append_val(field_path->path_indexes, + g_array_append_val(field_path->indexes, index); } break; @@ -582,7 +584,7 @@ int relative_ptokens_to_field_path(GList *ptokens, } end: - bt_ctf_field_path_destroy(tail_field_path); + BT_PUT(tail_field_path); return ret; } @@ -650,8 +652,7 @@ struct bt_ctf_field_path *pathstr_to_field_path(const char *pathstr, end: if (ret) { - bt_ctf_field_path_destroy(field_path); - field_path = NULL; + BT_PUT(field_path); } ptokens_destroy(ptokens); @@ -684,10 +685,10 @@ struct bt_ctf_field_type *field_path_to_field_type( } /* Locate target */ - for (i = 0; i < field_path->path_indexes->len; i++) { + for (i = 0; i < field_path->indexes->len; i++) { struct bt_ctf_field_type *child_type; int child_index = - g_array_index(field_path->path_indexes, int, i); + g_array_index(field_path->indexes, int, i); /* Get child field type */ child_type = bt_ctf_field_type_get_field_at_index(type, @@ -733,14 +734,14 @@ struct bt_ctf_field_path *get_ctx_stack_field_path(struct resolve_context *ctx) struct type_stack_frame *frame; frame = type_stack_at(ctx->type_stack, i); - g_array_append_val(field_path->path_indexes, frame->index); + g_array_append_val(field_path->indexes, frame->index); } return field_path; error: - bt_ctf_field_path_destroy(field_path); - return NULL; + BT_PUT(field_path); + return field_path; } /* @@ -759,8 +760,8 @@ int get_field_paths_lca_index(struct bt_ctf_field_path *field_path1, * Start from both roots and find the first mismatch. */ assert(field_path1->root == field_path2->root); - field_path1_len = field_path1->path_indexes->len; - field_path2_len = field_path2->path_indexes->len; + field_path1_len = field_path1->indexes->len; + field_path2_len = field_path2->indexes->len; while (true) { int target_index, ctx_index; @@ -777,9 +778,9 @@ int get_field_paths_lca_index(struct bt_ctf_field_path *field_path1, break; } - target_index = g_array_index(field_path1->path_indexes, int, + target_index = g_array_index(field_path1->indexes, int, lca_index); - ctx_index = g_array_index(field_path2->path_indexes, int, + ctx_index = g_array_index(field_path2->indexes, int, lca_index); if (target_index != ctx_index) { @@ -805,7 +806,7 @@ int validate_target_field_path(struct bt_ctf_field_path *target_field_path, { int ret = 0; struct bt_ctf_field_path *ctx_field_path; - int target_field_path_len = target_field_path->path_indexes->len; + int target_field_path_len = target_field_path->indexes->len; int lca_index; int ctx_cur_field_type_id; int target_type_id; @@ -856,9 +857,9 @@ int validate_target_field_path(struct bt_ctf_field_path *target_field_path, * Make sure the target field path is located before the * context field path. */ - target_index = g_array_index(target_field_path->path_indexes, + target_index = g_array_index(target_field_path->indexes, int, lca_index); - ctx_index = g_array_index(ctx_field_path->path_indexes, + ctx_index = g_array_index(ctx_field_path->indexes, int, lca_index); if (target_index >= ctx_index) { @@ -895,7 +896,7 @@ int validate_target_field_path(struct bt_ctf_field_path *target_field_path, } end: - bt_ctf_field_path_destroy(ctx_field_path); + BT_PUT(ctx_field_path); return ret; } @@ -961,8 +962,6 @@ int resolve_sequence_or_variant_type(struct bt_ctf_field_type *type, _printf_error("Cannot set sequence field type's length field path\n"); goto end; } - - target_field_path = NULL; } else if (type_id == CTF_TYPE_VARIANT) { ret = bt_ctf_field_type_variant_set_tag_field_path( type, target_field_path); @@ -971,8 +970,6 @@ int resolve_sequence_or_variant_type(struct bt_ctf_field_type *type, goto end; } - target_field_path = NULL; - ret = bt_ctf_field_type_variant_set_tag_field_type( type, target_type); if (ret) { @@ -984,7 +981,7 @@ int resolve_sequence_or_variant_type(struct bt_ctf_field_type *type, } end: - bt_ctf_field_path_destroy(target_field_path); + BT_PUT(target_field_path); BT_PUT(target_type); return ret; } diff --git a/include/Makefile.am b/include/Makefile.am index 25d64df7..fbb7fce6 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -28,6 +28,7 @@ babeltracectfirinclude_HEADERS = \ babeltrace/ctf-ir/event-fields.h \ babeltrace/ctf-ir/event-types.h \ babeltrace/ctf-ir/event.h \ + babeltrace/ctf-ir/field-path.h \ babeltrace/ctf-ir/stream.h \ babeltrace/ctf-ir/stream-class.h \ babeltrace/ctf-ir/trace.h \ @@ -59,6 +60,7 @@ noinst_HEADERS = \ babeltrace/ctf-ir/event-types-internal.h \ babeltrace/ctf-ir/event-fields-internal.h \ babeltrace/ctf-ir/event-internal.h \ + babeltrace/ctf-ir/field-path-internal.h \ babeltrace/ctf-ir/clock-internal.h \ babeltrace/ctf-ir/resolve-internal.h \ babeltrace/ctf-ir/stream-class-internal.h \ diff --git a/include/babeltrace/ctf-ir/event-types-internal.h b/include/babeltrace/ctf-ir/event-types-internal.h index a4ccd2e8..8eaaeb88 100644 --- a/include/babeltrace/ctf-ir/event-types-internal.h +++ b/include/babeltrace/ctf-ir/event-types-internal.h @@ -41,29 +41,6 @@ typedef void (*type_freeze_func)(struct bt_ctf_field_type *); typedef int (*type_serialize_func)(struct bt_ctf_field_type *, struct metadata_context *); -enum bt_ctf_node { - CTF_NODE_UNKNOWN = -1, - CTF_NODE_ENV = 0, - CTF_NODE_TRACE_PACKET_HEADER = 1, - CTF_NODE_STREAM_PACKET_CONTEXT = 2, - CTF_NODE_STREAM_EVENT_HEADER = 3, - CTF_NODE_STREAM_EVENT_CONTEXT = 4, - CTF_NODE_EVENT_CONTEXT = 5, - CTF_NODE_EVENT_FIELDS = 6, -}; - -struct bt_ctf_field_path { - enum bt_ctf_node root; - - /* - * Array of integers (int) indicating the index in either - * structures, variants, arrays, or sequences that make up - * the path to a field type. -1 means the "current element - * of an array or sequence type". - */ - GArray *path_indexes; -}; - struct bt_ctf_field_type { struct bt_object base; struct bt_declaration *declaration; @@ -155,7 +132,7 @@ struct bt_ctf_field_type_variant { struct bt_ctf_field_type parent; GString *tag_name; struct bt_ctf_field_type_enumeration *tag; - struct bt_ctf_field_path *tag_path; + struct bt_ctf_field_path *tag_field_path; GHashTable *field_name_to_index; GPtrArray *fields; /* Array of pointers to struct structure_field */ struct declaration_variant declaration; @@ -219,19 +196,6 @@ BT_HIDDEN struct bt_ctf_field_type *bt_ctf_field_type_copy( struct bt_ctf_field_type *type); -BT_HIDDEN -struct bt_ctf_field_path *bt_ctf_field_path_create(void); - -BT_HIDDEN -void bt_ctf_field_path_clear(struct bt_ctf_field_path *field_path); - -BT_HIDDEN -struct bt_ctf_field_path *bt_ctf_field_path_copy( - struct bt_ctf_field_path *path); - -BT_HIDDEN -void bt_ctf_field_path_destroy(struct bt_ctf_field_path *path); - BT_HIDDEN int bt_ctf_field_type_structure_get_field_name_index( struct bt_ctf_field_type *structure, const char *name); @@ -251,18 +215,10 @@ int bt_ctf_field_type_sequence_set_length_field_path( struct bt_ctf_field_type *type, struct bt_ctf_field_path *path); -BT_HIDDEN -struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_field_path( - struct bt_ctf_field_type *type); - BT_HIDDEN int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type, struct bt_ctf_field_path *path); -BT_HIDDEN -struct bt_ctf_field_path *bt_ctf_field_type_variant_get_tag_field_path( - struct bt_ctf_field_type *type); - BT_HIDDEN int bt_ctf_field_type_variant_set_tag_field_type(struct bt_ctf_field_type *type, struct bt_ctf_field_type *tag_type); diff --git a/include/babeltrace/ctf-ir/event-types.h b/include/babeltrace/ctf-ir/event-types.h index 2dfa433e..2bffe88a 100644 --- a/include/babeltrace/ctf-ir/event-types.h +++ b/include/babeltrace/ctf-ir/event-types.h @@ -41,6 +41,7 @@ struct bt_ctf_event_class; struct bt_ctf_event; struct bt_ctf_field_type; struct bt_ctf_field; +struct bt_ctf_field_path; enum bt_ctf_integer_base { BT_CTF_INTEGER_BASE_UNKNOWN = -1, @@ -63,6 +64,17 @@ enum bt_ctf_byte_order { BT_CTF_BYTE_ORDER_NETWORK, }; +enum bt_ctf_node { + CTF_NODE_UNKNOWN = -1, + CTF_NODE_ENV = 0, + CTF_NODE_TRACE_PACKET_HEADER = 1, + CTF_NODE_STREAM_PACKET_CONTEXT = 2, + CTF_NODE_STREAM_EVENT_HEADER = 3, + CTF_NODE_STREAM_EVENT_CONTEXT = 4, + CTF_NODE_EVENT_CONTEXT = 5, + CTF_NODE_EVENT_FIELDS = 6, +}; + /* * bt_ctf_field_type_integer_create: create an integer field type. * @@ -741,6 +753,32 @@ extern enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order( extern int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *type, enum bt_ctf_byte_order byte_order); +/* + * bt_ctf_field_type_variant_get_tag_field_path: get a variant's tag's field + * path. + * + * Get the variant's tag's field path. + * + * @param type Field type. + * + * Returns the field path on success, NULL on error or if no field path is set. + */ +extern struct bt_ctf_field_path *bt_ctf_field_type_variant_get_tag_field_path( + struct bt_ctf_field_type *type); + +/* + * bt_ctf_field_type_sequence_get_length_field_path: get a sequence's length's + * field path. + * + * Get the sequence's length's field path. + * + * @param type Field type. + * + * Returns the field path on success, NULL on error or if no field path is set. + */ +extern struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_field_path( + struct bt_ctf_field_type *type); + /* * bt_ctf_field_type_compare: compare two field types recursively * diff --git a/include/babeltrace/ctf-ir/field-path-internal.h b/include/babeltrace/ctf-ir/field-path-internal.h new file mode 100644 index 00000000..8abe0e3c --- /dev/null +++ b/include/babeltrace/ctf-ir/field-path-internal.h @@ -0,0 +1,57 @@ +#ifndef BABELTRACE_CTF_IR_FIELD_PATH_INTERNAL +#define BABELTRACE_CTF_IR_FIELD_PATH_INTERNAL + +/* + * BabelTrace - CTF IR: Field path + * + * Copyright 2016 Philippe Proulx + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * The Common Trace Format (CTF) Specification is available at + * http://www.efficios.com/ctf + */ + +#include +#include + +struct bt_ctf_field_path { + struct bt_object base; + enum bt_ctf_node root; + + /* + * Array of integers (int) indicating the index in either + * structures, variants, arrays, or sequences that make up + * the path to a field type. -1 means the "current element + * of an array or sequence type". + */ + GArray *indexes; +}; + +BT_HIDDEN +struct bt_ctf_field_path *bt_ctf_field_path_create(void); + +BT_HIDDEN +void bt_ctf_field_path_clear(struct bt_ctf_field_path *field_path); + +BT_HIDDEN +struct bt_ctf_field_path *bt_ctf_field_path_copy( + struct bt_ctf_field_path *path); + +#endif /* BABELTRACE_CTF_IR_FIELD_PATH_INTERNAL */ diff --git a/include/babeltrace/ctf-ir/field-path.h b/include/babeltrace/ctf-ir/field-path.h new file mode 100644 index 00000000..443bf39c --- /dev/null +++ b/include/babeltrace/ctf-ir/field-path.h @@ -0,0 +1,81 @@ +#ifndef BABELTRACE_CTF_IR_FIELD_PATH +#define BABELTRACE_CTF_IR_FIELD_PATH + +/* + * BabelTrace - CTF IR: Field path + * + * Copyright 2016 Philippe Proulx + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * The Common Trace Format (CTF) Specification is available at + * http://www.efficios.com/ctf + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct bt_ctf_field_path; + +/* + * bt_ctf_field_path_get_root: get the root node of a field path. + * + * Get the field path's root node. + * + * @param field_path Field path. + * + * Returns the root node of a field path, or BT_CTF_SCOPE_UNKNOWN on error. + */ +extern enum bt_ctf_node bt_ctf_field_path_get_root( + const struct bt_ctf_field_path *field_path); + +/* + * bt_ctf_field_path_get_index_count: get the number of indexes of a field path. + * + * Get the number of indexes of a field path. + * + * @param field_path Field path. + * + * Returns the field path's index count, or a negative value on error. + */ +extern int bt_ctf_field_path_get_index_count( + const struct bt_ctf_field_path *field_path); + +/* + * bt_ctf_field_path_get_index: get the field path's index at a specific index. + * + * Get the field path's index at a specific index. + * + * @param field_path Field path. + * @param index Index. + * + * Returns a field path index, or INT_MIN on error. + */ +extern int bt_ctf_field_path_get_index( + const struct bt_ctf_field_path *field_path, + int index); + +#ifdef __cplusplus +} +#endif + +#endif /* BABELTRACE_CTF_IR_FIELD_PATH */ diff --git a/tests/lib/test_bt_ctf_field_type_validation.c b/tests/lib/test_bt_ctf_field_type_validation.c index 2a173e7d..e114eae2 100644 --- a/tests/lib/test_bt_ctf_field_type_validation.c +++ b/tests/lib/test_bt_ctf_field_type_validation.c @@ -20,7 +20,7 @@ */ #include -#include +#include #include #include #include @@ -1645,20 +1645,16 @@ int validate_field_path(struct bt_ctf_field_type *field_type, int expected_index; int actual_index; int i = 0; - const struct bt_ctf_field_path *field_path; + struct bt_ctf_field_path *field_path = NULL; va_list ap; va_start(ap, root); - if (bt_ctf_field_type_is_sequence(field_type)) { - field_path = ((struct bt_ctf_field_type_sequence *) - field_type)->length_field_path; + field_path = bt_ctf_field_type_sequence_get_length_field_path( + field_type); } else if (bt_ctf_field_type_is_variant(field_type)) { - field_path = ((struct bt_ctf_field_type_variant *) - field_type)->tag_path; - } else { - ret = -1; - goto end; + field_path = bt_ctf_field_type_variant_get_tag_field_path( + field_type); } if (!field_path) { @@ -1666,12 +1662,12 @@ int validate_field_path(struct bt_ctf_field_type *field_type, goto end; } - if (field_path->root != root) { + if (bt_ctf_field_path_get_root(field_path) != root) { ret = -1; goto end; } - len = field_path->path_indexes->len; + len = bt_ctf_field_path_get_index_count(field_path); while (true) { expected_index = va_arg(ap, int); @@ -1684,9 +1680,9 @@ int validate_field_path(struct bt_ctf_field_type *field_type, break; } - actual_index = g_array_index(field_path->path_indexes, int, i); + actual_index = bt_ctf_field_path_get_index(field_path, i); - if (actual_index != expected_index) { + if (actual_index == INT_MIN) { ret = -1; goto end; } @@ -1699,6 +1695,7 @@ int validate_field_path(struct bt_ctf_field_type *field_type, } end: + BT_PUT(field_path); va_end(ap); return ret; -- 2.34.1