gwenhywfar 5.12.0
plugindescr.c
Go to the documentation of this file.
1/***************************************************************************
2 begin : Thu Apr 03 2003
3 copyright : (C) 2022 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
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., 59 Temple Place, Suite 330, Boston, *
21 * MA 02111-1307 USA *
22 * *
23 ***************************************************************************/
24
25#ifdef HAVE_CONFIG_H
26# include <config.h>
27#endif
28
29#define DISABLE_DEBUGLOG
30
31
32#include "plugindescr_p.h"
33#include "i18n_l.h"
34#include <gwenhywfar/buffer.h>
35#include <gwenhywfar/debug.h>
36#include <gwenhywfar/directory.h>
37#include <gwenhywfar/i18n.h>
38
39
40
41GWEN_LIST_FUNCTIONS(GWEN_PLUGIN_DESCRIPTION, GWEN_PluginDescription)
42GWEN_LIST2_FUNCTIONS(GWEN_PLUGIN_DESCRIPTION, GWEN_PluginDescription)
43
44
45
47
48static int _getLongDescrByFormat(const GWEN_PLUGIN_DESCRIPTION *pd, const char *s, GWEN_BUFFER *buf);
49static GWEN_PLUGIN_DESCRIPTION *_readPluginDescriptionFromFile(const char *folder, const char *fullFileName, const char *pluginType);
51
52
53
54
56{
58
60 pd->refCount=1;
61 DBG_MEM_INC("GWEN_PLUGIN_DESCRIPTION", 0);
63 return pd;
64}
65
66
67
69{
71 const char *p;
72
74 p=GWEN_XMLNode_GetProperty(node, "name", 0);
75 if (!p) {
76 DBG_ERROR(GWEN_LOGDOMAIN, "Unnamed plugin");
78 return 0;
79 }
80 pd->name=strdup(p);
81 pd->xmlNode=GWEN_XMLNode_dup(node);
82
83 p=GWEN_XMLNode_GetProperty(node, "i18n", NULL);
84 if (!p) {
85 DBG_NOTICE(GWEN_LOGDOMAIN, "Plugin has no I18N domain, using GWEN");
86 p="gwenhywfar";
87 }
88 pd->langDomain=strdup(p);
89
90 p=GWEN_XMLNode_GetProperty(node, "type", 0);
91 if (!p) {
92 DBG_ERROR(GWEN_LOGDOMAIN, "Plugin has no type");
94 return 0;
95 }
96 pd->type=strdup(p);
97
98 p=GWEN_XMLNode_GetCharValue(node, "version", 0);
99 if (p)
100 pd->version=strdup(p);
101 p=GWEN_XMLNode_GetCharValue(node, "author", 0);
102 if (p)
103 pd->author=strdup(p);
104 p=GWEN_XMLNode_GetCharValue(node, "short", 0);
105 if (p)
106 pd->shortDescr=strdup(p);
107 p=GWEN_XMLNode_GetCharValue(node, "descr", 0);
108 if (p)
109 pd->longDescr=strdup(p);
110 return pd;
111}
112
113
114
116{
117 if (pd) {
118 assert(pd->refCount);
119 if (pd->refCount==1) {
120 DBG_MEM_DEC("GWEN_PLUGIN_DESCRIPTION");
122 free(pd->path);
123 GWEN_XMLNode_free(pd->xmlNode);
124 free(pd->fileName);
125 free(pd->longDescr);
126 free(pd->shortDescr);
127 free(pd->author);
128 free(pd->version);
129 free(pd->langDomain);
130 free(pd->type);
131 free(pd->name);
132 pd->refCount=0;
134 }
135 else
136 pd->refCount--;
137 }
138}
139
140
141
143{
144 assert(pd);
145 assert(pd->refCount);
146 pd->refCount++;
147}
148
149
150
152{
154 const char *s;
155
156 assert(pd);
158 np->refCount=1;
159 DBG_MEM_INC("GWEN_PLUGIN_DESCRIPTION", 0);
161
162 s=pd->fileName;
163 if (s)
164 np->fileName=strdup(s);
165
166 s=pd->path;
167 if (s)
168 np->path=strdup(s);
169 s=pd->name;
170 if (s)
171 np->name=strdup(s);
172 s=pd->type;
173 if (s)
174 np->type=strdup(s);
175 s=pd->langDomain;
176 if (s)
177 np->langDomain=strdup(s);
178 s=pd->shortDescr;
179 if (s)
180 np->shortDescr=strdup(s);
181 s=pd->author;
182 if (s)
183 np->author=strdup(s);
184 s=pd->version;
185 if (s)
186 np->version=strdup(s);
187 s=pd->longDescr;
188 if (s)
189 np->longDescr=strdup(s);
190 np->isActive=pd->isActive;
191
192 if (pd->xmlNode)
193 np->xmlNode=GWEN_XMLNode_dup(pd->xmlNode);
194
195 return np;
196}
197
198
199
205
206
207
213
214
215
217{
218 assert(pd);
219 return pd->path;
220}
221
222
223
225{
226 assert(pd);
227 free(pd->path);
228 if (s)
229 pd->path=strdup(s);
230 else
231 pd->path=0;
232}
233
234
235
237{
238 assert(pd);
239 return pd->name;
240}
241
242
243
245{
246 assert(pd);
247 free(pd->name);
248 pd->name=s?strdup(s):NULL;
249}
250
251
252
254{
255 assert(pd);
256 return pd->type;
257}
258
259
260
262{
263 assert(pd);
264 free(pd->type);
265 pd->type=s?strdup(s):NULL;
266}
267
268
269
271{
272 assert(pd);
273 return GWEN_I18N_Translate(pd->langDomain, pd->shortDescr);
274}
275
276
277
279{
280 assert(pd);
281 free(pd->shortDescr);
282 pd->shortDescr=s?strdup(s):NULL;
283}
284
285
286
288{
289 assert(pd);
290 return pd->author;
291}
292
293
294
296{
297 assert(pd);
298 free(pd->author);
299 pd->author=s?strdup(s):NULL;
300}
301
302
303
305{
306 assert(pd);
307 return pd->version;
308}
309
310
311
313{
314 assert(pd);
315 free(pd->version);
316 pd->version=s?strdup(s):NULL;
317}
318
319
320
322{
323 assert(pd);
324 return GWEN_I18N_Translate(pd->langDomain, pd->longDescr);
325}
326
327
328
330{
331 assert(pd);
332 free(pd->longDescr);
333 pd->longDescr=s?strdup(s):NULL;
334}
335
336
337
339{
340 assert(pd);
341 if (pd->xmlNode) {
342 GWEN_XMLNODE *n;
343
344 n=GWEN_XMLNode_FindFirstTag(pd->xmlNode, "descr", 0, 0);
345 if (n) {
346 n=GWEN_XMLNode_FindFirstTag(n, "text", "format", s);
347 while (n) {
348 if (0==GWEN_XMLNode_GetProperty(n, "lang", 0)) {
349 int rv;
350
352 if (rv) {
353 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
354 return rv;
355 }
356 return 0;
357 }
358 n=GWEN_XMLNode_FindNextTag(n, "text", "format", s);
359 } /* while */
360 }
361 }
362 return GWEN_ERROR_GENERIC;
363}
364
365
366
367#ifndef NO_DEPRECATED_SYMBOLS
368static int _getLocalizedLongDescrByFormat(const GWEN_PLUGIN_DESCRIPTION *pd, const char *s, const char *lang, GWEN_BUFFER *buf)
369{
370 assert(pd);
371
372 if (pd->xmlNode) {
373 GWEN_XMLNODE *n;
374
375 n=GWEN_XMLNode_FindFirstTag(pd->xmlNode, "descr", 0, 0);
376 if (n) {
377 n=GWEN_XMLNode_FindFirstTag(n, "text", "lang", lang);
378 while (n) {
379 const char *fmt;
380
381 fmt=GWEN_XMLNode_GetProperty(n, "format", 0);
382 if (fmt && strcasecmp(fmt, s)==0) {
383 int rv;
384
386 if (rv) {
387 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
388 return rv;
389 }
390 return 0;
391 }
392 n=GWEN_XMLNode_FindNextTag(n, "text", "lang", lang);
393 } /* while */
394 }
395 }
396
397 return GWEN_ERROR_GENERIC;
398}
399
400
401
403{
404 GWEN_STRINGLIST *langl;
405 int rv;
406
408 if (langl) {
410
412 while (se) {
413 const char *l;
414
416 DBG_NOTICE(GWEN_LOGDOMAIN, "Trying locale \"%s\"", l);
417 assert(l);
418
419 rv=_getLocalizedLongDescrByFormat(pd, s, l, buf);
420 if (rv==0)
421 return rv;
422
424 } /* while */
425 } /* if language list available */
426
427 /* no localized version found, return text for default language */
428 rv=_getLongDescrByFormat(pd, s, buf);
429 if (rv) {
430 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
431 return rv;
432 }
433
434 return 0;
435}
436#endif // ifndef NO_DEPRECATED_SYMBOLS
437
438
439
441{
442 assert(pd);
443 return pd->fileName;
444}
445
446
447
449{
450 assert(pd);
451 free(pd->fileName);
452 if (s)
453 pd->fileName=strdup(s);
454 else
455 pd->fileName=0;
456}
457
458
459
461{
462 assert(pd);
463 return pd->xmlNode;
464}
465
466
467
469{
471
473
474 GWEN_LoadPluginDescrsByType(path, 0, pl);
477 return 0;
478 }
479 return pl;
480}
481
482
483
485{
486 assert(pd);
487 return pd->isActive;
488}
489
490
491
493{
494 assert(pd);
495 pd->isActive=i;
496}
497
498
499
500int GWEN_LoadPluginDescrsByType(const char *folder, const char *pluginType, GWEN_PLUGIN_DESCRIPTION_LIST2 *pdl)
501{
502 GWEN_STRINGLIST *fileNameList;
503 int rv;
504
505 fileNameList=GWEN_StringList_new();
506 rv=GWEN_Directory_GetFileEntries(folder?folder:"", fileNameList, "*.xml");
507 if (rv<0) {
508 DBG_INFO(GWEN_LOGDOMAIN, "No matching files found in %s", folder?folder:"<empty>");
509 GWEN_StringList_free(fileNameList);
510 return rv;
511 }
512
513 if (GWEN_StringList_Count(fileNameList)) {
515
516 se=GWEN_StringList_FirstEntry(fileNameList);
517 if (se) {
518 GWEN_BUFFER *nbuf;
519 unsigned int pathLen;
520
521 nbuf=GWEN_Buffer_new(0, 256, 0, 1);
522 if (folder && *folder) {
523 GWEN_Buffer_AppendString(nbuf, folder);
525 }
526 pathLen=GWEN_Buffer_GetUsedBytes(nbuf);
527
528 while(se) {
529 const char *fileName;
530
531 fileName=GWEN_StringListEntry_Data(se);
532 DBG_INFO(GWEN_LOGDOMAIN, "Checking entry \"%s\" (%s)\n", fileName, GWEN_Buffer_GetStart(nbuf));
533 if (fileName && *fileName) {
535
536 GWEN_Buffer_AppendString(nbuf, fileName);
537 pd=_readPluginDescriptionFromFile(folder, GWEN_Buffer_GetStart(nbuf), pluginType);
538 if (pd) {
540 "Adding loaded plugin description %s/%s (%s)",
543 }
544 else {
545 DBG_INFO(GWEN_LOGDOMAIN, "Could not read description from \"%s\"\n", fileName);
546 }
547 GWEN_Buffer_Crop(nbuf, 0, pathLen);
548 GWEN_Buffer_SetPos(nbuf, pathLen);
549 }
551 } /* while(se) */
552 GWEN_Buffer_free(nbuf);
553 } /* if (se) */
554 } /* if stringlist not empty */
555 else {
556 DBG_INFO(GWEN_LOGDOMAIN, "Not matching files in \"%s\"\n", folder);
557 }
558 GWEN_StringList_free(fileNameList);
559 return 0;
560}
561
562
563
564GWEN_PLUGIN_DESCRIPTION *_readPluginDescriptionFromFile(const char *folder, const char *fullFileName, const char *pluginType)
565{
566 GWEN_XMLNODE *fileNode;
567
568 fileNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "root");
569 if (GWEN_XML_ReadFile(fileNode, fullFileName,
571 DBG_WARN(GWEN_LOGDOMAIN, "Bad file \"%s\"", fullFileName);
572 }
573 else {
574 GWEN_XMLNODE *pluginDescrNode;
575 GWEN_XMLNODE *pluginNode=NULL;
576
577 pluginDescrNode=GWEN_XMLNode_FindFirstTag(fileNode, "PluginDescr", NULL, NULL);
578 if (!pluginDescrNode)
579 pluginDescrNode=fileNode;
580
581 pluginNode=_getLocalOrMainPluginNode(pluginDescrNode);
582 if (pluginNode) {
584 int typeMatches=1;
585
586 if (pluginType) {
587 const char *ft;
588
589 ft=GWEN_XMLNode_GetProperty(pluginNode, "type", NULL);
590 if (!ft)
591 typeMatches=0;
592 else if (strcasecmp(ft, pluginType)!=0) {
593 typeMatches=0;
594 }
595 } /* if pluginType specified */
596 if (typeMatches) {
597 pd=GWEN_PluginDescription_fromXml(pluginNode);
598 if (!pd) {
599 DBG_WARN(GWEN_LOGDOMAIN, "Bad plugin description");
600 }
601 else {
602 GWEN_PluginDescription_SetFileName(pd, fullFileName);
604 GWEN_XMLNode_free(fileNode);
605 return pd;
606 }
607 } /* if typeMatches */
608 else {
609 DBG_INFO(GWEN_LOGDOMAIN, "Ignoring file \"%s\" (bad/missing pluginType)", fullFileName);
610 }
611 }
612 else {
613 DBG_WARN(GWEN_LOGDOMAIN, "File \"%s\" does not contain a plugin description", fullFileName);
614 }
615 }
616 GWEN_XMLNode_free(fileNode);
617 return NULL;
618}
619
620
621
623{
625 GWEN_STRINGLIST *languageList;
626
627 languageList=GWEN_I18N_GetCurrentLocaleList();
628 if (languageList) {
630
631 se=GWEN_StringList_FirstEntry(languageList);
632 while (se) {
633 const char *l;
634
636 DBG_DEBUG(GWEN_LOGDOMAIN, "Trying locale \"%s\"", l);
637 assert(l);
638 n=GWEN_XMLNode_FindFirstTag(pluginDescrNode, "plugin", "lang", l);
639 if (n)
640 break;
642 } /* while */
643 } /* if language list available */
644
645 if (!n)
646 n=GWEN_XMLNode_FindFirstTag(pluginDescrNode, "plugin", 0, 0);
647
648 return n;
649}
650
651
652
653
654
655
656
657
#define NULL
Definition binreloc.c:300
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition buffer.c:42
int GWEN_Buffer_SetPos(GWEN_BUFFER *bf, uint32_t i)
Definition buffer.c:261
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
GWENHYWFAR_API const char * fmt
Definition buffer.h:283
#define DBG_MEM_INC(o, attach)
Definition debug.h:87
#define DBG_INFO(dbg_logger, format,...)
Definition debug.h:181
#define DBG_NOTICE(dbg_logger, format,...)
Definition debug.h:152
#define DBG_ERROR(dbg_logger, format,...)
Definition debug.h:97
#define DBG_WARN(dbg_logger, format,...)
Definition debug.h:125
#define DBG_MEM_DEC(o)
Definition debug.h:88
#define DBG_DEBUG(dbg_logger, format,...)
Definition debug.h:214
GWENHYWFAR_API int GWEN_Directory_GetFileEntries(const char *folder, GWEN_STRINGLIST *sl, const char *mask)
#define GWEN_ERROR_GENERIC
Definition error.h:62
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition buffer.h:38
#define GWEN_UNUSED
#define GWEN_DIR_SEPARATOR_S
GWEN_STRINGLIST * GWEN_I18N_GetCurrentLocaleList(void)
Definition i18n.c:241
const char * GWEN_I18N_Translate(const char *txtdom, const char *text)
Definition i18n.c:255
#define GWEN_LIST_FINI(t, element)
Definition list1.h:475
#define GWEN_LIST_FUNCTIONS(t, pr)
Definition list1.h:367
#define GWEN_LIST_INIT(t, element)
Definition list1.h:466
#define GWEN_LIST2_FUNCTIONS(t, pr)
Definition list2.h:99
struct GWEN_PLUGIN_DESCRIPTION_LIST2 GWEN_PLUGIN_DESCRIPTION_LIST2
Definition listdoc.h:6538
GWEN_PLUGIN_DESCRIPTION * GWEN_PluginDescription_List2_ForEach(GWEN_PLUGIN_DESCRIPTION_LIST2 *list, GWEN_PLUGIN_DESCRIPTION_LIST2_FOREACH func, void *user_data)
unsigned int GWEN_PluginDescription_List2_GetSize(GWEN_PLUGIN_DESCRIPTION_LIST2 *l)
void GWEN_PluginDescription_List2_PushBack(GWEN_PLUGIN_DESCRIPTION_LIST2 *l, GWEN_PLUGIN_DESCRIPTION *p)
void GWEN_PluginDescription_List2_free(GWEN_PLUGIN_DESCRIPTION_LIST2 *l)
GWEN_PLUGIN_DESCRIPTION_LIST2 * GWEN_PluginDescription_List2_new()
#define GWEN_LOGDOMAIN
Definition logger.h:35
#define GWEN_FREE_OBJECT(varname)
Definition memory.h:61
#define GWEN_NEW_OBJECT(typ, varname)
Definition memory.h:55
const char * GWEN_PluginDescription_GetVersion(const GWEN_PLUGIN_DESCRIPTION *pd)
void GWEN_PluginDescription_SetVersion(GWEN_PLUGIN_DESCRIPTION *pd, const char *s)
int GWEN_PluginDescription_GetLongDescrByFormat(const GWEN_PLUGIN_DESCRIPTION *pd, const char *s, GWEN_BUFFER *buf)
void GWEN_PluginDescription_SetAuthor(GWEN_PLUGIN_DESCRIPTION *pd, const char *s)
void GWEN_PluginDescription_SetName(GWEN_PLUGIN_DESCRIPTION *pd, const char *s)
void GWEN_PluginDescription_SetIsActive(GWEN_PLUGIN_DESCRIPTION *pd, int i)
GWEN_PLUGIN_DESCRIPTION * GWEN_PluginDescription_new(void)
Definition plugindescr.c:55
const char * GWEN_PluginDescription_GetType(const GWEN_PLUGIN_DESCRIPTION *pd)
void GWEN_PluginDescription_SetPath(GWEN_PLUGIN_DESCRIPTION *pd, const char *s)
static GWEN_XMLNODE * _getLocalOrMainPluginNode(GWEN_XMLNODE *pluginDescrNode)
GWEN_PLUGIN_DESCRIPTION * GWEN_PluginDescription_fromXml(GWEN_XMLNODE *node)
Definition plugindescr.c:68
void GWEN_PluginDescription_List2_freeAll(GWEN_PLUGIN_DESCRIPTION_LIST2 *pdl)
void GWEN_PluginDescription_free(GWEN_PLUGIN_DESCRIPTION *pd)
void GWEN_PluginDescription_Attach(GWEN_PLUGIN_DESCRIPTION *pd)
void GWEN_PluginDescription_SetFileName(GWEN_PLUGIN_DESCRIPTION *pd, const char *s)
static int _getLongDescrByFormat(const GWEN_PLUGIN_DESCRIPTION *pd, const char *s, GWEN_BUFFER *buf)
void GWEN_PluginDescription_SetType(GWEN_PLUGIN_DESCRIPTION *pd, const char *s)
GWEN_XMLNODE * GWEN_PluginDescription_GetXmlNode(const GWEN_PLUGIN_DESCRIPTION *pd)
const char * GWEN_PluginDescription_GetAuthor(const GWEN_PLUGIN_DESCRIPTION *pd)
const char * GWEN_PluginDescription_GetPath(const GWEN_PLUGIN_DESCRIPTION *pd)
void GWEN_PluginDescription_SetLongDescr(GWEN_PLUGIN_DESCRIPTION *pd, const char *s)
static GWEN_PLUGIN_DESCRIPTION * _readPluginDescriptionFromFile(const char *folder, const char *fullFileName, const char *pluginType)
static int _getLocalizedLongDescrByFormat(const GWEN_PLUGIN_DESCRIPTION *pd, const char *s, const char *lang, GWEN_BUFFER *buf)
static GWEN_PLUGIN_DESCRIPTION * _pdList2_freeAll_cb(GWEN_PLUGIN_DESCRIPTION *pd, void *)
const char * GWEN_PluginDescription_GetFileName(const GWEN_PLUGIN_DESCRIPTION *pd)
int GWEN_LoadPluginDescrsByType(const char *folder, const char *pluginType, GWEN_PLUGIN_DESCRIPTION_LIST2 *pdl)
int GWEN_PluginDescription_IsActive(const GWEN_PLUGIN_DESCRIPTION *pd)
const char * GWEN_PluginDescription_GetName(const GWEN_PLUGIN_DESCRIPTION *pd)
const char * GWEN_PluginDescription_GetLongDescr(const GWEN_PLUGIN_DESCRIPTION *pd)
GWEN_PLUGIN_DESCRIPTION * GWEN_PluginDescription_dup(const GWEN_PLUGIN_DESCRIPTION *pd)
void GWEN_PluginDescription_SetShortDescr(GWEN_PLUGIN_DESCRIPTION *pd, const char *s)
GWEN_PLUGIN_DESCRIPTION_LIST2 * GWEN_LoadPluginDescrs(const char *path)
const char * GWEN_PluginDescription_GetShortDescr(const GWEN_PLUGIN_DESCRIPTION *pd)
struct GWEN_PLUGIN_DESCRIPTION GWEN_PLUGIN_DESCRIPTION
Definition plugindescr.h:38
void GWEN_StringList_free(GWEN_STRINGLIST *sl)
Definition stringlist.c:62
const char * GWEN_StringListEntry_Data(const GWEN_STRINGLISTENTRY *se)
Definition stringlist.c:406
GWEN_STRINGLISTENTRY * GWEN_StringListEntry_Next(const GWEN_STRINGLISTENTRY *se)
Definition stringlist.c:398
unsigned int GWEN_StringList_Count(const GWEN_STRINGLIST *sl)
Definition stringlist.c:427
GWEN_STRINGLISTENTRY * GWEN_StringList_FirstEntry(const GWEN_STRINGLIST *sl)
Definition stringlist.c:390
GWEN_STRINGLIST * GWEN_StringList_new(void)
Definition stringlist.c:50
struct GWEN_STRINGLISTENTRYSTRUCT GWEN_STRINGLISTENTRY
Definition stringlist.h:53
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition stringlist.h:56
GWEN_XMLNODE * GWEN_XMLNode_dup(const GWEN_XMLNODE *n)
Definition xml.c:187
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_new(GWEN_XMLNODE_TYPE t, const char *data)
Definition xml.c:144
GWEN_XMLNODE * GWEN_XMLNode_FindNextTag(const GWEN_XMLNODE *n, const char *tname, const char *pname, const char *pvalue)
Definition xml.c:794
const char * GWEN_XMLNode_GetCharValue(const GWEN_XMLNODE *n, const char *name, const char *defValue)
Definition xml.c:812
void GWEN_XMLNode_free(GWEN_XMLNODE *n)
Definition xml.c:160
#define GWEN_XML_FLAGS_TOLERANT_ENDTAGS
Definition xml.h:103
GWENHYWFAR_API int GWEN_XMLNode_toBuffer(const GWEN_XMLNODE *n, GWEN_BUFFER *buf, uint32_t flags)
Definition xmlrw.c:627
#define GWEN_XML_FLAGS_HANDLE_HEADERS
Definition xml.h:94
struct GWEN__XMLNODE GWEN_XMLNODE
Definition xml.h:156
#define GWEN_XML_FLAGS_HANDLE_OPEN_HTMLTAGS
Definition xml.h:73
#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