/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 | } |