gwenhywfar 5.14.1
typemaker/main.c
Go to the documentation of this file.
1/***************************************************************************
2 begin : Mon Mar 01 2004
3 copyright : (C) 2004-2010 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/* Internationalization */
15#ifdef ENABLE_NLS
16# include <libintl.h>
17# include <locale.h>
18# define I18N(m) dgettext("gwenhywfar", m)
19# define I18S(m) m
20#else
21# define I18N(m) m
22# define I18S(m) m
23#endif
24
25
26#include "args.h"
27#include "typemaker_p.h"
28#include <gwenhywfar/debug.h>
29#include <gwenhywfar/logger.h>
30#include <gwenhywfar/xml.h>
31
32#include <stdlib.h>
33#include <assert.h>
34
35#include <sys/types.h>
36#include <sys/stat.h>
37#include <fcntl.h>
38#include <errno.h>
39#include <string.h>
40#include <ctype.h>
41
42
43
44int write_xml_to_bio(GWEN_XMLNODE *n, GWEN_SYNCIO *sio, uint32_t flags)
45{
46 GWEN_BUFFER *buf;
47 int rv;
48
49 buf=GWEN_Buffer_new(0, 256, 0, 1);
50 rv=GWEN_XMLNode_toBuffer(n, buf, flags);
51 if (rv) {
53 return rv;
54 }
55
56 rv=GWEN_SyncIo_WriteForced(sio, (const uint8_t *) GWEN_Buffer_GetStart(buf), GWEN_Buffer_GetUsedBytes(buf));
58 if (rv<0) {
59 DBG_INFO(0, "here (%d)", rv);
60 return rv;
61 }
62 return 0;
63}
64
65
66
68 GWEN_SYNCIO *sio,
69 GWEN_UNUSED const char *where)
70{
71 int isSys;
72 int err;
73 const char *d;
74 GWEN_XMLNODE *dn;
75 /*const char *nwhere;*/
76
77 /*nwhere=GWEN_XMLNode_GetProperty(node, "out", "header");
78 if (strcasecmp(nwhere, where)==0) {*/
80 if (!dn) {
81 DBG_ERROR(0, "Empty <header>");
82 return -1;
83 }
85 if (!d) {
86 DBG_ERROR(0, "Empty <header>");
87 return -1;
88 }
89 isSys=(strcasecmp(GWEN_XMLNode_GetProperty(node, "type", ""),
90 "sys")==0);
91
92 err=GWEN_SyncIo_WriteString(sio, "#include ");
93 if (err) {
94 DBG_ERROR_ERR(0, err);
95 return -1;
96 }
97 if (isSys) {
98 err=GWEN_SyncIo_WriteString(sio, "<");
99 if (err) {
100 DBG_ERROR_ERR(0, err);
101 return -1;
102 }
103 }
104 else {
105 err=GWEN_SyncIo_WriteString(sio, "\"");
106 if (err) {
107 DBG_ERROR_ERR(0, err);
108 return -1;
109 }
110 }
111 err=GWEN_SyncIo_WriteString(sio, d);
112 if (err) {
113 DBG_ERROR_ERR(0, err);
114 return -1;
115 }
116 if (isSys) {
117 err=GWEN_SyncIo_WriteLine(sio, ">");
118 if (err) {
119 DBG_ERROR_ERR(0, err);
120 return -1;
121 }
122 }
123 else {
124 err=GWEN_SyncIo_WriteLine(sio, "\"");
125 if (err) {
126 DBG_ERROR_ERR(0, err);
127 return -1;
128 }
129 }
130 /*} */
131
132 return 0;
133}
134
135
136void write_if_nonnull(GWEN_SYNCIO *sio, const char *str)
137{
138 if (str) {
139 GWEN_SyncIo_WriteString(sio, str);
140 GWEN_SyncIo_WriteString(sio, " ");
141 }
142}
143
144
146 GWEN_XMLNODE *node,
147 GWEN_SYNCIO *sio,
148 const char *acc)
149{
150 GWEN_XMLNODE *n;
151 int rv;
152 const char *prefix;
153 const char *styp;
154 const char *sacc;
155
156 sacc=get_struct_property(node, "access", "public");
157 prefix=get_struct_property(node, "prefix", 0);
158 if (!prefix) {
159 DBG_ERROR(0, "No prefix in struct");
160 return -1;
161 }
162 styp=get_struct_property(node, "id", 0);
163 if (!styp) {
164 DBG_ERROR(0, "No id in struct");
165 return -1;
166 }
168 while (n) {
170 if (strcasecmp(GWEN_XMLNode_GetData(n), "group")==0) {
171 const char *name;
172 int hasDoc;
173 GWEN_XMLNODE *dn;
174
175 hasDoc=0;
176 name=GWEN_XMLNode_GetProperty(n, "name", 0);
177 if (name) {
178 hasDoc=1;
179 GWEN_SyncIo_WriteString(sio, "/** @name ");
180 GWEN_SyncIo_WriteLine(sio, name);
181 dn=GWEN_XMLNode_FindFirstTag(n, "descr", 0, 0);
182 if (dn) {
183 GWEN_SyncIo_WriteLine(sio, " *");
184 if (write_xml_to_bio(dn, sio,
187 return -1;
188 }
189 GWEN_SyncIo_WriteLine(sio, "*/");
190 GWEN_SyncIo_WriteLine(sio, "/*@{*/");
191 }
192
193 rv=write_h_setget_c(args, n, sio, acc);
194 if (rv)
195 return rv;
196
197 if (hasDoc) {
198 GWEN_SyncIo_WriteLine(sio, "/*@}*/");
199 }
200
201 }
202 else if (strcasecmp(GWEN_XMLNode_GetData(n), "elem")==0) {
203 if (strcasecmp(GWEN_XMLNode_GetProperty(n, "access", sacc),
204 acc)==0) {
205 int isPtr;
206 const char *typ;
207 const char *name;
208 const char *mode;
209 const char *tmode;
210 int isConst;
211 /*int doCopy;*/
212 GWEN_XMLNODE *tnode;
213
214 name=GWEN_XMLNode_GetProperty(n, "name", 0);
215 if (!name) {
216 DBG_ERROR(0, "No name for element");
217 return -1;
218 }
219
220 typ=GWEN_XMLNode_GetProperty(n, "type", 0);
221 if (!typ) {
222 DBG_ERROR(0, "No type for element");
223 return -1;
224 }
225
226 isPtr=atoi(get_property(n, "ptr", "0"));
227 isConst=atoi(get_property(n, "const", "1"));
228 /*doCopy=atoi(get_property(n, "copy", "1"));*/
229 mode=GWEN_XMLNode_GetProperty(n, "mode", "single");
230 if (strcasecmp(mode, "single")!=0)
231 isPtr=1;
232
233 tnode=get_typedef(node, typ);
234 if (tnode)
235 tmode=GWEN_XMLNode_GetProperty(tnode, "mode", "single");
236 else
237 tmode=mode;
238
239 /* getter */
240 GWEN_SyncIo_WriteLine(sio, "/**");
241 GWEN_SyncIo_WriteString(sio, "* Returns the property @ref ");
242 GWEN_SyncIo_WriteString(sio, styp);
243 GWEN_SyncIo_WriteString(sio, "_");
244 GWEN_SyncIo_WriteChar(sio, toupper(*name));
245 GWEN_SyncIo_WriteLine(sio, name+1);
246 GWEN_SyncIo_WriteLine(sio, "*/");
247 write_if_nonnull(sio, args->domain);
248 if (isPtr &&
249 (/*strcasecmp(mode, "single")==0 ||*/ isConst)) {
250 GWEN_SyncIo_WriteString(sio, "const ");
251 }
252 if (strcasecmp(tmode, "enum")!=0)
253 GWEN_SyncIo_WriteString(sio, typ);
254 else {
255 GWEN_BUFFER *tid;
256 const char *s;
257
258 tid=GWEN_Buffer_new(0, 64, 0, 1);
259 s=get_struct_property(node, "id", 0);
260 assert(s);
262 GWEN_Buffer_AppendString(tid, "_");
263 GWEN_Buffer_AppendString(tid, typ);
265 GWEN_Buffer_free(tid);
266 }
267 if (isPtr) {
268 GWEN_SyncIo_WriteString(sio, " *");
269 }
270 else {
271 GWEN_SyncIo_WriteString(sio, " ");
272 }
273 GWEN_SyncIo_WriteString(sio, prefix);
274 GWEN_SyncIo_WriteString(sio, "_Get");
275 GWEN_SyncIo_WriteChar(sio, toupper(*name));;
276 GWEN_SyncIo_WriteString(sio, name+1);
277 GWEN_SyncIo_WriteString(sio, "(const ");
278 GWEN_SyncIo_WriteString(sio, styp);
279 GWEN_SyncIo_WriteLine(sio, " *el);");
280
281 /* setter */
282 GWEN_SyncIo_WriteLine(sio, "/**");
283 GWEN_SyncIo_WriteString(sio, "* Set the property @ref ");
284 GWEN_SyncIo_WriteString(sio, styp);
285 GWEN_SyncIo_WriteString(sio, "_");
286 GWEN_SyncIo_WriteChar(sio, toupper(*name));
287 GWEN_SyncIo_WriteLine(sio, name+1);
288 GWEN_SyncIo_WriteLine(sio, "*/");
289 write_if_nonnull(sio, args->domain);
290 GWEN_SyncIo_WriteString(sio, "void ");
291 GWEN_SyncIo_WriteString(sio, prefix);
292 GWEN_SyncIo_WriteString(sio, "_Set");
293 GWEN_SyncIo_WriteChar(sio, toupper(*name));;
294 GWEN_SyncIo_WriteString(sio, name+1);
295 GWEN_SyncIo_WriteString(sio, "(");
296
297 GWEN_SyncIo_WriteString(sio, styp);
298 GWEN_SyncIo_WriteString(sio, " *el, ");
299 if (isPtr && isConst) {
300 GWEN_SyncIo_WriteString(sio, "const ");
301 }
302 if (strcasecmp(tmode, "enum")!=0)
303 GWEN_SyncIo_WriteString(sio, typ);
304 else {
305 GWEN_BUFFER *tid;
306 const char *s;
307
308 tid=GWEN_Buffer_new(0, 64, 0, 1);
309 s=get_struct_property(node, "id", 0);
310 assert(s);
312 GWEN_Buffer_AppendString(tid, "_");
313 GWEN_Buffer_AppendString(tid, typ);
315 GWEN_Buffer_free(tid);
316 }
317
318 if (isPtr) {
319 GWEN_SyncIo_WriteString(sio, " *");
320 }
321 else {
322 GWEN_SyncIo_WriteString(sio, " ");
323 }
324 GWEN_SyncIo_WriteLine(sio, "d);");
325
326 if (strcasecmp(typ, "GWEN_STRINGLIST")==0) {
327 /* special functions for string lists */
328 write_if_nonnull(sio, args->domain);
329 GWEN_SyncIo_WriteString(sio, "void ");
330 GWEN_SyncIo_WriteString(sio, prefix);
331 GWEN_SyncIo_WriteString(sio, "_Add");
332 GWEN_SyncIo_WriteChar(sio, toupper(*name));
333 GWEN_SyncIo_WriteString(sio, name+1);
334 GWEN_SyncIo_WriteString(sio, "(");
335 GWEN_SyncIo_WriteString(sio, styp);
336 GWEN_SyncIo_WriteLine(sio, " *st, const char *d, int chk);");
337
338 write_if_nonnull(sio, args->domain);
339 GWEN_SyncIo_WriteString(sio, "void ");
340 GWEN_SyncIo_WriteString(sio, prefix);
341 GWEN_SyncIo_WriteString(sio, "_Remove");
342 GWEN_SyncIo_WriteChar(sio, toupper(*name));
343 GWEN_SyncIo_WriteString(sio, name+1);
344 GWEN_SyncIo_WriteString(sio, "(");
345 GWEN_SyncIo_WriteString(sio, styp);
346 GWEN_SyncIo_WriteLine(sio, " *st, const char *d);");
347
348 write_if_nonnull(sio, args->domain);
349 GWEN_SyncIo_WriteString(sio, "void ");
350 GWEN_SyncIo_WriteString(sio, prefix);
351 GWEN_SyncIo_WriteString(sio, "_Clear");
352 GWEN_SyncIo_WriteChar(sio, toupper(*name));;
353 GWEN_SyncIo_WriteString(sio, name+1);
354 GWEN_SyncIo_WriteString(sio, "(");
355 GWEN_SyncIo_WriteString(sio, styp);
356 GWEN_SyncIo_WriteLine(sio, " *st);");
357
358 write_if_nonnull(sio, args->domain);
359 GWEN_SyncIo_WriteString(sio, "int ");
360 GWEN_SyncIo_WriteString(sio, prefix);
361 GWEN_SyncIo_WriteString(sio, "_Has");
362 GWEN_SyncIo_WriteChar(sio, toupper(*name));;
363 GWEN_SyncIo_WriteString(sio, name+1);
364 GWEN_SyncIo_WriteString(sio, "(const ");
365 GWEN_SyncIo_WriteString(sio, styp);
366 GWEN_SyncIo_WriteLine(sio, " *st, const char *d);");
367 }
368
369 }
370 }
371 else if (strcasecmp(GWEN_XMLNode_GetData(n), "func")==0) {
372 if (strcasecmp(GWEN_XMLNode_GetProperty(n, "access", sacc),
373 acc)==0) {
374 const char *typ;
375 const char *name;
376 const char *rettype;
377 GWEN_XMLNODE *anode;
378 int isPtr;
379 /*int isVoid;*/
380 int idx;
381
382 name=GWEN_XMLNode_GetProperty(n, "name", 0);
383 if (!name) {
384 DBG_ERROR(0, "No name for element");
385 return -1;
386 }
387
388 typ=GWEN_XMLNode_GetProperty(n, "type", 0);
389 if (!typ) {
390 DBG_ERROR(0, "No type for element");
391 return -1;
392 }
393
394 rettype=GWEN_XMLNode_GetProperty(n, "return", 0);
395 if (!rettype) {
396 DBG_ERROR(0, "No return type for function");
397 return -1;
398 }
399
400 isPtr=atoi(get_property(n, "ptr", "0"));
401 /*isVoid=(!isPtr && strcasecmp(rettype, "void")==0);*/
402
403 /* getter */
404 GWEN_SyncIo_WriteLine(sio, "/**");
405 GWEN_SyncIo_WriteString(sio, "* Returns the property @ref ");
406 GWEN_SyncIo_WriteString(sio, styp);
407 GWEN_SyncIo_WriteString(sio, "_");
408 GWEN_SyncIo_WriteChar(sio, toupper(*name));
409 GWEN_SyncIo_WriteLine(sio, name+1);
410 GWEN_SyncIo_WriteLine(sio, "*/");
411 write_if_nonnull(sio, args->domain);
412
413 GWEN_SyncIo_WriteString(sio, styp);
414 GWEN_SyncIo_WriteString(sio, "_");
415 GWEN_SyncIo_WriteString(sio, typ);
416 GWEN_SyncIo_WriteString(sio, " ");
417 GWEN_SyncIo_WriteString(sio, prefix);
418 GWEN_SyncIo_WriteString(sio, "_Get");
419 GWEN_SyncIo_WriteChar(sio, toupper(*name));;
420 GWEN_SyncIo_WriteString(sio, name+1);
421 GWEN_SyncIo_WriteString(sio, "(const ");
422 GWEN_SyncIo_WriteString(sio, styp);
423 GWEN_SyncIo_WriteLine(sio, " *st);");
424
425 /* setter */
426 GWEN_SyncIo_WriteLine(sio, "/**");
427 GWEN_SyncIo_WriteString(sio, "* Set the property @ref ");
428 GWEN_SyncIo_WriteString(sio, styp);
429 GWEN_SyncIo_WriteString(sio, "_");
430 GWEN_SyncIo_WriteChar(sio, toupper(*name));
431 GWEN_SyncIo_WriteLine(sio, name+1);
432 GWEN_SyncIo_WriteLine(sio, "*/");
433 write_if_nonnull(sio, args->domain);
434 GWEN_SyncIo_WriteString(sio, "void ");
435 GWEN_SyncIo_WriteString(sio, prefix);
436 GWEN_SyncIo_WriteString(sio, "_Set");
437 GWEN_SyncIo_WriteChar(sio, toupper(*name));;
438 GWEN_SyncIo_WriteString(sio, name+1);
439 GWEN_SyncIo_WriteString(sio, "(");
440
441 GWEN_SyncIo_WriteString(sio, styp);
442 GWEN_SyncIo_WriteString(sio, " *st, ");
443 GWEN_SyncIo_WriteString(sio, styp);
444 GWEN_SyncIo_WriteString(sio, "_");
445 GWEN_SyncIo_WriteString(sio, typ);
446 GWEN_SyncIo_WriteLine(sio, " d);");
447
448 /* function call */
449 GWEN_SyncIo_WriteLine(sio, "/**");
450 /* TODO: Write API doc for this function */
451 GWEN_SyncIo_WriteLine(sio, "*/");
452 write_if_nonnull(sio, args->domain);
453 GWEN_SyncIo_WriteString(sio, rettype);
454 if (isPtr)
455 GWEN_SyncIo_WriteString(sio, "*");
456 GWEN_SyncIo_WriteString(sio, " ");
457 GWEN_SyncIo_WriteString(sio, prefix);
458 GWEN_SyncIo_WriteString(sio, "_");
459 GWEN_SyncIo_WriteChar(sio, toupper(*name));
460 GWEN_SyncIo_WriteString(sio, name+1);
461 GWEN_SyncIo_WriteString(sio, "(");
462
463 GWEN_SyncIo_WriteString(sio, styp);
464 GWEN_SyncIo_WriteString(sio, " *st");
465
466 anode=GWEN_XMLNode_FindFirstTag(n, "arg", 0, 0);
467 idx=0;
468 while (anode) {
469 const char *aname;
470 const char *atype;
471 int aisPtr;
472
473 GWEN_SyncIo_WriteString(sio, ", ");
474
475 aisPtr=atoi(GWEN_XMLNode_GetProperty(anode, "ptr", "0"));
476 aname=GWEN_XMLNode_GetProperty(anode, "name", 0);
477 if (!aname || !*aname) {
478 DBG_ERROR(0, "No name for argument %d in function %s", idx, name);
479 return -1;
480 }
481 atype=GWEN_XMLNode_GetProperty(anode, "type", 0);
482 if (!atype || !*atype) {
483 DBG_ERROR(0, "No type for argument %d in function %s", idx, name);
484 return -1;
485 }
486
487 GWEN_SyncIo_WriteString(sio, atype);
488 if (aisPtr)
489 GWEN_SyncIo_WriteString(sio, "*");
490 GWEN_SyncIo_WriteString(sio, " ");
491 GWEN_SyncIo_WriteString(sio, aname);
492
493 idx++;
494 anode=GWEN_XMLNode_FindNextTag(anode, "arg", 0, 0);
495 }
496
497 GWEN_SyncIo_WriteLine(sio, ");");
498
499 }
500 }
501 }
502 GWEN_SyncIo_WriteLine(sio, "");
504 }
505 return 0;
506}
507
508
509
511 GWEN_SYNCIO *sio,
512 const char *acc)
513{
514 GWEN_XMLNODE *n;
515
516 n=GWEN_XMLNode_FindFirstTag(node, "subtypes", 0, 0);
517 if (n)
518 n=GWEN_XMLNode_FindFirstTag(n, "type", "mode", "enum");
519 if (n) {
520 GWEN_BUFFER *tprefix;
521 GWEN_BUFFER *tid;
522 uint32_t ppos;
523 uint32_t tpos;
524 const char *s;
525
526 tprefix=GWEN_Buffer_new(0, 64, 0, 1);
527 tid=GWEN_Buffer_new(0, 64, 0, 1);
528
529 s=get_struct_property(node, "prefix", 0);
530 assert(s);
531 GWEN_Buffer_AppendString(tprefix, s);
532 GWEN_Buffer_AppendString(tprefix, "_");
533 ppos=GWEN_Buffer_GetPos(tprefix);
534
535 s=get_struct_property(node, "id", 0);
536 assert(s);
538 GWEN_Buffer_AppendString(tid, "_");
539 tpos=GWEN_Buffer_GetPos(tid);
540
541 while (n) {
542 s=GWEN_XMLNode_GetProperty(n, "access", "public");
543 if (strcasecmp(s, acc)==0) {
544 GWEN_XMLNODE *nn;
545
546 s=GWEN_XMLNode_GetProperty(n, "id", 0);
547 assert(s);
549 s=GWEN_XMLNode_GetProperty(n, "prefix", 0);
550 assert(s);
551 GWEN_Buffer_AppendString(tprefix, s);
552
553 GWEN_SyncIo_WriteLine(sio, "typedef enum {");
554 GWEN_SyncIo_WriteString(sio, " ");
556 GWEN_SyncIo_WriteString(sio, "Unknown=-1");
557
558 nn=GWEN_XMLNode_FindFirstTag(n, "values", 0, 0);
559 if (nn)
560 nn=GWEN_XMLNode_FindFirstTag(nn, "value", 0, 0);
561 if (nn) {
562 uint32_t vpos;
563
564 vpos=GWEN_Buffer_GetPos(tprefix);
565 while (nn) {
566 GWEN_XMLNODE *nnn;
567 GWEN_XMLNODE *dn;
568
570 if (!nnn) {
571 DBG_ERROR(0, "No values in enum description for \"%s\"",
573 GWEN_Buffer_free(tid);
574 GWEN_Buffer_free(tprefix);
575 return -1;
576 }
577 GWEN_SyncIo_WriteLine(sio, ",");
578
579 dn=GWEN_XMLNode_FindFirstTag(nn, "descr", 0, 0);
580 if (dn) {
581 GWEN_SyncIo_WriteString(sio, " /** ");
582 if (write_xml_to_bio(dn, sio,
585 return -1;
586 GWEN_SyncIo_WriteLine(sio, " */");
587 }
588
589 GWEN_SyncIo_WriteString(sio, " ");
591 assert(s);
592 GWEN_Buffer_AppendByte(tprefix, toupper(*s));
593 GWEN_Buffer_AppendString(tprefix, s+1);
595 s=GWEN_XMLNode_GetProperty(nn, "value", 0);
596 if (s) {
597 GWEN_SyncIo_WriteString(sio, "=");
599 }
600
601 GWEN_Buffer_Crop(tprefix, 0, vpos);
602 nn=GWEN_XMLNode_FindNextTag(nn, "value", 0, 0);
603 }
604 }
605
606 GWEN_SyncIo_WriteLine(sio, "");
607 GWEN_SyncIo_WriteString(sio, "} ");
609 GWEN_SyncIo_WriteLine(sio, ";");
610 GWEN_SyncIo_WriteLine(sio, "");
611
612 write_if_nonnull(sio, args->domain);
614 GWEN_SyncIo_WriteString(sio, " ");
616 GWEN_SyncIo_WriteLine(sio, "_fromString(const char *s);");
617
618 write_if_nonnull(sio, args->domain);
619 GWEN_SyncIo_WriteString(sio, "const char *");
621 GWEN_SyncIo_WriteString(sio, "_toString(");
623 GWEN_SyncIo_WriteLine(sio, " v);");
624
625 GWEN_Buffer_Crop(tprefix, 0, ppos);
626 GWEN_Buffer_Crop(tid, 0, tpos);
627 GWEN_SyncIo_WriteLine(sio, "");
628 } /* if access type matches */
629 n=GWEN_XMLNode_FindNextTag(n, "type", "mode", "enum");
630 } /* while n */
631 GWEN_Buffer_free(tid);
632 GWEN_Buffer_free(tprefix);
633 } /* if enum types found */
634
635 return 0;
636}
637
638
639
641 GWEN_SYNCIO *sio,
642 const char *acc)
643{
644 GWEN_XMLNODE *n;
645 const char *styp;
646
647 styp=get_struct_property(node, "id", 0);
648 if (!styp) {
649 DBG_ERROR(0, "No id in struct");
650 return -1;
651 }
652
653 n=GWEN_XMLNode_FindFirstTag(node, "func", 0, 0);
654 while (n) {
655 const char *sacc;
656
657 sacc=get_struct_property(n, "access", "public");
658 assert(sacc);
659 if (strcasecmp(sacc, acc)==0) {
660 const char *prefix;
661 const char *name;
662 const char *rettype;
663 const char *typ;
664 GWEN_XMLNODE *anode;
665 int isPtr;
666 int idx;
667
668 name=GWEN_XMLNode_GetProperty(n, "name", 0);
669 if (!name) {
670 DBG_ERROR(0, "No name for function");
671 return -1;
672 }
673
674 rettype=GWEN_XMLNode_GetProperty(n, "return", 0);
675 if (!rettype) {
676 DBG_ERROR(0, "No return type for function");
677 return -1;
678 }
679
680 prefix=get_struct_property(n, "prefix", 0);
681 if (!prefix) {
682 DBG_ERROR(0, "No prefix in struct");
683 return -1;
684 }
685
686 isPtr=atoi(get_property(n, "ptr", "0"));
687
688 typ=GWEN_XMLNode_GetProperty(n, "type", 0);
689 if (!typ) {
690 DBG_ERROR(0, "No type for function");
691 return -1;
692 }
693
694 /* typdef rettype (*typ)(args) */
695 GWEN_SyncIo_WriteString(sio, "typedef ");
696 GWEN_SyncIo_WriteString(sio, rettype);
697 if (isPtr)
698 GWEN_SyncIo_WriteString(sio, "*");
699 GWEN_SyncIo_WriteString(sio, " (*");
700 GWEN_SyncIo_WriteString(sio, styp);
701 GWEN_SyncIo_WriteString(sio, "_");
702 GWEN_SyncIo_WriteString(sio, typ);
703 GWEN_SyncIo_WriteString(sio, ")(");
704
705 GWEN_SyncIo_WriteString(sio, styp);
706 GWEN_SyncIo_WriteString(sio, " *st");
707
708 anode=GWEN_XMLNode_FindFirstTag(n, "arg", 0, 0);
709 idx=0;
710 while (anode) {
711 const char *aname;
712 const char *atype;
713 int aisPtr;
714
715 GWEN_SyncIo_WriteString(sio, ", ");
716
717 aisPtr=atoi(GWEN_XMLNode_GetProperty(anode, "ptr", "0"));
718 aname=GWEN_XMLNode_GetProperty(anode, "name", 0);
719 if (!aname || !*aname) {
720 DBG_ERROR(0, "No name for argument %d in function %s", idx, name);
721 return -1;
722 }
723 atype=GWEN_XMLNode_GetProperty(anode, "type", 0);
724 if (!atype || !*atype) {
725 DBG_ERROR(0, "No type for argument %d in function %s", idx, name);
726 return -1;
727 }
728
729 GWEN_SyncIo_WriteString(sio, atype);
730 GWEN_SyncIo_WriteString(sio, " ");
731 if (aisPtr)
732 GWEN_SyncIo_WriteString(sio, "*");
733 GWEN_SyncIo_WriteString(sio, aname);
734
735 idx++;
736 anode=GWEN_XMLNode_FindNextTag(anode, "arg", 0, 0);
737 }
738
739 GWEN_SyncIo_WriteLine(sio, ");");
740 }
741
742 n=GWEN_XMLNode_FindNextTag(n, "func", 0, 0);
743 } /* while functions */
744
745 GWEN_SyncIo_WriteLine(sio, "");
746
747 return 0;
748}
749
750
751
752
754 GWEN_XMLNODE *node,
755 GWEN_SYNCIO *sio,
756 const char *acc,
757 int level)
758{
759 GWEN_XMLNODE *n;
760 int rv;
761 const char *prefix;
762 const char *styp;
763
764 prefix=get_struct_property(node, "prefix", 0);
765 if (!prefix) {
766 DBG_ERROR(0, "No prefix in struct");
767 return -1;
768 }
769 styp=get_struct_property(node, "id", 0);
770 if (!styp) {
771 DBG_ERROR(0, "No id in struct");
772 return -1;
773 }
775 while (n) {
777 if (strcasecmp(GWEN_XMLNode_GetData(n), "group")==0) {
778 const char *name;
779 GWEN_XMLNODE *dn;
780 char numbuf[16];
781
782 name=GWEN_XMLNode_GetProperty(n, "name", 0);
783 if (!name) {
784 DBG_ERROR(0, "No name for element");
785 return -1;
786 }
787
788 snprintf(numbuf, sizeof(numbuf), "%d", level);
789 GWEN_SyncIo_WriteString(sio, "<h");
790 GWEN_SyncIo_WriteString(sio, numbuf);
791 GWEN_SyncIo_WriteString(sio, ">");
792 GWEN_SyncIo_WriteChar(sio, toupper(*name));
793 GWEN_SyncIo_WriteString(sio, name+1);
794 GWEN_SyncIo_WriteString(sio, "</h");
795 GWEN_SyncIo_WriteString(sio, numbuf);
796 GWEN_SyncIo_WriteLine(sio, ">");
797
798 GWEN_SyncIo_WriteLine(sio, "<p>");
799 dn=GWEN_XMLNode_FindFirstTag(n, "descr", 0, 0);
800 if (dn) {
801 if (write_xml_to_bio(dn, sio,
804 DBG_INFO(0, "here");
805 return -1;
806 }
807 }
808 GWEN_SyncIo_WriteLine(sio, "</p>");
809
810 rv=write_apidocrec_c(args, n, sio, acc, level+1);
811 if (rv) {
812 DBG_INFO(0, "here (%d)", rv);
813 return rv;
814 }
815 }
816 else if (strcasecmp(GWEN_XMLNode_GetData(n), "elem")==0) {
817 if (strcasecmp(GWEN_XMLNode_GetProperty(n, "access", "public"),
818 acc)==0) {
819 const char *typ;
820 const char *name;
821 GWEN_XMLNODE *dn;
822 char numbuf[16];
823
824 name=GWEN_XMLNode_GetProperty(n, "name", 0);
825 if (!name) {
826 DBG_ERROR(0, "No name for element");
827 return -1;
828 }
829
830 typ=GWEN_XMLNode_GetProperty(n, "type", 0);
831 if (!typ) {
832 DBG_ERROR(0, "No type for element");
833 return -1;
834 }
835
836 snprintf(numbuf, sizeof(numbuf), "%d", level);
837 GWEN_SyncIo_WriteString(sio, "@anchor ");
838 GWEN_SyncIo_WriteString(sio, styp);
839 GWEN_SyncIo_WriteString(sio, "_");
840 GWEN_SyncIo_WriteChar(sio, toupper(*name));
841 GWEN_SyncIo_WriteLine(sio, name+1);
842
843 GWEN_SyncIo_WriteString(sio, "<h");
844 GWEN_SyncIo_WriteString(sio, numbuf);
845 GWEN_SyncIo_WriteString(sio, ">");
846 GWEN_SyncIo_WriteChar(sio, toupper(*name));
847 GWEN_SyncIo_WriteString(sio, name+1);
848 GWEN_SyncIo_WriteString(sio, "</h");
849 GWEN_SyncIo_WriteString(sio, numbuf);
850 GWEN_SyncIo_WriteLine(sio, ">");
851
852 dn=GWEN_XMLNode_FindFirstTag(n, "brief", 0, 0);
853 if (dn) {
854 GWEN_SyncIo_WriteString(sio, "@short ");
855 if (write_xml_to_bio(dn, sio,
858 DBG_INFO(0, "here");
859 return -1;
860 }
861 GWEN_SyncIo_WriteLine(sio, "");
862 GWEN_SyncIo_WriteLine(sio, "");
863 }
864
865 GWEN_SyncIo_WriteLine(sio, "<p>");
866 dn=GWEN_XMLNode_FindFirstTag(n, "descr", 0, 0);
867 if (dn) {
868 rv=write_xml_to_bio(dn, sio,
871 if (rv) {
872 DBG_INFO(0, "here (%d)", rv);
873 return -1;
874 }
875 }
876 GWEN_SyncIo_WriteLine(sio, "</p>");
877
878 GWEN_SyncIo_WriteLine(sio, "<p>");
879 GWEN_SyncIo_WriteString(sio, "Set this property with @ref ");
880 GWEN_SyncIo_WriteString(sio, prefix);
881 GWEN_SyncIo_WriteString(sio, "_Set");
882 GWEN_SyncIo_WriteChar(sio, toupper(*name));
883 GWEN_SyncIo_WriteString(sio, name+1);
884 GWEN_SyncIo_WriteLine(sio, ", ");
885 GWEN_SyncIo_WriteString(sio, "get it with @ref ");
886 GWEN_SyncIo_WriteString(sio, prefix);
887 GWEN_SyncIo_WriteString(sio, "_Get");
888 GWEN_SyncIo_WriteChar(sio, toupper(*name));
889 GWEN_SyncIo_WriteLine(sio, name+1);
890 GWEN_SyncIo_WriteLine(sio, "</p>");
891 GWEN_SyncIo_WriteLine(sio, "");
892 }
893 }
894 }
896 }
897 return 0;
898}
899
900
901
903 GWEN_XMLNODE *node,
904 GWEN_SYNCIO *sio,
905 const char *acc)
906{
907 const char *prefix;
908 const char *styp;
909 GWEN_XMLNODE *dn;
910 const char *brief;
911 const char *s;
912 int rv;
913
914 prefix=get_struct_property(node, "prefix", 0);
915 if (!prefix) {
916 DBG_ERROR(0, "No prefix in struct");
917 return -1;
918 }
919 styp=get_struct_property(node, "id", 0);
920 if (!styp) {
921 DBG_ERROR(0, "No id in struct");
922 return -1;
923 }
924
925 GWEN_SyncIo_WriteString(sio, "/** @page P_");
926 GWEN_SyncIo_WriteString(sio, styp);
927 GWEN_SyncIo_WriteString(sio, "_");
928 s=acc;
929 while (*s) {
930 GWEN_SyncIo_WriteChar(sio, toupper(*s));
931 s++;
932 }
933 brief=GWEN_XMLNode_GetProperty(node, "name", prefix);
934 GWEN_SyncIo_WriteString(sio, " ");
935 GWEN_SyncIo_WriteString(sio, brief);
936 GWEN_SyncIo_WriteString(sio, " (");
937 GWEN_SyncIo_WriteString(sio, acc);
938 GWEN_SyncIo_WriteLine(sio, ")");
939
940 GWEN_SyncIo_WriteString(sio, "This page describes the properties of ");
941 GWEN_SyncIo_WriteLine(sio, styp);
942
943 dn=GWEN_XMLNode_FindFirstTag(node, "descr", 0, 0);
944 if (dn) {
945 if (write_xml_to_bio(dn, sio,
948 DBG_INFO(0, "here");
949 return -1;
950 }
951 }
952
953 rv=write_apidocrec_c(args, node, sio, acc, 3);
954 if (rv) {
955 DBG_INFO(0, "here (%d)", rv);
956 return rv;
957 }
958
959 GWEN_SyncIo_WriteLine(sio, "*/");
960
961 return 0;
962}
963
964
965
966
968{
969 int rv;
970 GWEN_XMLNODE *n;
971
972 n=GWEN_XMLNode_FindFirstTag(node, "types", 0, 0);
973 if (!n) {
974 DBG_WARN(0, "Empty file");
975 return 0;
976 }
977 rv=write_hp_files_c(args, n);
978 if (rv) {
979 DBG_INFO(0, "here (%d)", rv);
980 return rv;
981 }
982
983 rv=write_hl_files_c(args, n);
984 if (rv) {
985 DBG_INFO(0, "here (%d)", rv);
986 return rv;
987 }
988
989 rv=write_ha_files_c(args, n);
990 if (rv) {
991 DBG_INFO(0, "here (%d)", rv);
992 return rv;
993 }
994
995 rv=write_code_files_c(args, n);
996 if (rv) {
997 DBG_INFO(0, "here (%d)", rv);
998 return rv;
999 }
1000
1001 return 0;
1002}
1003
1004
1005
1006const char *get_function_name2(GWEN_XMLNODE *node, const char *ftype,
1007 const char *name)
1008{
1009 GWEN_XMLNODE *n;
1010
1011 /* find typedef for this type */
1012 n=node;
1013 /* get root */
1014 while (GWEN_XMLNode_GetParent(n))
1016
1017 n=GWEN_XMLNode_FindFirstTag(n, "typedefs", 0, 0);
1018 if (!n)
1019 return 0;
1020 n=GWEN_XMLNode_FindFirstTag(n, "type", "id", name);
1021 if (!n)
1022 return 0;
1023
1024 n=GWEN_XMLNode_FindFirstTag(n, "functions", 0, 0);
1025 if (n) {
1026 n=GWEN_XMLNode_FindFirstTag(n, "function", "type", ftype);
1027 if (n)
1028 return GWEN_XMLNode_GetProperty(n, "name", 0);
1029 }
1030
1031 return 0;
1032}
1033
1034
1035
1036const char *get_function_name(GWEN_XMLNODE *node, const char *ftype)
1037{
1038 GWEN_XMLNODE *n;
1039 const char *name;
1040
1041 n=GWEN_XMLNode_FindFirstTag(node, "functions", 0, 0);
1042 if (n) {
1043 n=GWEN_XMLNode_FindFirstTag(n, "function", "type", ftype);
1044 if (n)
1045 return GWEN_XMLNode_GetProperty(n, "name", 0);
1046 }
1047
1048 name=GWEN_XMLNode_GetProperty(node, "type", 0);
1049 if (!name) {
1050 DBG_ERROR(0, "no type for element");
1051 return 0;
1052 }
1053
1054 /* find typedef for this type */
1055 n=node;
1056 /* get root */
1057 while (GWEN_XMLNode_GetParent(n))
1059
1060 n=GWEN_XMLNode_FindFirstTag(n, "typedefs", 0, 0);
1061 if (!n)
1062 return 0;
1063 n=GWEN_XMLNode_FindFirstTag(n, "type", "id", name);
1064 if (!n)
1065 return 0;
1066
1067 n=GWEN_XMLNode_FindFirstTag(n, "functions", 0, 0);
1068 if (n) {
1069 n=GWEN_XMLNode_FindFirstTag(n, "function", "type", ftype);
1070 if (n)
1071 return GWEN_XMLNode_GetProperty(n, "name", 0);
1072 }
1073
1074 return 0;
1075}
1076
1077
1078
1079GWEN_XMLNODE *get_typedef(GWEN_XMLNODE *node, const char *name)
1080{
1081 GWEN_XMLNODE *n;
1082 GWEN_XMLNODE *n2;
1083
1084 assert(name);
1085 /* find typedef for this type */
1086 n=node;
1087 /* get root */
1088 while (GWEN_XMLNode_GetParent(n))
1090
1091 n2=GWEN_XMLNode_FindFirstTag(n, "typedefs", 0, 0);
1092 if (n2)
1093 n2=GWEN_XMLNode_FindFirstTag(n2, "type", "id", name);
1094 if (n2)
1095 return n2;
1096
1097 n2=GWEN_XMLNode_FindFirstTag(n, "types", 0, 0);
1098 if (n2)
1099 n2=GWEN_XMLNode_FindFirstTag(n2, "type", "id", name);
1100 if (n2)
1101 return n2;
1102
1103 n2=get_struct_node(node);
1104 assert(n2);
1105
1106 n2=GWEN_XMLNode_FindFirstTag(n2, "subtypes", 0, 0);
1107 if (n2)
1108 n2=GWEN_XMLNode_FindFirstTag(n2, "type", "id", name);
1109 if (n2)
1110 return n2;
1111
1112 return 0;
1113}
1114
1115
1116
1117const char *get_property(GWEN_XMLNODE *node,
1118 const char *pname,
1119 const char *defval)
1120{
1121 GWEN_XMLNODE *n;
1122 const char *name;
1123 const char *r;
1124
1125 r=GWEN_XMLNode_GetProperty(node, pname, 0);
1126 if (r)
1127 return r;
1128
1129 name=GWEN_XMLNode_GetProperty(node, "type", 0);
1130 if (!name) {
1131 DBG_ERROR(0, "no type for element");
1132 return defval;
1133 }
1134
1135 /* find typedef for this type */
1136 n=node;
1137 /* get root */
1138 while (GWEN_XMLNode_GetParent(n))
1140
1141 n=GWEN_XMLNode_FindFirstTag(n, "typedefs", 0, 0);
1142 if (!n)
1143 return defval;
1144 n=GWEN_XMLNode_FindFirstTag(n, "type", "id", name);
1145 if (!n)
1146 return defval;
1147
1148 return GWEN_XMLNode_GetProperty(n, pname, defval);
1149}
1150
1151
1152
1154 const char *pname,
1155 const char *defval)
1156{
1157 GWEN_XMLNODE *n;
1158
1160 if (strcasecmp(GWEN_XMLNode_GetData(node), "type")==0) {
1161 return GWEN_XMLNode_GetProperty(node, pname, defval);
1162 }
1163
1164 /* find typedef for this type */
1165 n=GWEN_XMLNode_GetParent(node);
1166 if (n)
1167 return get_struct_property(n, pname, defval);
1168
1169 return defval;
1170}
1171
1172
1173
1175{
1176 while (node) {
1178 if (strcasecmp(GWEN_XMLNode_GetData(node), "type")==0) {
1179 return node;
1180 }
1181 node=GWEN_XMLNode_GetParent(node);
1182 }
1183
1184 return 0;
1185}
1186
1187
1188
1189int main(int argc, char **argv)
1190{
1191 ARGUMENTS *args;
1192 int rv;
1193 FREEPARAM *inFile;
1194
1195 args=Arguments_new();
1196 rv=checkArgs(args, argc, argv);
1197 if (rv==-1) {
1198 fprintf(stderr, "Parameter error\n");
1199 return rv;
1200 }
1201 else if (rv==-2) {
1202 return 0;
1203 }
1204
1205 GWEN_Logger_Open(0, "typemaker",
1206 args->logFile,
1207 args->logType,
1210
1211 inFile=args->params;
1212 if (!inFile) {
1213 fprintf(stderr, "No input file given.\n");
1214 Arguments_free(args);
1215 return 1;
1216 }
1217
1218 /* read all files */
1219 while (inFile) {
1220 GWEN_XMLNODE *n;
1221
1224 fprintf(stderr, "ERROR: Error reading file \"%s\"\n", inFile->param);
1226 return 2;
1227 }
1228
1229 /* write file(s) */
1230 rv=write_files(args, n);
1231 if (rv) {
1232 DBG_ERROR(0, "Error in file \"%s\"", inFile->param);
1234 return 2;
1235 }
1236
1238 inFile=inFile->next;
1239 } /* while */
1240
1241
1242 Arguments_free(args);
1243
1244 return 0;
1245}
1246
1247
1248
1249
int write_ha_files_c(ARGUMENTS *args, GWEN_XMLNODE *node)
Definition ahc.c:541
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition buffer.c:42
uint32_t GWEN_Buffer_GetPos(const GWEN_BUFFER *bf)
Definition buffer.c:253
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition buffer.c:89
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition buffer.c:992
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition buffer.c:277
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition buffer.c:235
int GWEN_Buffer_Crop(GWEN_BUFFER *bf, uint32_t pos, uint32_t l)
Definition buffer.c:950
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition buffer.c:393
int write_code_files_c(ARGUMENTS *args, GWEN_XMLNODE *node)
Definition code_c.c:3008
#define DBG_INFO(dbg_logger, format,...)
Definition debug.h:181
#define DBG_ERROR(dbg_logger, format,...)
Definition debug.h:97
#define DBG_ERROR_ERR(dbg_logger, dbg_err)
Definition debug.h:113
#define DBG_WARN(dbg_logger, format,...)
Definition debug.h:125
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition buffer.h:38
#define GWEN_UNUSED
int write_hl_files_c(ARGUMENTS *args, GWEN_XMLNODE *node)
Definition lhc.c:403
int GWEN_Logger_Open(const char *logDomain, const char *ident, const char *file, GWEN_LOGGER_LOGTYPE logtype, GWEN_LOGGER_FACILITY facility)
Definition logger.c:281
void GWEN_Logger_SetLevel(const char *logDomain, GWEN_LOGGER_LEVEL l)
Definition logger.c:472
@ GWEN_LoggerFacility_User
Definition logger.h:55
int write_hp_files_c(ARGUMENTS *args, GWEN_XMLNODE *node)
Definition phc.c:509
const char * domain
GWEN_LOGGER_LEVEL logLevel
GWEN_LOGGER_LOGTYPE logType
FREEPARAM * params
const char * param
FREEPARAM * next
int GWEN_SyncIo_WriteString(GWEN_SYNCIO *sio, const char *s)
Definition syncio.c:392
int GWEN_SyncIo_WriteChar(GWEN_SYNCIO *sio, char s)
Definition syncio.c:431
int GWEN_SyncIo_WriteLine(GWEN_SYNCIO *sio, const char *s)
Definition syncio.c:407
int GWEN_SyncIo_WriteForced(GWEN_SYNCIO *sio, const uint8_t *buffer, uint32_t size)
Definition syncio.c:317
struct GWEN_SYNCIO GWEN_SYNCIO
Definition syncio.h:40
ARGUMENTS * Arguments_new()
void Arguments_free(ARGUMENTS *ar)
int checkArgs(ARGUMENTS *args, int argc, char **argv)
struct _S_PARAM FREEPARAM
struct _S_ARGS ARGUMENTS
int write_h_setget_c(ARGUMENTS *args, GWEN_XMLNODE *node, GWEN_SYNCIO *sio, const char *acc)
GWEN_XMLNODE * get_typedef(GWEN_XMLNODE *node, const char *name)
int main(int argc, char **argv)
void write_if_nonnull(GWEN_SYNCIO *sio, const char *str)
int write_files(ARGUMENTS *args, GWEN_XMLNODE *node)
const char * get_property(GWEN_XMLNODE *node, const char *pname, const char *defval)
const char * get_function_name(GWEN_XMLNODE *node, const char *ftype)
int write_h_enums(ARGUMENTS *args, GWEN_XMLNODE *node, GWEN_SYNCIO *sio, const char *acc)
int write_xml_to_bio(GWEN_XMLNODE *n, GWEN_SYNCIO *sio, uint32_t flags)
int write_h_funcs(GWEN_UNUSED ARGUMENTS *args, GWEN_XMLNODE *node, GWEN_SYNCIO *sio, const char *acc)
int write_h_header(GWEN_UNUSED ARGUMENTS *args, GWEN_XMLNODE *node, GWEN_SYNCIO *sio, GWEN_UNUSED const char *where)
int write_apidocrec_c(ARGUMENTS *args, GWEN_XMLNODE *node, GWEN_SYNCIO *sio, const char *acc, int level)
GWEN_XMLNODE * get_struct_node(GWEN_XMLNODE *node)
const char * get_function_name2(GWEN_XMLNODE *node, const char *ftype, const char *name)
const char * get_struct_property(GWEN_XMLNODE *node, const char *pname, const char *defval)
int write_apidoc_c(ARGUMENTS *args, GWEN_XMLNODE *node, GWEN_SYNCIO *sio, const char *acc)
const char * GWEN_XMLNode_GetProperty(const GWEN_XMLNODE *n, const char *name, const char *defaultValue)
Definition xml.c:239
GWEN_XMLNODE * GWEN_XMLNode_FindFirstTag(const GWEN_XMLNODE *n, const char *tname, const char *pname, const char *pvalue)
Definition xml.c:776
GWEN_XMLNODE * GWEN_XMLNode_GetParent(const GWEN_XMLNODE *n)
Definition xml.c:416
GWEN_XMLNODE * GWEN_XMLNode_GetFirstTag(const GWEN_XMLNODE *n)
Definition xml.c:705
GWEN_XMLNODE_TYPE GWEN_XMLNode_GetType(const GWEN_XMLNODE *n)
Definition xml.c:458
GWEN_XMLNODE * GWEN_XMLNode_new(GWEN_XMLNODE_TYPE t, const char *data)
Definition xml.c:144
GWEN_XMLNODE * GWEN_XMLNode_GetNextTag(const GWEN_XMLNODE *n)
Definition xml.c:712
GWEN_XMLNODE * GWEN_XMLNode_FindNextTag(const GWEN_XMLNODE *n, const char *tname, const char *pname, const char *pvalue)
Definition xml.c:794
GWEN_XMLNODE * GWEN_XMLNode_GetFirstData(const GWEN_XMLNODE *n)
Definition xml.c:724
void GWEN_XMLNode_free(GWEN_XMLNODE *n)
Definition xml.c:160
const char * GWEN_XMLNode_GetData(const GWEN_XMLNODE *n)
Definition xml.c:370
GWENHYWFAR_API int GWEN_XMLNode_toBuffer(const GWEN_XMLNODE *n, GWEN_BUFFER *buf, uint32_t flags)
Definition xmlrw.c:627
#define GWEN_XML_FLAGS_INDENT
Definition xml.h:66
struct GWEN__XMLNODE GWEN_XMLNODE
Definition xml.h:156
#define GWEN_XML_FLAGS_DEFAULT
Definition xml.h:117
GWENHYWFAR_API int GWEN_XML_ReadFile(GWEN_XMLNODE *n, const char *filepath, uint32_t flags)
Definition xmlrw.c:1298
@ GWEN_XMLNodeTypeTag
Definition xml.h:145
#define GWEN_XML_FLAGS_SIMPLE
Definition xml.h:89