1 /***************************************************************************
2 begin : Thu Jul 02 2009
3 copyright : (C) 2018 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * Please see toplevel file COPYING for license details *
8 ***************************************************************************/
9
10 #ifdef HAVE_CONFIG_H
11 # include <config.h>
12 #endif
13
14
15 #include "tm_typemanager_p.h"
16
17 #include <gwenhywfar/debug.h>
18 #include <gwenhywfar/misc.h>
19 #include <gwenhywfar/directory.h>
20
21 #include <assert.h>
22 #include <ctype.h>
23
24
25
26 #define TM_TYPEMANAGER_XMLFLAGS (\
27 GWEN_XML_FLAGS_DEFAULT | \
28 GWEN_XML_FLAGS_HANDLE_HEADERS | \
29 GWEN_XML_FLAGS_HANDLE_OPEN_HTMLTAGS \
30 )
31
32
33
34
Typemaker2_TypeManager_new()35 TYPEMAKER2_TYPEMANAGER *Typemaker2_TypeManager_new()
36 {
37 TYPEMAKER2_TYPEMANAGER *tym;
38
39 GWEN_NEW_OBJECT(TYPEMAKER2_TYPEMANAGER, tym);
40
41 tym->typeList=Typemaker2_Type_List_new();
42 tym->folders=GWEN_StringList_new();
43 tym->lang=strdup("c");
44
45
46 return tym;
47 }
48
49
50
Typemaker2_TypeManager_free(TYPEMAKER2_TYPEMANAGER * tym)51 void Typemaker2_TypeManager_free(TYPEMAKER2_TYPEMANAGER *tym)
52 {
53 if (tym) {
54 Typemaker2_Type_List_free(tym->typeList);
55 GWEN_StringList_free(tym->folders);
56 GWEN_FREE_OBJECT(tym);
57 }
58 }
59
60
61
Typemaker2_TypeManager_GetLanguage(const TYPEMAKER2_TYPEMANAGER * tym)62 const char *Typemaker2_TypeManager_GetLanguage(const TYPEMAKER2_TYPEMANAGER *tym)
63 {
64 assert(tym);
65 return tym->lang;
66 }
67
68
69
Typemaker2_TypeManager_SetLanguage(TYPEMAKER2_TYPEMANAGER * tym,const char * s)70 void Typemaker2_TypeManager_SetLanguage(TYPEMAKER2_TYPEMANAGER *tym, const char *s)
71 {
72 assert(tym);
73 free(tym->lang);
74 if (s)
75 tym->lang=strdup(s);
76 else
77 tym->lang=NULL;
78 }
79
80
81
Typemaker2_TypeManager_GetApiDeclaration(const TYPEMAKER2_TYPEMANAGER * tym)82 const char *Typemaker2_TypeManager_GetApiDeclaration(const TYPEMAKER2_TYPEMANAGER *tym)
83 {
84 assert(tym);
85 return tym->apiDeclaration;
86 }
87
88
89
Typemaker2_TypeManager_SetApiDeclaration(TYPEMAKER2_TYPEMANAGER * tym,const char * s)90 void Typemaker2_TypeManager_SetApiDeclaration(TYPEMAKER2_TYPEMANAGER *tym, const char *s)
91 {
92 assert(tym);
93 free(tym->apiDeclaration);
94 if (s)
95 tym->apiDeclaration=strdup(s);
96 else
97 tym->apiDeclaration=NULL;
98 }
99
100
101
Typemaker2_TypeManager_AddFolder(TYPEMAKER2_TYPEMANAGER * tym,const char * s)102 void Typemaker2_TypeManager_AddFolder(TYPEMAKER2_TYPEMANAGER *tym, const char *s)
103 {
104 assert(tym);
105 GWEN_StringList_AppendString(tym->folders, s, 0, 1);
106 }
107
108
109
Typemaker2_TypeManager_AddType(TYPEMAKER2_TYPEMANAGER * tym,TYPEMAKER2_TYPE * ty)110 void Typemaker2_TypeManager_AddType(TYPEMAKER2_TYPEMANAGER *tym, TYPEMAKER2_TYPE *ty)
111 {
112 assert(tym);
113 Typemaker2_Type_List_Add(ty, tym->typeList);
114 }
115
116
117
Typemaker2_TypeManager_FindType(TYPEMAKER2_TYPEMANAGER * tym,const char * s)118 TYPEMAKER2_TYPE *Typemaker2_TypeManager_FindType(TYPEMAKER2_TYPEMANAGER *tym, const char *s)
119 {
120 TYPEMAKER2_TYPE *ty;
121
122 assert(tym);
123 ty=Typemaker2_Type_List_First(tym->typeList);
124 while (ty) {
125 const char *n;
126
127 n=Typemaker2_Type_GetName(ty);
128 if (n && strcasecmp(s, n)==0)
129 break;
130 ty=Typemaker2_Type_List_Next(ty);
131 }
132
133 return ty;
134 }
135
136
137
Typemaker2_TypeManager_LoadType(TYPEMAKER2_TYPEMANAGER * tym,const char * typeName)138 TYPEMAKER2_TYPE *Typemaker2_TypeManager_LoadType(TYPEMAKER2_TYPEMANAGER *tym, const char *typeName)
139 {
140 GWEN_BUFFER *tbuf;
141 GWEN_BUFFER *nbuf;
142 char *p;
143 int rv;
144 TYPEMAKER2_TYPE *ty=NULL;
145 GWEN_XMLNODE *root;
146 GWEN_XMLNODE *node;
147
148 tbuf=GWEN_Buffer_new(0, 256, 0, 1);
149 GWEN_Buffer_AppendString(tbuf, typeName);
150 p=GWEN_Buffer_GetStart(tbuf);
151 while (*p) {
152 *p=tolower(*p);
153 p++;
154 }
155 GWEN_Buffer_AppendString(tbuf, ".tm2");
156
157 nbuf=GWEN_Buffer_new(0, 256, 0, 1);
158 rv=GWEN_Directory_FindFileInPaths(tym->folders, GWEN_Buffer_GetStart(tbuf), nbuf);
159 if (rv<0) {
160 DBG_ERROR(GWEN_LOGDOMAIN, "Typefile [%s] not found (%d)", GWEN_Buffer_GetStart(tbuf), rv);
161 GWEN_Buffer_free(nbuf);
162 GWEN_Buffer_free(tbuf);
163 return NULL;
164 }
165
166 /* read XML file */
167 root=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "xml");
168
169 rv=GWEN_XML_ReadFile(root, GWEN_Buffer_GetStart(nbuf), TM_TYPEMANAGER_XMLFLAGS);
170 if (rv<0) {
171 DBG_ERROR(GWEN_LOGDOMAIN, "Could not load typefile [%s] (%d)", GWEN_Buffer_GetStart(nbuf), rv);
172 GWEN_XMLNode_free(root);
173 GWEN_Buffer_free(nbuf);
174 GWEN_Buffer_free(tbuf);
175 return NULL;
176 }
177
178 /* get <tm2> element */
179 node=GWEN_XMLNode_FindFirstTag(root, "tm2", NULL, NULL);
180 if (node==NULL) {
181 DBG_ERROR(GWEN_LOGDOMAIN,
182 "File [%s] does not contain a tm2 element",
183 GWEN_Buffer_GetStart(nbuf));
184 GWEN_XMLNode_free(root);
185 GWEN_Buffer_free(nbuf);
186 GWEN_Buffer_free(tbuf);
187 return NULL;
188 }
189
190 /* get <typedef> element with id==typeName and wanted language */
191 node=GWEN_XMLNode_FindFirstTag(node, "typedef", "id", typeName);
192 while (node) {
193 const char *s=GWEN_XMLNode_GetProperty(node, "lang", NULL);
194 if (s && *s && strcasecmp(s, tym->lang)==0)
195 break;
196 node=GWEN_XMLNode_FindNextTag(node, "typedef", "id", typeName);
197 }
198 if (node==NULL) {
199 DBG_ERROR(GWEN_LOGDOMAIN,
200 "File [%s] does not contain a <typedef> element for type [%s] and language [%s]",
201 GWEN_Buffer_GetStart(nbuf), typeName, tym->lang);
202 GWEN_XMLNode_free(root);
203 GWEN_Buffer_free(nbuf);
204 GWEN_Buffer_free(tbuf);
205 return NULL;
206 }
207
208 /* load typedef from XML element */
209 ty=Typemaker2_Type_new();
210 rv=Typemaker2_Type_readXml(ty, node, NULL);
211 if (rv<0) {
212 DBG_INFO(GWEN_LOGDOMAIN, "Error reading type [%s] from file [%s] (%d)",
213 typeName,
214 GWEN_Buffer_GetStart(nbuf),
215 rv);
216 Typemaker2_Type_free(ty);
217 GWEN_XMLNode_free(root);
218 GWEN_Buffer_free(nbuf);
219 GWEN_Buffer_free(tbuf);
220 return NULL;
221 }
222
223 GWEN_XMLNode_free(root);
224 GWEN_Buffer_free(nbuf);
225 GWEN_Buffer_free(tbuf);
226
227 return ty;
228 }
229
230
231
Typemaker2_TypeManager_MakeTypeDerivatives(TYPEMAKER2_TYPEMANAGER * tym,TYPEMAKER2_TYPE * ty,const char * baseType,const char * nType,const char * nPrefix)232 int Typemaker2_TypeManager_MakeTypeDerivatives(TYPEMAKER2_TYPEMANAGER *tym,
233 TYPEMAKER2_TYPE *ty,
234 const char *baseType,
235 const char *nType, const char *nPrefix)
236 {
237 TYPEMAKER2_TYPE *t2;
238 char tbuf[256];
239 int rv;
240
241 t2=Typemaker2_Type_new();
242 Typemaker2_Type_SetExtends(t2, baseType);
243 Typemaker2_Type_SetType(t2, TypeMaker2_Type_Pointer);
244 Typemaker2_Type_SetBaseType(t2, Typemaker2_Type_GetName(ty));
245
246 snprintf(tbuf, sizeof(tbuf)-1, "%s_%s", Typemaker2_Type_GetName(ty), nType);
247 tbuf[sizeof(tbuf)-1]=0;
248 Typemaker2_Type_SetName(t2, tbuf);
249
250 snprintf(tbuf, sizeof(tbuf)-1, "%s_%s", Typemaker2_Type_GetIdentifier(ty), nType);
251 tbuf[sizeof(tbuf)-1]=0;
252 Typemaker2_Type_SetIdentifier(t2, tbuf);
253
254 snprintf(tbuf, sizeof(tbuf)-1, "%s_%s", Typemaker2_Type_GetPrefix(ty), nPrefix);
255 tbuf[sizeof(tbuf)-1]=0;
256 Typemaker2_Type_SetPrefix(t2, tbuf);
257
258 Typemaker2_TypeManager_AddType(tym, t2);
259
260 /* set type pointers in this type structure */
261 rv=Typemaker2_TypeManager_SetTypePtrs(tym, t2);
262 if (rv<0) {
263 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
264 return rv;
265 }
266 rv=Typemaker2_TypeManager_SetMemberTypePtrs(tym, t2);
267 if (rv<0) {
268 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
269 return rv;
270 }
271
272 return 0;
273 }
274
275
276
Typemaker2_TypeManager_MakeTypeList1(TYPEMAKER2_TYPEMANAGER * tym,TYPEMAKER2_TYPE * ty)277 int Typemaker2_TypeManager_MakeTypeList1(TYPEMAKER2_TYPEMANAGER *tym, TYPEMAKER2_TYPE *ty)
278 {
279 return Typemaker2_TypeManager_MakeTypeDerivatives(tym, ty, "list1_base", "LIST", "List");
280 }
281
282
283
Typemaker2_TypeManager_MakeTypeList2(TYPEMAKER2_TYPEMANAGER * tym,TYPEMAKER2_TYPE * ty)284 int Typemaker2_TypeManager_MakeTypeList2(TYPEMAKER2_TYPEMANAGER *tym, TYPEMAKER2_TYPE *ty)
285 {
286 return Typemaker2_TypeManager_MakeTypeDerivatives(tym, ty, "list2_base", "LIST2", "List2");
287 }
288
289
290
Typemaker2_TypeManager_MakeTypeTree(TYPEMAKER2_TYPEMANAGER * tym,TYPEMAKER2_TYPE * ty)291 int Typemaker2_TypeManager_MakeTypeTree(TYPEMAKER2_TYPEMANAGER *tym, TYPEMAKER2_TYPE *ty)
292 {
293 return Typemaker2_TypeManager_MakeTypeDerivatives(tym, ty, "tree_base", "TREE", "Tree");
294 }
295
296
297
Typemaker2_TypeManager_LoadTypeFile(TYPEMAKER2_TYPEMANAGER * tym,const char * fileName)298 TYPEMAKER2_TYPE *Typemaker2_TypeManager_LoadTypeFile(TYPEMAKER2_TYPEMANAGER *tym, const char *fileName)
299 {
300 int rv;
301 TYPEMAKER2_TYPE *ty=NULL;
302 GWEN_XMLNODE *root;
303 GWEN_XMLNODE *node;
304
305 /* read XML file */
306 root=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "xml");
307
308 rv=GWEN_XML_ReadFile(root, fileName, TM_TYPEMANAGER_XMLFLAGS);
309 if (rv<0) {
310 DBG_ERROR(GWEN_LOGDOMAIN, "Could not load typefile [%s] (%d)", fileName, rv);
311 GWEN_XMLNode_free(root);
312 return NULL;
313 }
314
315 /* get <tm2> element */
316 node=GWEN_XMLNode_FindFirstTag(root, "tm2", NULL, NULL);
317 if (node==NULL) {
318 DBG_ERROR(GWEN_LOGDOMAIN,
319 "File [%s] does not contain a tm2 element",
320 fileName);
321 GWEN_XMLNode_free(root);
322 return NULL;
323 }
324
325 /* get <type> element with id==typeName and wanted language */
326 node=GWEN_XMLNode_FindFirstTag(node, "type", NULL, NULL);
327 if (node==NULL) {
328 DBG_ERROR(GWEN_LOGDOMAIN,
329 "File [%s] does not contain a type element",
330 fileName);
331 GWEN_XMLNode_free(root);
332 return NULL;
333 }
334
335 /* load type from XML element */
336 ty=Typemaker2_Type_new();
337 rv=Typemaker2_Type_readXml(ty, node, tym->lang);
338 if (rv<0) {
339 DBG_INFO(GWEN_LOGDOMAIN, "Error reading type from file [%s] (%d)",
340 fileName,
341 rv);
342 Typemaker2_Type_free(ty);
343 GWEN_XMLNode_free(root);
344 return NULL;
345 }
346
347 GWEN_XMLNode_free(root);
348
349 /* preset some stuff */
350 if (1) {
351 const char *x;
352
353 x=Typemaker2_Type_GetExtends(ty);
354 if (!x || !(*x))
355 Typemaker2_Type_SetExtends(ty, "struct_base");
356 }
357
358 /* add first, because other types might want to refer to this one */
359 Typemaker2_Type_List_Add(ty, tym->typeList);
360
361
362 if (Typemaker2_Type_GetFlags(ty) & TYPEMAKER2_TYPEFLAGS_WITH_LIST1)
363 Typemaker2_TypeManager_MakeTypeList1(tym, ty);
364 if (Typemaker2_Type_GetFlags(ty) & TYPEMAKER2_TYPEFLAGS_WITH_LIST2)
365 Typemaker2_TypeManager_MakeTypeList2(tym, ty);
366 if (Typemaker2_Type_GetFlags(ty) & TYPEMAKER2_TYPEFLAGS_WITH_TREE)
367 Typemaker2_TypeManager_MakeTypeTree(tym, ty);
368
369 //Typemaker2_TypeManager_Dump(tym, stderr, 2);
370
371 /* set type pointers in this type structure */
372 rv=Typemaker2_TypeManager_SetTypePtrs(tym, ty);
373 if (rv<0) {
374 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
375 Typemaker2_Type_free(ty);
376 return NULL;
377 }
378
379 /* set type pointers in the member structures */
380 rv=Typemaker2_TypeManager_SetMemberTypePtrs(tym, ty);
381 if (rv<0) {
382 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
383 Typemaker2_Type_free(ty);
384 return NULL;
385 }
386
387
388 return ty;
389 }
390
391
392
Typemaker2_TypeManager_LoadTypeFile2(TYPEMAKER2_TYPEMANAGER * tym,const char * fileName,TYPEMAKER2_TYPE_LIST2 * tlist2)393 int Typemaker2_TypeManager_LoadTypeFile2(TYPEMAKER2_TYPEMANAGER *tym, const char *fileName,
394 TYPEMAKER2_TYPE_LIST2 *tlist2)
395 {
396 int rv;
397 TYPEMAKER2_TYPE *ty=NULL;
398 GWEN_XMLNODE *root;
399 GWEN_XMLNODE *node;
400 TYPEMAKER2_TYPE_LIST2 *tl;
401 TYPEMAKER2_TYPE_LIST2_ITERATOR *it;
402
403 /* read XML file */
404 root=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "xml");
405
406 rv=GWEN_XML_ReadFile(root, fileName, TM_TYPEMANAGER_XMLFLAGS);
407 if (rv<0) {
408 DBG_ERROR(GWEN_LOGDOMAIN, "Could not load typefile [%s] (%d)", fileName, rv);
409 GWEN_XMLNode_free(root);
410 return rv;
411 }
412
413 /* get <tm2> element */
414 node=GWEN_XMLNode_FindFirstTag(root, "tm2", NULL, NULL);
415 if (node==NULL) {
416 DBG_ERROR(GWEN_LOGDOMAIN,
417 "File [%s] does not contain a tm2 element",
418 fileName);
419 GWEN_XMLNode_free(root);
420 return GWEN_ERROR_NO_DATA;
421 }
422
423 /* get <type> element with id==typeName and wanted language */
424 node=GWEN_XMLNode_FindFirstTag(node, "type", NULL, NULL);
425 if (node==NULL) {
426 DBG_ERROR(GWEN_LOGDOMAIN,
427 "File [%s] does not contain a type element",
428 fileName);
429 GWEN_XMLNode_free(root);
430 return GWEN_ERROR_NO_DATA;
431 }
432
433 /* read all types from the file */
434 tl=Typemaker2_Type_List2_new();
435 while (node) {
436 /* load type from XML element */
437 ty=Typemaker2_Type_new();
438 rv=Typemaker2_Type_readXml(ty, node, tym->lang);
439 if (rv<0) {
440 DBG_INFO(GWEN_LOGDOMAIN, "Error reading type from file [%s] (%d)",
441 fileName,
442 rv);
443 Typemaker2_Type_free(ty);
444 GWEN_XMLNode_free(root);
445 Typemaker2_Type_List2_free(tl);
446 return rv;
447 }
448
449 /* preset some stuff */
450 if (1) {
451 const char *x;
452
453 x=Typemaker2_Type_GetExtends(ty);
454 if (!x || !(*x))
455 Typemaker2_Type_SetExtends(ty, "struct_base");
456 }
457
458 /* add first, because other types might want to refer to this one */
459 Typemaker2_Type_List_Add(ty, tym->typeList);
460 Typemaker2_Type_List2_PushBack(tl, ty);
461
462 if (Typemaker2_Type_GetFlags(ty) & TYPEMAKER2_TYPEFLAGS_WITH_LIST1)
463 Typemaker2_TypeManager_MakeTypeList1(tym, ty);
464 if (Typemaker2_Type_GetFlags(ty) & TYPEMAKER2_TYPEFLAGS_WITH_LIST2)
465 Typemaker2_TypeManager_MakeTypeList2(tym, ty);
466 if (Typemaker2_Type_GetFlags(ty) & TYPEMAKER2_TYPEFLAGS_WITH_TREE)
467 Typemaker2_TypeManager_MakeTypeTree(tym, ty);
468
469 node=GWEN_XMLNode_FindNextTag(node, "type", NULL, NULL);
470 }
471
472 GWEN_XMLNode_free(root);
473
474 //Typemaker2_TypeManager_Dump(tym, stderr, 2);
475
476 /* set type pointers first */
477 it=Typemaker2_Type_List2_First(tl);
478 if (it) {
479 ty=Typemaker2_Type_List2Iterator_Data(it);
480 while (ty) {
481 /* set type pointers in this type structure */
482 rv=Typemaker2_TypeManager_SetTypePtrs(tym, ty);
483 if (rv<0) {
484 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
485 Typemaker2_Type_List2Iterator_free(it);
486 Typemaker2_Type_List2_free(tl);
487 return rv;
488 }
489
490 /* handle next type */
491 ty=Typemaker2_Type_List2Iterator_Next(it);
492 }
493 Typemaker2_Type_List2Iterator_free(it);
494 }
495
496 /* now set member pointers */
497 it=Typemaker2_Type_List2_First(tl);
498 if (it) {
499 ty=Typemaker2_Type_List2Iterator_Data(it);
500 while (ty) {
501 /* set type pointers in the member structures */
502 rv=Typemaker2_TypeManager_SetMemberTypePtrs(tym, ty);
503 if (rv<0) {
504 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
505 Typemaker2_Type_List2Iterator_free(it);
506 Typemaker2_Type_List2_free(tl);
507 return rv;
508 }
509
510 /* add to provided list2 */
511 Typemaker2_Type_List2_PushBack(tlist2, ty);
512 /* handle next type */
513 ty=Typemaker2_Type_List2Iterator_Next(it);
514 }
515 Typemaker2_Type_List2Iterator_free(it);
516 }
517
518 /* done, free list */
519 Typemaker2_Type_List2_free(tl);
520
521 return 0;
522 }
523
524
525
Typemaker2_TypeManager_LoadTypeFileNoLookup(TYPEMAKER2_TYPEMANAGER * tym,const char * fileName,TYPEMAKER2_TYPE_LIST2 * tlist2)526 int Typemaker2_TypeManager_LoadTypeFileNoLookup(TYPEMAKER2_TYPEMANAGER *tym, const char *fileName,
527 TYPEMAKER2_TYPE_LIST2 *tlist2)
528 {
529 int rv;
530 TYPEMAKER2_TYPE *ty=NULL;
531 GWEN_XMLNODE *root;
532 GWEN_XMLNODE *node;
533
534 /* read XML file */
535 root=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "xml");
536
537 rv=GWEN_XML_ReadFile(root, fileName, TM_TYPEMANAGER_XMLFLAGS);
538 if (rv<0) {
539 DBG_ERROR(GWEN_LOGDOMAIN, "Could not load typefile [%s] (%d)", fileName, rv);
540 GWEN_XMLNode_free(root);
541 return rv;
542 }
543
544 /* get <tm2> element */
545 node=GWEN_XMLNode_FindFirstTag(root, "tm2", NULL, NULL);
546 if (node==NULL) {
547 DBG_ERROR(GWEN_LOGDOMAIN,
548 "File [%s] does not contain a tm2 element",
549 fileName);
550 GWEN_XMLNode_free(root);
551 return GWEN_ERROR_NO_DATA;
552 }
553
554 /* get <type> element with id==typeName and wanted language */
555 node=GWEN_XMLNode_FindFirstTag(node, "type", NULL, NULL);
556 if (node==NULL) {
557 DBG_ERROR(GWEN_LOGDOMAIN,
558 "File [%s] does not contain a type element",
559 fileName);
560 GWEN_XMLNode_free(root);
561 return GWEN_ERROR_NO_DATA;
562 }
563
564 /* read all types from the file */
565 while (node) {
566 /* load type from XML element */
567 ty=Typemaker2_Type_new();
568 rv=Typemaker2_Type_readXml(ty, node, tym->lang);
569 if (rv<0) {
570 DBG_INFO(GWEN_LOGDOMAIN, "Error reading type from file [%s] (%d)",
571 fileName,
572 rv);
573 Typemaker2_Type_free(ty);
574 GWEN_XMLNode_free(root);
575 return rv;
576 }
577
578 /* preset some stuff */
579 if (1) {
580 const char *x;
581
582 x=Typemaker2_Type_GetExtends(ty);
583 if (!x || !(*x))
584 Typemaker2_Type_SetExtends(ty, "struct_base");
585 }
586
587 /* add first, because other types might want to refer to this one */
588 Typemaker2_Type_List_Add(ty, tym->typeList);
589 Typemaker2_Type_List2_PushBack(tlist2, ty);
590
591 if (Typemaker2_Type_GetFlags(ty) & TYPEMAKER2_TYPEFLAGS_WITH_LIST1)
592 Typemaker2_TypeManager_MakeTypeList1(tym, ty);
593 if (Typemaker2_Type_GetFlags(ty) & TYPEMAKER2_TYPEFLAGS_WITH_LIST2)
594 Typemaker2_TypeManager_MakeTypeList2(tym, ty);
595 if (Typemaker2_Type_GetFlags(ty) & TYPEMAKER2_TYPEFLAGS_WITH_TREE)
596 Typemaker2_TypeManager_MakeTypeTree(tym, ty);
597
598 node=GWEN_XMLNode_FindNextTag(node, "type", NULL, NULL);
599 }
600
601 GWEN_XMLNode_free(root);
602
603 //Typemaker2_TypeManager_Dump(tym, stderr, 2);
604
605 return 0;
606 }
607
608
609
Typemaker2_TypeManager_SetTypePtrs(TYPEMAKER2_TYPEMANAGER * tym,TYPEMAKER2_TYPE * ty)610 int Typemaker2_TypeManager_SetTypePtrs(TYPEMAKER2_TYPEMANAGER *tym, TYPEMAKER2_TYPE *ty)
611 {
612 if (Typemaker2_Type_GetExtendsPtr(ty)==NULL) {
613 const char *s;
614
615 s=Typemaker2_Type_GetExtends(ty);
616 if (s && *s) {
617 TYPEMAKER2_TYPE *tt;
618
619 tt=Typemaker2_TypeManager_GetType(tym, s);
620 if (tt==NULL) {
621 DBG_INFO(GWEN_LOGDOMAIN, "Type for \"extends\" not found [%s]", s);
622 return GWEN_ERROR_NOT_FOUND;
623 }
624 Typemaker2_Type_SetExtendsPtr(ty, tt);
625 }
626 }
627
628 if (Typemaker2_Type_GetBaseTypePtr(ty)==NULL) {
629 const char *s;
630
631 s=Typemaker2_Type_GetBaseType(ty);
632 if (s && *s) {
633 TYPEMAKER2_TYPE *tt;
634
635 tt=Typemaker2_TypeManager_GetType(tym, s);
636 if (tt==NULL) {
637 DBG_INFO(GWEN_LOGDOMAIN, "Type for \"basetype\" not found [%s]", s);
638 return GWEN_ERROR_NOT_FOUND;
639 }
640 Typemaker2_Type_SetBaseTypePtr(ty, tt);
641 }
642 }
643
644 if (Typemaker2_Type_GetInheritsPtr(ty)==NULL) {
645 const char *s;
646
647 s=Typemaker2_Type_GetInherits(ty);
648 if (s && *s) {
649 TYPEMAKER2_TYPE *tt;
650
651 tt=Typemaker2_TypeManager_GetType(tym, s);
652 if (tt==NULL) {
653 DBG_INFO(GWEN_LOGDOMAIN, "Type for \"inherits\" not found [%s]", s);
654 return GWEN_ERROR_NOT_FOUND;
655 }
656 Typemaker2_Type_SetInheritsPtr(ty, tt);
657 }
658 }
659
660 return 0;
661 }
662
663
664
Typemaker2_TypeManager_SetMemberTypePtrs(TYPEMAKER2_TYPEMANAGER * tym,TYPEMAKER2_TYPE * ty)665 int Typemaker2_TypeManager_SetMemberTypePtrs(TYPEMAKER2_TYPEMANAGER *tym, TYPEMAKER2_TYPE *ty)
666 {
667 TYPEMAKER2_MEMBER_LIST *ml;
668
669 ml=Typemaker2_Type_GetMembers(ty);
670 if (ml) {
671 TYPEMAKER2_MEMBER *m;
672 int pos=0;
673
674 /* set pointers */
675 m=Typemaker2_Member_List_First(ml);
676 while (m) {
677 if (Typemaker2_Member_GetTypePtr(m)==NULL) {
678 const char *s;
679
680 /* set type pointer */
681 s=Typemaker2_Member_GetTypeName(m);
682 if (s && *s) {
683 TYPEMAKER2_TYPE *tt;
684
685 tt=Typemaker2_TypeManager_GetType(tym, s);
686 if (tt==NULL) {
687 DBG_INFO(GWEN_LOGDOMAIN, "Type for \"type\" not found [%s]", s);
688 return GWEN_ERROR_NOT_FOUND;
689 }
690 Typemaker2_Member_SetTypePtr(m, tt);
691 }
692
693 /* set enum pointer (if any) */
694 if ((Typemaker2_Member_GetFlags(m) & TYPEMAKER2_FLAGS_ENUM) &&
695 Typemaker2_Member_GetEnumPtr(m)==NULL) {
696 s=Typemaker2_Member_GetEnumId(m);
697 if (s && *s) {
698 TYPEMAKER2_ENUM *te=Typemaker2_Type_FindEnum(ty, s);
699 if (te)
700 Typemaker2_Member_SetEnumPtr(m, te);
701 else {
702 DBG_ERROR(GWEN_LOGDOMAIN, "Enum [%s] not found", s);
703 return GWEN_ERROR_NOT_FOUND;
704 }
705 }
706 }
707 }
708
709 m=Typemaker2_Member_List_Next(m);
710 }
711
712 /* update member positions (needed for toObject/fromObject functions) */
713 m=Typemaker2_Member_List_First(ml);
714 while (m) {
715 if (!(Typemaker2_Member_GetFlags(m) & TYPEMAKER2_FLAGS_VOLATILE)) {
716 const char *s;
717
718 Typemaker2_Member_SetMemberPosition(m, pos++);
719
720 /* create field id */
721 s=Typemaker2_Type_GetName(ty);
722 if (s && *s) {
723 GWEN_BUFFER *tbuf;
724 char *p;
725
726 tbuf=GWEN_Buffer_new(0, 256, 0, 1);
727 GWEN_Buffer_AppendString(tbuf, s);
728 GWEN_Buffer_AppendString(tbuf, "_FIELD_");
729 s=Typemaker2_Member_GetName(m);
730 GWEN_Buffer_AppendString(tbuf, s);
731 /* all in capitals */
732 p=GWEN_Buffer_GetStart(tbuf);
733 while (*p) {
734 *p=toupper(*p);
735 p++;
736 }
737
738 Typemaker2_Member_SetFieldId(m, GWEN_Buffer_GetStart(tbuf));
739 GWEN_Buffer_free(tbuf);
740 }
741 }
742
743 m=Typemaker2_Member_List_Next(m);
744 }
745 Typemaker2_Type_SetNonVolatileMemberCount(ty, pos);
746 if (pos) {
747 const char *s;
748
749 /* create field id */
750 s=Typemaker2_Type_GetName(ty);
751 if (s && *s) {
752 GWEN_BUFFER *tbuf;
753 char *p;
754
755 tbuf=GWEN_Buffer_new(0, 256, 0, 1);
756 GWEN_Buffer_AppendString(tbuf, s);
757 GWEN_Buffer_AppendString(tbuf, "_FIELD_COUNT");
758 /* all in capitals */
759 p=GWEN_Buffer_GetStart(tbuf);
760 while (*p) {
761 *p=toupper(*p);
762 p++;
763 }
764
765 Typemaker2_Type_SetFieldCountId(ty, GWEN_Buffer_GetStart(tbuf));
766 GWEN_Buffer_free(tbuf);
767 }
768
769 }
770 }
771
772 return 0;
773 }
774
775
776
Typemaker2_TypeManager_GetType(TYPEMAKER2_TYPEMANAGER * tym,const char * s)777 TYPEMAKER2_TYPE *Typemaker2_TypeManager_GetType(TYPEMAKER2_TYPEMANAGER *tym, const char *s)
778 {
779 TYPEMAKER2_TYPE *ty;
780
781 ty=Typemaker2_TypeManager_FindType(tym, s);
782 if (ty==NULL) {
783 ty=Typemaker2_TypeManager_LoadType(tym, s);
784 if (ty) {
785 int rv;
786
787 /* add first, because other types might want to refer to this one */
788 Typemaker2_Type_List_Add(ty, tym->typeList);
789
790 /* set type pointers in this type structure */
791 rv=Typemaker2_TypeManager_SetTypePtrs(tym, ty);
792 if (rv<0) {
793 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
794 return NULL;
795 }
796
797 /* set type pointers in the member structures */
798 rv=Typemaker2_TypeManager_SetMemberTypePtrs(tym, ty);
799 if (rv<0) {
800 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
801 return NULL;
802 }
803 }
804 else {
805 DBG_INFO(GWEN_LOGDOMAIN, "here");
806 }
807 }
808
809 if (ty==NULL) {
810 DBG_INFO(GWEN_LOGDOMAIN, "Type [%s] not found", s);
811 }
812
813 return ty;
814 }
815
816
817
Typemaker2_TypeManager_Dump(TYPEMAKER2_TYPEMANAGER * tym,FILE * f,int indent)818 void Typemaker2_TypeManager_Dump(TYPEMAKER2_TYPEMANAGER *tym, FILE *f, int indent)
819 {
820 TYPEMAKER2_TYPE *ty;
821 int i;
822
823 for (i=0; i<indent; i++)
824 fprintf(f, " ");
825 fprintf(f, "TypeManager\n");
826
827 for (i=0; i<indent; i++)
828 fprintf(f, " ");
829 fprintf(f, "Types\n");
830
831 ty=Typemaker2_Type_List_First(tym->typeList);
832 while (ty) {
833 Typemaker2_Type_Dump(ty, f, indent+2);
834 ty=Typemaker2_Type_List_Next(ty);
835 }
836 }
837
838
839
840
841
842