+void lttv_attribute_recursive_free(LttvAttribute *self)
+{
+ int i, nb;
+
+ Attribute *a;
+
+ nb = self->attributes->len;
+
+ for(i = 0 ; i < nb ; i++) {
+ a = &g_array_index(self->attributes, Attribute, i);
+ if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) {
+ lttv_attribute_recursive_free((LttvAttribute *)(a->value.dv_gobject));
+ }
+ }
+ g_object_unref(self);
+}
+
+
+void lttv_attribute_recursive_add(LttvAttribute *dest, LttvAttribute *src)
+{
+ int i, nb;
+
+ Attribute *a;
+
+ LttvAttributeValue value;
+
+ nb = src->attributes->len;
+
+ for(i = 0 ; i < nb ; i++) {
+ a = &g_array_index(src->attributes, Attribute, i);
+ if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) {
+ lttv_attribute_recursive_add(
+ /*CHECK*/(LttvAttribute *)lttv_attribute_find_subdir(dest, a->name),
+ (LttvAttribute *)(a->value.dv_gobject));
+ }
+ else {
+ g_assert(lttv_attribute_find(dest, a->name, a->type, &value));
+ switch(a->type) {
+ case LTTV_INT:
+ *value.v_int += a->value.dv_int;
+ break;
+ case LTTV_UINT:
+ *value.v_uint += a->value.dv_uint;
+ break;
+ case LTTV_LONG:
+ *value.v_long += a->value.dv_long;
+ break;
+ case LTTV_ULONG:
+ *value.v_ulong += a->value.dv_ulong;
+ break;
+ case LTTV_FLOAT:
+ *value.v_float += a->value.dv_float;
+ break;
+ case LTTV_DOUBLE:
+ *value.v_double += a->value.dv_double;
+ break;
+ case LTTV_TIME:
+ *value.v_time = ltt_time_add(*value.v_time, a->value.dv_time);
+ break;
+ case LTTV_POINTER:
+ break;
+ case LTTV_STRING:
+ break;
+ case LTTV_GOBJECT:
+ break;
+ case LTTV_NONE:
+ break;
+ }
+ }
+ }
+}
+
+