Coverage Report

Created: 2025-11-11 06:59

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