+ if (unary_expression->u.unary_expression.type != UNARY_STRING) {
+ fprintf(fd, "[error] %s: byte_order: expecting string\n",
+ __func__);
+ return -EINVAL;
+ }
+ if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
+ byte_order = BIG_ENDIAN;
+ else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
+ byte_order = LITTLE_ENDIAN;
+ else {
+ fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
+ __func__, unary_expression->u.unary_expression.u.string);
+ return -EINVAL;
+ }
+ return byte_order;
+}
+
+static
+int get_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression,
+ struct ctf_trace *trace)
+{
+ int byte_order;
+
+ if (unary_expression->u.unary_expression.type != UNARY_STRING) {
+ fprintf(fd, "[error] %s: byte_order: expecting string\n",
+ __func__);
+ return -EINVAL;
+ }
+ if (!strcmp(unary_expression->u.unary_expression.u.string, "native"))
+ byte_order = trace->byte_order;
+ else if (!strcmp(unary_expression->u.unary_expression.u.string, "network"))
+ byte_order = BIG_ENDIAN;
+ else if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
+ byte_order = BIG_ENDIAN;
+ else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
+ byte_order = LITTLE_ENDIAN;
+ else {
+ fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
+ __func__, unary_expression->u.unary_expression.u.string);
+ return -EINVAL;
+ }
+ return byte_order;
+}
+
+static
+struct declaration *ctf_declaration_integer_visit(FILE *fd, int depth,
+ struct cds_list_head *expressions,
+ struct ctf_trace *trace)
+{
+ struct ctf_node *expression;
+ uint64_t alignment, size;
+ int byte_order = trace->byte_order;
+ int signedness = 0;
+ int has_alignment = 0, has_size = 0;
+ struct declaration_integer *integer_declaration;
+
+ cds_list_for_each_entry(expression, expressions, siblings) {
+ struct ctf_node *left, *right;
+
+ left = _cds_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
+ right = _cds_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
+ assert(left->u.unary_expression.type == UNARY_STRING);
+ if (!strcmp(left->u.unary_expression.u.string, "signed")) {
+ signedness = get_boolean(fd, depth, right);
+ if (signedness < 0)
+ return NULL;
+ } else if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
+ byte_order = get_byte_order(fd, depth, right, trace);
+ if (byte_order < 0)
+ return NULL;
+ } else if (!strcmp(left->u.unary_expression.u.string, "size")) {
+ if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
+ fprintf(fd, "[error] %s: size: expecting unsigned constant\n",
+ __func__);
+ return NULL;
+ }
+ size = right->u.unary_expression.u.unsigned_constant;
+ has_size = 1;
+ } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
+ if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
+ fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
+ __func__);
+ return NULL;
+ }
+ alignment = right->u.unary_expression.u.unsigned_constant;
+ /* Make sure alignment is a power of two */
+ if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
+ fprintf(fd, "[error] %s: align: expecting power of two\n",
+ __func__);
+ return NULL;
+ }
+ has_alignment = 1;
+ } else {
+ fprintf(fd, "[error] %s: unknown attribute name %s\n",
+ __func__, left->u.unary_expression.u.string);
+ return NULL;
+ }
+ }
+ if (!has_size) {
+ fprintf(fd, "[error] %s: missing size attribute\n", __func__);
+ return NULL;
+ }
+ if (!has_alignment) {
+ if (size % CHAR_BIT) {
+ /* bit-packed alignment */
+ alignment = 1;
+ } else {
+ /* byte-packed alignment */
+ alignment = CHAR_BIT;
+ }