Coverage Report

Created: 2025-11-14 06:33

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
3.00M
                                            igraph_int_t value) {
32
33
3.00M
    igraph_int_t *p;
34
35
3.00M
    IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->names, 1);
36
3.00M
    IGRAPH_VECTOR_CHAR_INIT_FINALLY(&t->types, 1);
37
3.00M
    IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->children, 1);
38
3.00M
    IGRAPH_VECTOR_INT_INIT_FINALLY(&t->lines, 1);
39
40
    /* names */
41
3.00M
    VECTOR(t->names)[0] = (void*) name;
42
43
    /* line number */
44
3.00M
    VECTOR(t->lines)[0] = line;
45
46
    /* types */
47
3.00M
    VECTOR(t->types)[0] = IGRAPH_I_GML_TREE_INTEGER;
48
49
    /* children */
50
3.00M
    p = IGRAPH_CALLOC(1, igraph_int_t);
51
3.00M
    IGRAPH_CHECK_OOM(p, "Cannot create integer GML tree node.");
52
3.00M
    *p = value;
53
3.00M
    VECTOR(t->children)[0] = p;
54
55
3.00M
    IGRAPH_FINALLY_CLEAN(4);
56
3.00M
    return IGRAPH_SUCCESS;
57
3.00M
}
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
5.49k
                                         igraph_real_t value) {
63
64
5.49k
    igraph_real_t *p;
65
66
5.49k
    IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->names, 1);
67
5.49k
    IGRAPH_VECTOR_CHAR_INIT_FINALLY(&t->types, 1);
68
5.49k
    IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->children, 1);
69
5.49k
    IGRAPH_VECTOR_INT_INIT_FINALLY(&t->lines, 1);
70
71
    /* names */
72
5.49k
    VECTOR(t->names)[0] = (void*) name;
73
74
    /* line number */
75
5.49k
    VECTOR(t->lines)[0] = line;
76
77
    /* types */
78
5.49k
    VECTOR(t->types)[0] = IGRAPH_I_GML_TREE_REAL;
79
80
    /* children */
81
5.49k
    p = IGRAPH_CALLOC(1, igraph_real_t);
82
5.49k
    IGRAPH_CHECK_OOM(p, "Cannot create real GML tree node.");
83
5.49k
    *p = value;
84
5.49k
    VECTOR(t->children)[0] = p;
85
86
5.49k
    IGRAPH_FINALLY_CLEAN(4);
87
5.49k
    return IGRAPH_SUCCESS;
88
5.49k
}
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
492k
                                           const char *value) {
94
95
492k
    IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->names, 1);
96
492k
    IGRAPH_VECTOR_CHAR_INIT_FINALLY(&t->types, 1);
97
492k
    IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->children, 1);
98
492k
    IGRAPH_VECTOR_INT_INIT_FINALLY(&t->lines, 1);
99
100
    /* names */
101
492k
    VECTOR(t->names)[0] = (void*) name;
102
103
    /* line number */
104
492k
    VECTOR(t->lines)[0] = line;
105
106
    /* types */
107
492k
    VECTOR(t->types)[0] = IGRAPH_I_GML_TREE_STRING;
108
109
    /* children */
110
492k
    VECTOR(t->children)[0] = (void*) value;
111
112
492k
    IGRAPH_FINALLY_CLEAN(4);
113
492k
    return IGRAPH_SUCCESS;
114
492k
}
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
3.92M
                                         igraph_gml_tree_t *value) {
120
121
3.92M
    IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->names, 1);
122
3.92M
    IGRAPH_VECTOR_CHAR_INIT_FINALLY(&t->types, 1);
123
3.92M
    IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->children, 1);
124
3.92M
    IGRAPH_VECTOR_INT_INIT_FINALLY(&t->lines, 1);
125
126
    /* names */
127
3.92M
    VECTOR(t->names)[0] = (void*) name;
128
129
    /* line number */
130
3.92M
    VECTOR(t->lines)[0] = line;
131
132
    /* types */
133
3.92M
    VECTOR(t->types)[0] = IGRAPH_I_GML_TREE_TREE;
134
135
    /* children */
136
3.92M
    VECTOR(t->children)[0] = value;
137
138
3.92M
    IGRAPH_FINALLY_CLEAN(4);
139
3.92M
    return IGRAPH_SUCCESS;
140
141
3.92M
}
142
143
3.65M
igraph_error_t igraph_gml_tree_init_empty(igraph_gml_tree_t *t) {
144
3.65M
    IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->names, 0);
145
3.65M
    IGRAPH_VECTOR_CHAR_INIT_FINALLY(&t->types, 0);
146
3.65M
    IGRAPH_VECTOR_PTR_INIT_FINALLY(&t->children, 0);
147
3.65M
    IGRAPH_VECTOR_INT_INIT_FINALLY(&t->lines, 0);
148
3.65M
    IGRAPH_FINALLY_CLEAN(4);
149
3.65M
    return IGRAPH_SUCCESS;
150
3.65M
}
151
152
/* merge is destructive, the _second_ tree is destroyed */
153
7.15M
igraph_error_t igraph_gml_tree_mergedest(igraph_gml_tree_t *t1, igraph_gml_tree_t *t2) {
154
7.15M
    igraph_int_t i, n = igraph_vector_ptr_size(&t2->children);
155
156
14.3M
    for (i = 0; i < n; i++) {
157
7.15M
        IGRAPH_CHECK(igraph_vector_ptr_push_back(&t1->names, VECTOR(t2->names)[i]));
158
7.15M
        IGRAPH_CHECK(igraph_vector_char_push_back(&t1->types, VECTOR(t2->types)[i]));
159
7.15M
        IGRAPH_CHECK(igraph_vector_ptr_push_back(&t1->children, VECTOR(t2->children)[i]));
160
7.15M
        IGRAPH_CHECK(igraph_vector_int_push_back(&t1->lines, VECTOR(t2->lines)[i]));
161
7.15M
    }
162
163
7.15M
    igraph_vector_ptr_destroy(&t2->names);
164
7.15M
    igraph_vector_char_destroy(&t2->types);
165
7.15M
    igraph_vector_ptr_destroy(&t2->children);
166
7.15M
    igraph_vector_int_destroy(&t2->lines);
167
168
7.15M
    return IGRAPH_SUCCESS;
169
7.15M
}
170
171
3.92M
void igraph_gml_tree_destroy(igraph_gml_tree_t *t) {
172
173
3.92M
    igraph_int_t i, n = igraph_vector_ptr_size(&t->children);
174
11.3M
    for (i = 0; i < n; i++) {
175
7.42M
        igraph_i_gml_tree_type_t type = (igraph_i_gml_tree_type_t) VECTOR(t->types)[i];
176
7.42M
        switch (type) {
177
3.92M
        case IGRAPH_I_GML_TREE_TREE:
178
3.92M
            igraph_gml_tree_destroy(VECTOR(t->children)[i]);
179
3.92M
            IGRAPH_FREE(VECTOR(t->names)[i]);
180
3.92M
            break;
181
3.00M
        case IGRAPH_I_GML_TREE_INTEGER:
182
3.00M
            IGRAPH_FREE(VECTOR(t->children)[i]);
183
3.00M
            IGRAPH_FREE(VECTOR(t->names)[i]);
184
3.00M
            break;
185
5.49k
        case IGRAPH_I_GML_TREE_REAL:
186
5.49k
            IGRAPH_FREE(VECTOR(t->children)[i]);
187
5.49k
            IGRAPH_FREE(VECTOR(t->names)[i]);
188
5.49k
            break;
189
492k
        case IGRAPH_I_GML_TREE_STRING:
190
492k
            IGRAPH_FREE(VECTOR(t->children)[i]);
191
492k
            IGRAPH_FREE(VECTOR(t->names)[i]);
192
492k
            break;
193
0
        case IGRAPH_I_GML_TREE_DELETED:
194
0
            break;
195
7.42M
        }
196
7.42M
    }
197
3.92M
    igraph_vector_ptr_destroy(&t->names);
198
3.92M
    igraph_vector_char_destroy(&t->types);
199
3.92M
    igraph_vector_ptr_destroy(&t->children);
200
3.92M
    igraph_vector_int_destroy(&t->lines);
201
3.92M
    IGRAPH_FREE(t);
202
3.92M
}
203
204
18.9M
igraph_int_t igraph_gml_tree_length(const igraph_gml_tree_t *t) {
205
18.9M
    return igraph_vector_ptr_size(&t->names);
206
18.9M
}
207
208
igraph_int_t igraph_gml_tree_find(
209
    const igraph_gml_tree_t *t, const char *name, igraph_int_t from
210
3.26M
) {
211
3.26M
    igraph_int_t size = igraph_vector_ptr_size(&t->names);
212
6.11M
    while ( from < size && (! VECTOR(t->names)[from] ||
213
3.05M
                            strcmp(VECTOR(t->names)[from], name)) ) {
214
2.84M
        from++;
215
2.84M
    }
216
217
3.26M
    if (from == size) {
218
3.05M
        from = -1;
219
3.05M
    }
220
3.26M
    return from;
221
3.26M
}
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
8.94M
igraph_i_gml_tree_type_t igraph_gml_tree_type(const igraph_gml_tree_t *t, igraph_int_t pos) {
235
8.94M
    return (igraph_i_gml_tree_type_t) VECTOR(t->types)[pos];
236
8.94M
}
237
238
12.4M
const char *igraph_gml_tree_name(const igraph_gml_tree_t *t, igraph_int_t pos) {
239
12.4M
    return VECTOR(t->names)[pos];
240
12.4M
}
241
242
1.91k
igraph_int_t igraph_gml_tree_line(const igraph_gml_tree_t *t, igraph_int_t pos) {
243
1.91k
    return VECTOR(t->lines)[pos];
244
1.91k
}
245
246
igraph_int_t igraph_gml_tree_get_integer(const igraph_gml_tree_t *t,
247
2.67M
                                             igraph_int_t pos) {
248
2.67M
    igraph_int_t *i = VECTOR(t->children)[pos];
249
2.67M
    return *i;
250
2.67M
}
251
252
igraph_real_t igraph_gml_tree_get_real(const igraph_gml_tree_t *t,
253
3.83k
                                       igraph_int_t pos) {
254
3.83k
    igraph_real_t *d = VECTOR(t->children)[pos];
255
3.83k
    return *d;
256
3.83k
}
257
258
const char *igraph_gml_tree_get_string(const igraph_gml_tree_t *t,
259
68.5k
                                       igraph_int_t pos) {
260
68.5k
    const char *s = VECTOR(t->children)[pos];
261
68.5k
    return s;
262
68.5k
}
263
264
igraph_gml_tree_t *igraph_gml_tree_get_tree(const igraph_gml_tree_t *t,
265
6.45M
                                            igraph_int_t pos) {
266
6.45M
    igraph_gml_tree_t *tree = VECTOR(t->children)[pos];
267
6.45M
    return tree;
268
6.45M
}
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
}