Coverage Report

Created: 2026-06-05 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/igraph/src/io/gml-tree.c
Line
Count
Source
1
/*
2
   igraph library.
3
   Copyright (C) 2007-2022  The igraph development team
4
5
   This program is free software; you can redistribute it and/or modify
6
   it under the terms of the GNU General Public License as published by
7
   the Free Software Foundation; either version 2 of the License, or
8
   (at your option) any later version.
9
10
   This program is distributed in the hope that it will be useful,
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
   GNU General Public License for more details.
14
15
   You should have received a copy of the GNU General Public License
16
   along with this program; if not, write to the Free Software
17
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18
   02110-1301 USA
19
*/
20
21
#include "igraph_memory.h"
22
#include "igraph_error.h"
23
24
#include "io/gml-tree.h"
25
26
#include <string.h>
27
28
igraph_error_t igraph_gml_tree_init_integer(igraph_gml_tree_t *t,
29
                                            const char *name,
30
                                            igraph_int_t line,
31
8.23M
                                            igraph_int_t value) {
32
33
8.23M
    igraph_int_t *p;
34
35
8.23M
    IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->names, 1);
36
8.23M
    IGRAPH_VECTOR_CHAR_INIT_FINALLY(&t->types, 1);
37
8.23M
    IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->children, 1);
38
8.23M
    IGRAPH_VECTOR_INT_INIT_FINALLY(&t->lines, 1);
39
40
    /* names */
41
8.23M
    VECTOR(t->names)[0] = (void*) name;
42
43
    /* line number */
44
8.23M
    VECTOR(t->lines)[0] = line;
45
46
    /* types */
47
8.23M
    VECTOR(t->types)[0] = IGRAPH_I_GML_TREE_INTEGER;
48
49
    /* children */
50
8.23M
    p = IGRAPH_CALLOC(1, igraph_int_t);
51
8.23M
    IGRAPH_CHECK_OOM(p, "Cannot create integer GML tree node.");
52
8.23M
    *p = value;
53
8.23M
    VECTOR(t->children)[0] = p;
54
55
8.23M
    IGRAPH_FINALLY_CLEAN(4);
56
8.23M
    return IGRAPH_SUCCESS;
57
8.23M
}
58
59
igraph_error_t igraph_gml_tree_init_real(igraph_gml_tree_t *t,
60
                                         const char *name,
61
                                         igraph_int_t line,
62
126k
                                         igraph_real_t value) {
63
64
126k
    igraph_real_t *p;
65
66
126k
    IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->names, 1);
67
126k
    IGRAPH_VECTOR_CHAR_INIT_FINALLY(&t->types, 1);
68
126k
    IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->children, 1);
69
126k
    IGRAPH_VECTOR_INT_INIT_FINALLY(&t->lines, 1);
70
71
    /* names */
72
126k
    VECTOR(t->names)[0] = (void*) name;
73
74
    /* line number */
75
126k
    VECTOR(t->lines)[0] = line;
76
77
    /* types */
78
126k
    VECTOR(t->types)[0] = IGRAPH_I_GML_TREE_REAL;
79
80
    /* children */
81
126k
    p = IGRAPH_CALLOC(1, igraph_real_t);
82
126k
    IGRAPH_CHECK_OOM(p, "Cannot create real GML tree node.");
83
126k
    *p = value;
84
126k
    VECTOR(t->children)[0] = p;
85
86
126k
    IGRAPH_FINALLY_CLEAN(4);
87
126k
    return IGRAPH_SUCCESS;
88
126k
}
89
90
igraph_error_t igraph_gml_tree_init_string(igraph_gml_tree_t *t,
91
                                           const char *name,
92
                                           igraph_int_t line,
93
4.31M
                                           const char *value) {
94
95
4.31M
    IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->names, 1);
96
4.31M
    IGRAPH_VECTOR_CHAR_INIT_FINALLY(&t->types, 1);
97
4.31M
    IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->children, 1);
98
4.31M
    IGRAPH_VECTOR_INT_INIT_FINALLY(&t->lines, 1);
99
100
    /* names */
101
4.31M
    VECTOR(t->names)[0] = (void*) name;
102
103
    /* line number */
104
4.31M
    VECTOR(t->lines)[0] = line;
105
106
    /* types */
107
4.31M
    VECTOR(t->types)[0] = IGRAPH_I_GML_TREE_STRING;
108
109
    /* children */
110
4.31M
    VECTOR(t->children)[0] = (void*) value;
111
112
4.31M
    IGRAPH_FINALLY_CLEAN(4);
113
4.31M
    return IGRAPH_SUCCESS;
114
4.31M
}
115
116
igraph_error_t igraph_gml_tree_init_tree(igraph_gml_tree_t *t,
117
                                         const char *name,
118
                                         igraph_int_t line,
119
12.7M
                                         igraph_gml_tree_t *value) {
120
121
12.7M
    IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->names, 1);
122
12.7M
    IGRAPH_VECTOR_CHAR_INIT_FINALLY(&t->types, 1);
123
12.7M
    IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->children, 1);
124
12.7M
    IGRAPH_VECTOR_INT_INIT_FINALLY(&t->lines, 1);
125
126
    /* names */
127
12.7M
    VECTOR(t->names)[0] = (void*) name;
128
129
    /* line number */
130
12.7M
    VECTOR(t->lines)[0] = line;
131
132
    /* types */
133
12.7M
    VECTOR(t->types)[0] = IGRAPH_I_GML_TREE_TREE;
134
135
    /* children */
136
12.7M
    VECTOR(t->children)[0] = value;
137
138
12.7M
    IGRAPH_FINALLY_CLEAN(4);
139
12.7M
    return IGRAPH_SUCCESS;
140
141
12.7M
}
142
143
8.27M
igraph_error_t igraph_gml_tree_init_empty(igraph_gml_tree_t *t) {
144
8.27M
    IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->names, 0);
145
8.27M
    IGRAPH_VECTOR_CHAR_INIT_FINALLY(&t->types, 0);
146
8.27M
    IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->children, 0);
147
8.27M
    IGRAPH_VECTOR_INT_INIT_FINALLY(&t->lines, 0);
148
8.27M
    IGRAPH_FINALLY_CLEAN(4);
149
8.27M
    return IGRAPH_SUCCESS;
150
8.27M
}
151
152
/* merge is destructive, the _second_ tree is destroyed */
153
20.9M
igraph_error_t igraph_gml_tree_mergedest(igraph_gml_tree_t *t1, igraph_gml_tree_t *t2) {
154
20.9M
    igraph_int_t i, n = igraph_vector_ptr_size(&t2->children);
155
156
41.8M
    for (i = 0; i < n; i++) {
157
20.9M
        IGRAPH_CHECK(igraph_vector_ptr_push_back(&t1->names, VECTOR(t2->names)[i]));
158
20.9M
        IGRAPH_CHECK(igraph_vector_char_push_back(&t1->types, VECTOR(t2->types)[i]));
159
20.9M
        IGRAPH_CHECK(igraph_vector_ptr_push_back(&t1->children, VECTOR(t2->children)[i]));
160
20.9M
        IGRAPH_CHECK(igraph_vector_int_push_back(&t1->lines, VECTOR(t2->lines)[i]));
161
20.9M
    }
162
163
20.9M
    igraph_vector_ptr_destroy(&t2->names);
164
20.9M
    igraph_vector_char_destroy(&t2->types);
165
20.9M
    igraph_vector_ptr_destroy(&t2->children);
166
20.9M
    igraph_vector_int_destroy(&t2->lines);
167
168
20.9M
    return IGRAPH_SUCCESS;
169
20.9M
}
170
171
12.8M
void igraph_gml_tree_destroy(igraph_gml_tree_t *t) {
172
173
12.8M
    igraph_int_t i, n = igraph_vector_ptr_size(&t->children);
174
38.2M
    for (i = 0; i < n; i++) {
175
25.4M
        igraph_i_gml_tree_type_t type = (igraph_i_gml_tree_type_t) VECTOR(t->types)[i];
176
25.4M
        switch (type) {
177
12.7M
        case IGRAPH_I_GML_TREE_TREE:
178
12.7M
            igraph_gml_tree_destroy(VECTOR(t->children)[i]);
179
12.7M
            IGRAPH_FREE(VECTOR(t->names)[i]);
180
12.7M
            break;
181
8.23M
        case IGRAPH_I_GML_TREE_INTEGER:
182
8.23M
            IGRAPH_FREE(VECTOR(t->children)[i]);
183
8.23M
            IGRAPH_FREE(VECTOR(t->names)[i]);
184
8.23M
            break;
185
126k
        case IGRAPH_I_GML_TREE_REAL:
186
126k
            IGRAPH_FREE(VECTOR(t->children)[i]);
187
126k
            IGRAPH_FREE(VECTOR(t->names)[i]);
188
126k
            break;
189
4.31M
        case IGRAPH_I_GML_TREE_STRING:
190
4.31M
            IGRAPH_FREE(VECTOR(t->children)[i]);
191
4.31M
            IGRAPH_FREE(VECTOR(t->names)[i]);
192
4.31M
            break;
193
0
        case IGRAPH_I_GML_TREE_DELETED:
194
0
            break;
195
25.4M
        }
196
25.4M
    }
197
12.8M
    igraph_vector_ptr_destroy(&t->names);
198
12.8M
    igraph_vector_char_destroy(&t->types);
199
12.8M
    igraph_vector_ptr_destroy(&t->children);
200
12.8M
    igraph_vector_int_destroy(&t->lines);
201
12.8M
    IGRAPH_FREE(t);
202
12.8M
}
203
204
68.8M
igraph_int_t igraph_gml_tree_length(const igraph_gml_tree_t *t) {
205
68.8M
    return igraph_vector_ptr_size(&t->names);
206
68.8M
}
207
208
igraph_int_t igraph_gml_tree_find(
209
    const igraph_gml_tree_t *t, const char *name, igraph_int_t from
210
11.3M
) {
211
11.3M
    igraph_int_t size = igraph_vector_ptr_size(&t->names);
212
15.6M
    while ( from < size && (! VECTOR(t->names)[from] ||
213
9.03M
                            strcmp(VECTOR(t->names)[from], name)) ) {
214
4.23M
        from++;
215
4.23M
    }
216
217
11.3M
    if (from == size) {
218
6.57M
        from = -1;
219
6.57M
    }
220
11.3M
    return from;
221
11.3M
}
222
223
igraph_int_t igraph_gml_tree_findback(
224
    const igraph_gml_tree_t *t, const char *name, igraph_int_t from
225
0
) {
226
0
    while ( from >= 0 && (! VECTOR(t->names)[from] ||
227
0
                          strcmp(VECTOR(t->names)[from], name)) ) {
228
0
        from--;
229
0
    }
230
231
0
    return from;
232
0
}
233
234
34.3M
igraph_i_gml_tree_type_t igraph_gml_tree_type(const igraph_gml_tree_t *t, igraph_int_t pos) {
235
34.3M
    return (igraph_i_gml_tree_type_t) VECTOR(t->types)[pos];
236
34.3M
}
237
238
47.4M
const char *igraph_gml_tree_name(const igraph_gml_tree_t *t, igraph_int_t pos) {
239
47.4M
    return VECTOR(t->names)[pos];
240
47.4M
}
241
242
9.52k
igraph_int_t igraph_gml_tree_line(const igraph_gml_tree_t *t, igraph_int_t pos) {
243
9.52k
    return VECTOR(t->lines)[pos];
244
9.52k
}
245
246
igraph_int_t igraph_gml_tree_get_integer(const igraph_gml_tree_t *t,
247
14.3M
                                             igraph_int_t pos) {
248
14.3M
    igraph_int_t *i = VECTOR(t->children)[pos];
249
14.3M
    return *i;
250
14.3M
}
251
252
igraph_real_t igraph_gml_tree_get_real(const igraph_gml_tree_t *t,
253
123k
                                       igraph_int_t pos) {
254
123k
    igraph_real_t *d = VECTOR(t->children)[pos];
255
123k
    return *d;
256
123k
}
257
258
const char *igraph_gml_tree_get_string(const igraph_gml_tree_t *t,
259
3.85M
                                       igraph_int_t pos) {
260
3.85M
    const char *s = VECTOR(t->children)[pos];
261
3.85M
    return s;
262
3.85M
}
263
264
igraph_gml_tree_t *igraph_gml_tree_get_tree(const igraph_gml_tree_t *t,
265
21.4M
                                            igraph_int_t pos) {
266
21.4M
    igraph_gml_tree_t *tree = VECTOR(t->children)[pos];
267
21.4M
    return tree;
268
21.4M
}
269
270
0
void igraph_gml_tree_delete(igraph_gml_tree_t *t, igraph_int_t pos) {
271
0
    if (VECTOR(t->types)[pos] == IGRAPH_I_GML_TREE_TREE) {
272
0
        igraph_gml_tree_destroy(VECTOR(t->children)[pos]);
273
0
    }
274
0
    IGRAPH_FREE(VECTOR(t->names)[pos]);
275
0
    IGRAPH_FREE(VECTOR(t->children)[pos]);
276
0
    VECTOR(t->children)[pos] = 0;
277
0
    VECTOR(t->names)[pos] = 0;
278
0
    VECTOR(t->types)[pos] = IGRAPH_I_GML_TREE_DELETED;
279
0
}