diff options
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/plugins/import/imp_vrml2/imp_vrml_read.c')
-rw-r--r-- | src/others/mimesh/libg3d-0.0.8/plugins/import/imp_vrml2/imp_vrml_read.c | 647 |
1 files changed, 647 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_vrml2/imp_vrml_read.c b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_vrml2/imp_vrml_read.c new file mode 100644 index 0000000..580c5cd --- /dev/null +++ b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_vrml2/imp_vrml_read.c | |||
@@ -0,0 +1,647 @@ | |||
1 | /* $Id$ */ | ||
2 | |||
3 | /* | ||
4 | libg3d - 3D object loading library | ||
5 | |||
6 | Copyright (C) 2005-2009 Markus Dahms <mad@automagically.de> | ||
7 | |||
8 | This library is free software; you can redistribute it and/or | ||
9 | modify it under the terms of the GNU Lesser General Public | ||
10 | License as published by the Free Software Foundation; either | ||
11 | version 2.1 of the License, or (at your option) any later version. | ||
12 | |||
13 | This library is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | Lesser General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU Lesser General Public | ||
19 | License along with this library; if not, write to the Free Software | ||
20 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
21 | */ | ||
22 | #include <string.h> | ||
23 | #include <stdlib.h> | ||
24 | |||
25 | #include "imp_vrml_types.h" | ||
26 | #include "imp_vrml_read.h" | ||
27 | |||
28 | #include "imp_vrml2_nodes.h" | ||
29 | #include "imp_vrml2_types.h" | ||
30 | |||
31 | gboolean vrml_read_check_buffer(VrmlReader *reader) | ||
32 | { | ||
33 | if(reader->bufsize > 0) | ||
34 | return TRUE; | ||
35 | if(g3d_stream_eof(reader->stream)) | ||
36 | return FALSE; | ||
37 | memset(reader->buffer, '\0', reader->max_bufsize); | ||
38 | g3d_stream_read_line(reader->stream, reader->buffer, | ||
39 | reader->max_bufsize - 1); | ||
40 | reader->line ++; | ||
41 | reader->bufsize = strlen(reader->buffer); | ||
42 | reader->bufp = reader->buffer; | ||
43 | return (reader->bufsize > 0); | ||
44 | } | ||
45 | |||
46 | gboolean vrml_read_skip_ws(VrmlReader *reader) | ||
47 | { | ||
48 | if(!vrml_read_check_buffer(reader)) | ||
49 | return FALSE; | ||
50 | while(g_ascii_isspace(*(reader->bufp))) { | ||
51 | vrml_read_dec(reader); | ||
52 | if(!vrml_read_check_buffer(reader)) | ||
53 | return FALSE; | ||
54 | } | ||
55 | return TRUE; | ||
56 | } | ||
57 | |||
58 | gchar *vrml_read_token(VrmlReader *reader) | ||
59 | { | ||
60 | gchar *s = NULL; | ||
61 | gsize len = 0; | ||
62 | |||
63 | if(!vrml_read_skip_ws(reader)) | ||
64 | return NULL; | ||
65 | while(vrml_read_check_buffer(reader) && | ||
66 | !g_ascii_isspace(*(reader->bufp)) && | ||
67 | (*(reader->bufp) != ',')) { | ||
68 | len ++; | ||
69 | s = g_realloc(s, (len + 1) * sizeof(gchar)); | ||
70 | s[len - 1] = *(reader->bufp); | ||
71 | s[len - 0] = '\0'; | ||
72 | vrml_read_dec(reader); | ||
73 | } | ||
74 | #if DEBUG > 3 | ||
75 | g_debug("token: %s", s); | ||
76 | #endif | ||
77 | return s; | ||
78 | } | ||
79 | |||
80 | gchar *vrml_read_numeric(VrmlReader *reader) | ||
81 | { | ||
82 | gchar *s = NULL; | ||
83 | gsize len = 0; | ||
84 | gboolean first = TRUE; | ||
85 | |||
86 | if(!vrml_read_skip_ws(reader)) | ||
87 | return NULL; | ||
88 | while(vrml_read_check_buffer(reader) && | ||
89 | (g_ascii_isdigit(*(reader->bufp)) || | ||
90 | strchr(".-e", *(reader->bufp)))) { | ||
91 | |||
92 | if(first) { | ||
93 | if(*(reader->bufp) == 'e') | ||
94 | return NULL; | ||
95 | first = FALSE; | ||
96 | } | ||
97 | |||
98 | len ++; | ||
99 | s = g_realloc(s, (len + 1) * sizeof(gchar)); | ||
100 | s[len - 1] = *(reader->bufp); | ||
101 | s[len - 0] = '\0'; | ||
102 | vrml_read_dec(reader); | ||
103 | } | ||
104 | #if DEBUG > 3 | ||
105 | g_debug("numeric: %s", s); | ||
106 | #endif | ||
107 | return s; | ||
108 | } | ||
109 | |||
110 | gchar *vrml_read_id(VrmlReader *reader) | ||
111 | { | ||
112 | gchar *buf; | ||
113 | gsize bufsize; | ||
114 | |||
115 | if(!vrml_read_skip_ws(reader)) | ||
116 | return NULL; | ||
117 | if(!vrml_read_check_buffer(reader)) | ||
118 | return NULL; | ||
119 | bufsize = 2; | ||
120 | buf = g_new(gchar, 2 * sizeof(gchar)); | ||
121 | buf[0] = *(reader->bufp); | ||
122 | buf[1] = '\0'; | ||
123 | if(!(g_ascii_isalpha(buf[0]) || strchr("_", buf[0]))) { | ||
124 | g_free(buf); | ||
125 | return NULL; | ||
126 | } | ||
127 | vrml_read_dec(reader); | ||
128 | if(!vrml_read_check_buffer(reader)) | ||
129 | return buf; | ||
130 | while(g_ascii_isalnum(*(reader->bufp)) || strchr("_.", *(reader->bufp))) { | ||
131 | bufsize ++; | ||
132 | buf = g_realloc(buf, bufsize * sizeof(gchar)); | ||
133 | buf[bufsize - 2] = *(reader->bufp); | ||
134 | buf[bufsize - 1] = '\0'; | ||
135 | vrml_read_dec(reader); | ||
136 | if(!vrml_read_check_buffer(reader)) | ||
137 | return buf; | ||
138 | } | ||
139 | return buf; | ||
140 | } | ||
141 | |||
142 | gchar *vrml_read_string(VrmlReader *reader) | ||
143 | { | ||
144 | gchar *buf = NULL; | ||
145 | gsize bufsize = 0; | ||
146 | |||
147 | if(!vrml_read_check_buffer(reader)) | ||
148 | return NULL; | ||
149 | while(*(reader->bufp) != '"') { | ||
150 | bufsize ++; | ||
151 | buf = g_realloc(buf, (bufsize + 1) * sizeof(gchar)); | ||
152 | buf[bufsize - 1] = *(reader->bufp); | ||
153 | buf[bufsize] = '\0'; | ||
154 | vrml_read_dec(reader); | ||
155 | if(!vrml_read_check_buffer(reader)) | ||
156 | return buf; | ||
157 | } | ||
158 | vrml_read_dec(reader); | ||
159 | return buf; | ||
160 | } | ||
161 | |||
162 | gboolean vrml_read_skip_unknown(VrmlReader *reader) | ||
163 | { | ||
164 | gchar c, *s; | ||
165 | #if DEBUG > 0 | ||
166 | g_debug("vrml: skipping unknown stuff in line %d", reader->line); | ||
167 | #endif | ||
168 | |||
169 | while(vrml_read_check_buffer(reader)) { | ||
170 | c = *(reader->bufp); | ||
171 | vrml_read_dec(reader); | ||
172 | switch(c) { | ||
173 | case '"': | ||
174 | s = vrml_read_string(reader); | ||
175 | if(s) { | ||
176 | g_debug("found string '%s'", s); | ||
177 | g_free(s); | ||
178 | } | ||
179 | break; | ||
180 | case '{': | ||
181 | case '[': | ||
182 | vrml_read_skip_unknown(reader); | ||
183 | break; | ||
184 | case '}': | ||
185 | case ']': | ||
186 | return TRUE; | ||
187 | break; | ||
188 | default: | ||
189 | break; | ||
190 | } | ||
191 | } | ||
192 | return FALSE; | ||
193 | } | ||
194 | |||
195 | gchar *vrml_read_nodeid(VrmlReader *reader) | ||
196 | { | ||
197 | gchar *id; | ||
198 | id = vrml_read_id(reader); | ||
199 | if(id == NULL) | ||
200 | return NULL; | ||
201 | if(!g_ascii_isupper(id[0])) { | ||
202 | g_free(id); | ||
203 | return NULL; | ||
204 | } | ||
205 | return id; | ||
206 | } | ||
207 | |||
208 | gboolean vrml_read_expect(VrmlReader *reader, const gchar c) | ||
209 | { | ||
210 | gchar b; | ||
211 | if(!vrml_read_skip_ws(reader)) | ||
212 | return FALSE; | ||
213 | if(!vrml_read_check_buffer(reader)) | ||
214 | return FALSE; | ||
215 | b = *(reader->bufp); | ||
216 | vrml_read_dec(reader); | ||
217 | return (b == c); | ||
218 | } | ||
219 | |||
220 | gboolean vrml_read_list(VrmlReader *reader, vrml_read_list_item_callback cb, | ||
221 | gpointer user_data) | ||
222 | { | ||
223 | if(!vrml_read_expect(reader, '[')) | ||
224 | return FALSE; | ||
225 | |||
226 | while(vrml_read_skip_ws(reader)) { | ||
227 | if(*(reader->bufp) == ']') { | ||
228 | vrml_read_dec(reader); | ||
229 | return TRUE; | ||
230 | } | ||
231 | if(!cb(reader, user_data)) | ||
232 | return FALSE; | ||
233 | |||
234 | if(!vrml_read_skip_ws(reader)) | ||
235 | return FALSE; | ||
236 | if(*(reader->bufp) == ',') | ||
237 | vrml_read_dec(reader); | ||
238 | } | ||
239 | /* should not be reached */ | ||
240 | return vrml_read_expect(reader, ']'); | ||
241 | } | ||
242 | |||
243 | /*****************************************************************************/ | ||
244 | |||
245 | static VrmlObject *vrml_lookup_object(VrmlReader *reader, const gchar *id) | ||
246 | { | ||
247 | VrmlObject *object; | ||
248 | |||
249 | object = g_new0(VrmlObject, 1); | ||
250 | object->defid = g_strdup(id); | ||
251 | object->name = g_strdup("object from library"); | ||
252 | |||
253 | return object; | ||
254 | } | ||
255 | |||
256 | static gboolean vrml_read_float_n(VrmlReader *reader, G3DFloat *a, guint32 n) | ||
257 | { | ||
258 | gint i; | ||
259 | gchar *s; | ||
260 | |||
261 | for(i = 0; i < n; i ++) { | ||
262 | s = vrml_read_numeric(reader); | ||
263 | if(s) { | ||
264 | a[i] = atof(s); | ||
265 | g_free(s); | ||
266 | } else | ||
267 | return FALSE; | ||
268 | } | ||
269 | return TRUE; | ||
270 | } | ||
271 | |||
272 | static gboolean vrml_read_token_n(VrmlReader *reader, VrmlProperty *property, | ||
273 | guint32 n) | ||
274 | { | ||
275 | gchar *token; | ||
276 | gint32 i; | ||
277 | |||
278 | for(i = 0; i < n; i ++) { | ||
279 | token = vrml_read_token(reader); | ||
280 | #if DEBUG > 2 | ||
281 | g_debug("Token: %s", token); | ||
282 | #endif | ||
283 | g_free(token); | ||
284 | } | ||
285 | |||
286 | return TRUE; | ||
287 | } | ||
288 | |||
289 | /* property list callbacks */ | ||
290 | |||
291 | gboolean vrml_read_list_object_cb(VrmlReader *reader, gpointer data) | ||
292 | { | ||
293 | VrmlProperty *property = data; | ||
294 | |||
295 | property->n_items ++; | ||
296 | property->v_object = g_realloc(property->v_object, | ||
297 | property->n_items * sizeof(VrmlObject *)); | ||
298 | property->v_object[property->n_items - 1] = | ||
299 | vrml_read_object(reader, property->level + 1); | ||
300 | return (property->v_object[property->n_items - 1] != NULL); | ||
301 | } | ||
302 | |||
303 | gboolean vrml_read_list_string_cb(VrmlReader *reader, gpointer data) | ||
304 | { | ||
305 | VrmlProperty *property = data; | ||
306 | |||
307 | if(!vrml_read_expect(reader, '"')) | ||
308 | return FALSE; | ||
309 | |||
310 | property->n_items ++; | ||
311 | property->v_str = g_realloc(property->v_str, | ||
312 | property->n_items * sizeof(gchar *)); | ||
313 | property->v_str[property->n_items - 1] = | ||
314 | vrml_read_string(reader); | ||
315 | return TRUE; | ||
316 | } | ||
317 | |||
318 | gboolean vrml_read_list_int_cb(VrmlReader *reader, gpointer data) | ||
319 | { | ||
320 | VrmlProperty *property = data; | ||
321 | gchar *s; | ||
322 | |||
323 | s = vrml_read_numeric(reader); | ||
324 | if(s) { | ||
325 | property->n_items ++; | ||
326 | property->v_int = g_realloc(property->v_int, | ||
327 | property->n_items * sizeof(gint32)); | ||
328 | property->v_int[property->n_items - 1] = atoi(s); | ||
329 | g_free(s); | ||
330 | return TRUE; | ||
331 | } | ||
332 | return FALSE; | ||
333 | } | ||
334 | |||
335 | gboolean vrml_read_list_float_cb(VrmlReader *reader, gpointer data) | ||
336 | { | ||
337 | VrmlProperty *property = data; | ||
338 | |||
339 | property->n_items ++; | ||
340 | property->v_float = g_realloc(property->v_float, | ||
341 | property->n_items * sizeof(G3DFloat)); | ||
342 | return vrml_read_float_n(reader, | ||
343 | property->v_float + (property->n_items - 1), 1); | ||
344 | } | ||
345 | |||
346 | gboolean vrml_read_list_float2_cb(VrmlReader *reader, gpointer data) | ||
347 | { | ||
348 | VrmlProperty *property = data; | ||
349 | |||
350 | property->n_items += 2; | ||
351 | property->v_float = g_realloc(property->v_float, | ||
352 | property->n_items * sizeof(G3DFloat)); | ||
353 | return vrml_read_float_n(reader, | ||
354 | property->v_float + (property->n_items - 2), 2); | ||
355 | } | ||
356 | |||
357 | gboolean vrml_read_list_float3_cb(VrmlReader *reader, gpointer data) | ||
358 | { | ||
359 | VrmlProperty *property = data; | ||
360 | |||
361 | property->n_items += 3; | ||
362 | property->v_float = g_realloc(property->v_float, | ||
363 | property->n_items * sizeof(G3DFloat)); | ||
364 | return vrml_read_float_n(reader, | ||
365 | property->v_float + (property->n_items - 3), 3); | ||
366 | } | ||
367 | |||
368 | gboolean vrml_read_list_float4_cb(VrmlReader *reader, gpointer data) | ||
369 | { | ||
370 | VrmlProperty *property = data; | ||
371 | |||
372 | property->n_items += 4; | ||
373 | property->v_float = g_realloc(property->v_float, | ||
374 | property->n_items * sizeof(G3DFloat)); | ||
375 | return vrml_read_float_n(reader, | ||
376 | property->v_float + (property->n_items - 4), 4); | ||
377 | } | ||
378 | |||
379 | gboolean vrml_read_list_floatx_cb(VrmlReader *reader, gpointer data) | ||
380 | { | ||
381 | VrmlProperty *property = data; | ||
382 | gchar *s; | ||
383 | |||
384 | s = vrml_read_numeric(reader); | ||
385 | while(s) { | ||
386 | property->n_items ++; | ||
387 | property->v_float = g_realloc(property->v_float, | ||
388 | property->n_items * sizeof(G3DFloat)); | ||
389 | property->v_float[property->n_items - 1] = atof(s); | ||
390 | g_free(s); | ||
391 | s = vrml_read_numeric(reader); | ||
392 | } | ||
393 | return TRUE; | ||
394 | } | ||
395 | |||
396 | /* property reader */ | ||
397 | |||
398 | VrmlProperty *vrml_read_property(VrmlReader *reader, guint32 level) | ||
399 | { | ||
400 | VrmlProperty *property; | ||
401 | VrmlTypeDef *type = NULL; | ||
402 | gint i; | ||
403 | gchar *id, *s; | ||
404 | |||
405 | id = vrml_read_id(reader); | ||
406 | if(id == NULL) | ||
407 | return NULL; | ||
408 | |||
409 | /* look up object */ | ||
410 | for(i = 0; vrml2_types[i].name != NULL; i ++) | ||
411 | if(strcmp(id, vrml2_types[i].name) == 0) { | ||
412 | type = &(vrml2_types[i]); | ||
413 | break; | ||
414 | } | ||
415 | if(type == NULL) { | ||
416 | g_warning("VRML: unknown type %s in line %d", id, reader->line); | ||
417 | return NULL; | ||
418 | } | ||
419 | property = g_new0(VrmlProperty, 1); | ||
420 | property->name = id; | ||
421 | if(type->detect != NULL) | ||
422 | property->id = type->detect(reader); | ||
423 | else | ||
424 | property->id = type->id; | ||
425 | property->level = level; | ||
426 | |||
427 | #if DEBUG > 0 | ||
428 | g_debug("\\%sproperty '%s', type %d", | ||
429 | vrml_read_padding + strlen(vrml_read_padding) - 1 - level, | ||
430 | id, property->id); | ||
431 | #endif | ||
432 | |||
433 | switch(property->id) { | ||
434 | case T_OBJECT: | ||
435 | property->n_items = 1; | ||
436 | property->v_object = g_new0(VrmlObject *, 1); | ||
437 | property->v_object[0] = vrml_read_object(reader, level + 1); | ||
438 | break; | ||
439 | case T_TOKEN2: | ||
440 | vrml_read_token_n(reader, property, 2); | ||
441 | break; | ||
442 | case T_TOKEN3: | ||
443 | vrml_read_token_n(reader, property, 3); | ||
444 | break; | ||
445 | case T_STRING: | ||
446 | property->n_items = 1; | ||
447 | if(!vrml_read_expect(reader, '"')) | ||
448 | return FALSE; | ||
449 | property->v_str = g_new0(gchar *, 1); | ||
450 | property->v_str[0] = vrml_read_string(reader); | ||
451 | break; | ||
452 | case T_BOOLEAN: | ||
453 | s = vrml_read_token(reader); | ||
454 | if(s) { | ||
455 | if(strcmp(s, "TRUE") == 0) | ||
456 | property->v_boolean = TRUE; | ||
457 | g_free(s); | ||
458 | } | ||
459 | break; | ||
460 | case T_INT: | ||
461 | s = vrml_read_numeric(reader); | ||
462 | if(s) { | ||
463 | property->n_items = 1; | ||
464 | property->v_int = g_new0(gint32, 1); | ||
465 | property->v_int[0] = atoi(s); | ||
466 | g_free(s); | ||
467 | } | ||
468 | break; | ||
469 | case T_FLOAT: | ||
470 | property->n_items = 1; | ||
471 | property->v_float = g_new0(G3DFloat, 1); | ||
472 | vrml_read_float_n(reader, property->v_float, 1); | ||
473 | break; | ||
474 | case T_FLOAT2: | ||
475 | property->n_items = 2; | ||
476 | property->v_float = g_new0(G3DFloat, 2); | ||
477 | vrml_read_float_n(reader, property->v_float, 2); | ||
478 | break; | ||
479 | case T_FLOAT3: | ||
480 | property->n_items = 3; | ||
481 | property->v_float = g_new0(G3DFloat, 3); | ||
482 | vrml_read_float_n(reader, property->v_float, 3); | ||
483 | break; | ||
484 | case T_FLOAT4: | ||
485 | property->n_items = 4; | ||
486 | property->v_float = g_new0(G3DFloat, 4); | ||
487 | vrml_read_float_n(reader, property->v_float, 4); | ||
488 | break; | ||
489 | case T_FLOAT_X: | ||
490 | s = vrml_read_numeric(reader); | ||
491 | while(s) { | ||
492 | property->n_items ++; | ||
493 | property->v_float = g_realloc(property->v_float, | ||
494 | property->n_items * sizeof(G3DFloat)); | ||
495 | property->v_float[property->n_items - 1] = atof(s); | ||
496 | #if DEBUG > 2 | ||
497 | g_debug("T_FLOAT_X: %i: %.2f", property->n_items, | ||
498 | property->v_float[property->n_items - 1]); | ||
499 | #endif | ||
500 | g_free(s); | ||
501 | s = vrml_read_numeric(reader); | ||
502 | } | ||
503 | break; | ||
504 | case T_LIST_OBJECT: | ||
505 | vrml_read_list(reader, vrml_read_list_object_cb, property); | ||
506 | break; | ||
507 | case T_LIST_STRING: | ||
508 | vrml_read_list(reader, vrml_read_list_string_cb, property); | ||
509 | break; | ||
510 | case T_LIST_INT: | ||
511 | vrml_read_list(reader, vrml_read_list_int_cb, property); | ||
512 | break; | ||
513 | case T_LIST_FLOAT: | ||
514 | vrml_read_list(reader, vrml_read_list_float_cb, property); | ||
515 | break; | ||
516 | case T_LIST_FLOAT2: | ||
517 | vrml_read_list(reader, vrml_read_list_float2_cb, property); | ||
518 | break; | ||
519 | case T_LIST_FLOAT3: | ||
520 | vrml_read_list(reader, vrml_read_list_float3_cb, property); | ||
521 | break; | ||
522 | case T_LIST_FLOAT4: | ||
523 | vrml_read_list(reader, vrml_read_list_float4_cb, property); | ||
524 | break; | ||
525 | case T_LIST_FLOAT_X: | ||
526 | vrml_read_list(reader, vrml_read_list_floatx_cb, property); | ||
527 | break; | ||
528 | |||
529 | default: | ||
530 | g_free(property->name); | ||
531 | g_free(property); | ||
532 | return NULL; | ||
533 | break; | ||
534 | } | ||
535 | |||
536 | return property; | ||
537 | } | ||
538 | |||
539 | static VrmlObject *vrml_read_route_object(VrmlReader *reader, guint32 level) | ||
540 | { | ||
541 | VrmlObject *object; | ||
542 | gchar *id; | ||
543 | #if DEBUG > 2 | ||
544 | g_debug("ROUTE object"); | ||
545 | #endif | ||
546 | id = vrml_read_id(reader); /* source */ | ||
547 | if(id == NULL) { | ||
548 | g_warning("ROUTE: could not get source"); | ||
549 | return NULL; | ||
550 | } | ||
551 | g_free(id); | ||
552 | id = vrml_read_id(reader); /* TO */ | ||
553 | if(id == NULL) { | ||
554 | g_warning("ROUTE: could not get TO"); | ||
555 | return NULL; | ||
556 | } | ||
557 | g_free(id); | ||
558 | id = vrml_read_id(reader); /* destination */ | ||
559 | if(id == NULL) { | ||
560 | g_warning("ROUTE: could not get destination"); | ||
561 | return NULL; | ||
562 | } | ||
563 | g_free(id); | ||
564 | object = g_new0(VrmlObject, 1); | ||
565 | object->name = g_strdup("ROUTE object"); | ||
566 | object->level = level; | ||
567 | return object; | ||
568 | } | ||
569 | |||
570 | VrmlObject *vrml_read_object(VrmlReader *reader, guint32 level) | ||
571 | { | ||
572 | VrmlObject *object; | ||
573 | VrmlProperty *property; | ||
574 | gchar *id, *defid = NULL; | ||
575 | gboolean define = FALSE; | ||
576 | |||
577 | id = vrml_read_id(reader); | ||
578 | if(id == NULL) | ||
579 | return NULL; | ||
580 | if(strcmp(id, "NULL") == 0) { | ||
581 | return NULL; | ||
582 | } else if(strcmp(id, "DEF") == 0) { | ||
583 | define = TRUE; | ||
584 | defid = vrml_read_id(reader); | ||
585 | if(defid == NULL) | ||
586 | return NULL; | ||
587 | id = vrml_read_id(reader); | ||
588 | if(id == NULL) | ||
589 | return NULL; | ||
590 | } else if(strcmp(id, "USE") == 0) { | ||
591 | defid = vrml_read_id(reader); | ||
592 | #if DEBUG > 2 | ||
593 | g_debug("looking up '%s'", defid); | ||
594 | #endif | ||
595 | return vrml_lookup_object(reader, defid); | ||
596 | } else if(strcmp(id, "ROUTE") == 0) { | ||
597 | return vrml_read_route_object(reader, level); | ||
598 | } | ||
599 | |||
600 | if(!vrml_read_expect(reader, '{')) { | ||
601 | g_warning("vrml_read_object: expected '{' in line %d", reader->line); | ||
602 | g_free(id); | ||
603 | if(defid) | ||
604 | g_free(defid); | ||
605 | return FALSE; | ||
606 | } | ||
607 | #if DEBUG > 0 | ||
608 | g_debug("\\%sobject '%s'", | ||
609 | vrml_read_padding + strlen(vrml_read_padding) - 1 - level, | ||
610 | id); | ||
611 | #endif | ||
612 | |||
613 | object = g_new0(VrmlObject, 1); | ||
614 | object->name = id; | ||
615 | object->defid = defid; | ||
616 | object->define = define; | ||
617 | object->level = level; | ||
618 | |||
619 | /* read properties */ | ||
620 | while(vrml_read_skip_ws(reader)) { | ||
621 | #if DEBUG > 2 | ||
622 | g_debug("O: '%c'", *(reader->bufp)); | ||
623 | #endif | ||
624 | if(*(reader->bufp) == '}') { | ||
625 | vrml_read_dec(reader); | ||
626 | return object; | ||
627 | } | ||
628 | property = vrml_read_property(reader, level + 1); | ||
629 | if(property != NULL) | ||
630 | object->properties = g_slist_append(object->properties, property); | ||
631 | else { | ||
632 | vrml_read_skip_unknown(reader); | ||
633 | return object; | ||
634 | } | ||
635 | } | ||
636 | vrml_read_expect(reader, '}'); | ||
637 | return object; | ||
638 | } | ||
639 | |||
640 | gboolean vrml_read_global(VrmlReader *reader) | ||
641 | { | ||
642 | while(vrml_read_skip_ws(reader)) { | ||
643 | if(!vrml_read_object(reader, 0)) | ||
644 | return FALSE; | ||
645 | } | ||
646 | return TRUE; | ||
647 | } | ||