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