gwenhywfar  5.10.1
plugindescr.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Thu Apr 03 2003
3  copyright : (C) 2003-2010 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 #include <sys/types.h>
40 #include <sys/stat.h>
41 #ifdef HAVE_UNISTD_H
42 # include <unistd.h>
43 #endif
44 #include <errno.h>
45 #include <string.h>
46 #ifdef HAVE_STRINGS_H
47 # include <strings.h>
48 #endif
49 
50 
51 
52 GWEN_LIST_FUNCTIONS(GWEN_PLUGIN_DESCRIPTION, GWEN_PluginDescription)
53 GWEN_LIST2_FUNCTIONS(GWEN_PLUGIN_DESCRIPTION, GWEN_PluginDescription)
54 
55 
56 
58 {
60  const char *p;
61 
63  pd->refCount=1;
64  DBG_MEM_INC("GWEN_PLUGIN_DESCRIPTION", 0);
66  p=GWEN_XMLNode_GetProperty(node, "name", 0);
67  if (!p) {
68  DBG_ERROR(GWEN_LOGDOMAIN, "Unnamed plugin");
70  return 0;
71  }
72  pd->name=strdup(p);
73  pd->xmlNode=GWEN_XMLNode_dup(node);
74 
75  p=GWEN_XMLNode_GetProperty(node, "i18n", NULL);
76  if (!p) {
77  DBG_NOTICE(GWEN_LOGDOMAIN, "Plugin has no I18N domain, using GWEN");
78  p="gwenhywfar";
79  }
80  pd->langDomain=strdup(p);
81 
82  p=GWEN_XMLNode_GetProperty(node, "type", 0);
83  if (!p) {
84  DBG_ERROR(GWEN_LOGDOMAIN, "Plugin has no type");
86  return 0;
87  }
88  pd->type=strdup(p);
89 
90  p=GWEN_XMLNode_GetCharValue(node, "version", 0);
91  if (p)
92  pd->version=strdup(p);
93  p=GWEN_XMLNode_GetCharValue(node, "author", 0);
94  if (p)
95  pd->author=strdup(p);
96  p=GWEN_XMLNode_GetCharValue(node, "short", 0);
97  if (p)
98  pd->shortDescr=strdup(p);
99  p=GWEN_XMLNode_GetCharValue(node, "descr", 0);
100  if (p)
101  pd->longDescr=strdup(p);
102  return pd;
103 }
104 
105 
106 
108 {
109  if (pd) {
110  assert(pd->refCount);
111  if (pd->refCount==1) {
112  DBG_MEM_DEC("GWEN_PLUGIN_DESCRIPTION");
114  free(pd->path);
115  GWEN_XMLNode_free(pd->xmlNode);
116  free(pd->fileName);
117  free(pd->longDescr);
118  free(pd->shortDescr);
119  free(pd->author);
120  free(pd->version);
121  free(pd->langDomain);
122  free(pd->type);
123  free(pd->name);
124  pd->refCount=0;
125  GWEN_FREE_OBJECT(pd);
126  }
127  else
128  pd->refCount--;
129  }
130 }
131 
132 
133 
135 {
136  assert(pd);
137  assert(pd->refCount);
138  pd->refCount++;
139 }
140 
141 
142 
144 {
146  const char *s;
147 
148  assert(pd);
150  np->refCount=1;
151  DBG_MEM_INC("GWEN_PLUGIN_DESCRIPTION", 0);
153 
154  s=pd->fileName;
155  if (s)
156  np->fileName=strdup(s);
157 
158  s=pd->path;
159  if (s)
160  np->path=strdup(s);
161  s=pd->name;
162  if (s)
163  np->name=strdup(s);
164  s=pd->type;
165  if (s)
166  np->type=strdup(s);
167  s=pd->langDomain;
168  if (s)
169  np->langDomain=strdup(s);
170  s=pd->shortDescr;
171  if (s)
172  np->shortDescr=strdup(s);
173  s=pd->author;
174  if (s)
175  np->author=strdup(s);
176  s=pd->version;
177  if (s)
178  np->version=strdup(s);
179  s=pd->longDescr;
180  if (s)
181  np->longDescr=strdup(s);
182  np->isActive=pd->isActive;
183  if (pd->xmlNode)
184  np->xmlNode=GWEN_XMLNode_dup(pd->xmlNode);
185 
186  return np;
187 }
188 
189 
190 
192  __attribute__((unused)) void *user_data)
193 {
195  return 0;
196 }
197 
198 
199 
201 {
203  (pdl,
205  0);
207 }
208 
209 
210 
212 {
213  assert(pd);
214  return pd->path;
215 }
216 
217 
218 
220  const char *s)
221 {
222  assert(pd);
223  free(pd->path);
224  if (s)
225  pd->path=strdup(s);
226  else
227  pd->path=0;
228 }
229 
230 
231 
233 {
234  assert(pd);
235  return pd->name;
236 }
237 
238 
239 
241 {
242  assert(pd);
243  return pd->type;
244 }
245 
246 
247 
249 {
250  assert(pd);
251  return GWEN_I18N_Translate(pd->langDomain, pd->shortDescr);
252 }
253 
254 
255 
257 {
258  assert(pd);
259  return pd->author;
260 }
261 
262 
263 
265 {
266  assert(pd);
267  return pd->version;
268 }
269 
270 
271 
273 {
274  assert(pd);
275  return GWEN_I18N_Translate(pd->langDomain, pd->longDescr);
276 }
277 
278 
279 
281  const char *s,
282  GWEN_BUFFER *buf)
283 {
284  GWEN_XMLNODE *n;
285 
286  assert(pd);
287  assert(pd->xmlNode);
288 
289  n=GWEN_XMLNode_FindFirstTag(pd->xmlNode, "descr", 0, 0);
290  if (n) {
291  n=GWEN_XMLNode_FindFirstTag(n, "text", "format", s);
292  while (n) {
293  if (0==GWEN_XMLNode_GetProperty(n, "lang", 0)) {
294  int rv;
295 
297  if (rv) {
298  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
299  return rv;
300  }
301  return 0;
302  }
303  n=GWEN_XMLNode_FindNextTag(n, "text", "format", s);
304  } /* while */
305  }
306 
307  return -1;
308 }
309 
310 
311 
313  const char *s,
314  const char *lang,
315  GWEN_BUFFER *buf)
316 {
317  GWEN_XMLNODE *n;
318 
319  assert(pd);
320  assert(pd->xmlNode);
321 
322  n=GWEN_XMLNode_FindFirstTag(pd->xmlNode, "descr", 0, 0);
323  if (n) {
324  n=GWEN_XMLNode_FindFirstTag(n, "text", "lang", lang);
325  while (n) {
326  const char *fmt;
327 
328  fmt=GWEN_XMLNode_GetProperty(n, "format", 0);
329  if (fmt && strcasecmp(fmt, s)==0) {
330  int rv;
331 
333  if (rv) {
334  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
335  return rv;
336  }
337  return 0;
338  }
339  n=GWEN_XMLNode_FindNextTag(n, "text", "lang", lang);
340  } /* while */
341  }
342 
343  return -1;
344 }
345 
346 
347 
348 #ifndef NO_DEPRECATED_SYMBOLS
350  const char *s,
351  GWEN_BUFFER *buf)
352 {
353  GWEN_STRINGLIST *langl;
354  int rv;
355 
357  if (langl) {
359 
360  se=GWEN_StringList_FirstEntry(langl);
361  while (se) {
362  const char *l;
363 
365  DBG_NOTICE(GWEN_LOGDOMAIN, "Trying locale \"%s\"", l);
366  assert(l);
367 
369  s,
370  l,
371  buf);
372  if (rv==0)
373  return rv;
374 
376  } /* while */
377  } /* if language list available */
378 
379  /* no localized version found, return text for default language */
381  if (rv) {
382  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
383  return rv;
384  }
385 
386  return 0;
387 }
388 #endif // ifndef NO_DEPRECATED_SYMBOLS
389 
390 
392 {
393  assert(pd);
394  return pd->fileName;
395 }
396 
397 
398 
400  const char *s)
401 {
402  assert(pd);
403  free(pd->fileName);
404  if (s)
405  pd->fileName=strdup(s);
406  else
407  pd->fileName=0;
408 }
409 
410 
411 
413 {
414  assert(pd);
415  return pd->xmlNode;
416 }
417 
418 
419 
421 {
423 
425 
426  GWEN_LoadPluginDescrsByType(path, 0, pl);
429  return 0;
430  }
431  return pl;
432 }
433 
434 
435 
437 {
438  assert(pd);
439  return pd->isActive;
440 }
441 
442 
443 
445 {
446  assert(pd);
447  pd->isActive=i;
448 }
449 
450 
451 
452 int GWEN_LoadPluginDescrsByType(const char *path,
453  const char *type,
455 {
456  GWEN_DIRECTORY *d;
457  GWEN_BUFFER *nbuf;
458  char nbuffer[64];
459  unsigned int pathLen;
460 
461  if (!path)
462  path="";
463 
464  /* create path */
465  nbuf=GWEN_Buffer_new(0, 256, 0, 1);
466  GWEN_Buffer_AppendString(nbuf, path);
467  pathLen=GWEN_Buffer_GetUsedBytes(nbuf);
468 
469  d=GWEN_Directory_new();
472  "Path \"%s\" is not available",
473  GWEN_Buffer_GetStart(nbuf));
474  GWEN_Buffer_free(nbuf);
476  return -1;
477  }
478 
479  while (!GWEN_Directory_Read(d,
480  nbuffer,
481  sizeof(nbuffer))) {
482  if (strcmp(nbuffer, ".") &&
483  strcmp(nbuffer, "..")) {
484  int nlen;
485 
486  nlen=strlen(nbuffer);
487  if (nlen>3) {
488  if (strcasecmp(nbuffer+nlen-4, ".xml")==0) {
489  struct stat st;
490 
491  GWEN_Buffer_Crop(nbuf, 0, pathLen);
492  GWEN_Buffer_SetPos(nbuf, pathLen);
494  GWEN_Buffer_AppendString(nbuf, nbuffer);
495 
496  if (stat(GWEN_Buffer_GetStart(nbuf), &st)) {
497  DBG_ERROR(GWEN_LOGDOMAIN, "stat(%s): %s",
498  GWEN_Buffer_GetStart(nbuf),
499  strerror(errno));
500  }
501  else {
502  if (!S_ISDIR(st.st_mode)) {
503  GWEN_XMLNODE *fileNode;
504 
505  fileNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "root");
506  if (GWEN_XML_ReadFile(fileNode,
507  GWEN_Buffer_GetStart(nbuf),
512  "Bad file \"%s\"", GWEN_Buffer_GetStart(nbuf));
513  }
514  else {
515  GWEN_XMLNODE *node;
516  GWEN_XMLNODE *n;
517  GWEN_STRINGLIST *langl;
518 
519  n=0;
520  node=GWEN_XMLNode_FindFirstTag(fileNode, "PluginDescr", 0, 0);
521  if (!node)
522  node=fileNode;
524  if (langl) {
526 
527  se=GWEN_StringList_FirstEntry(langl);
528  while (se) {
529  const char *l;
530 
532  DBG_DEBUG(GWEN_LOGDOMAIN, "Trying locale \"%s\"", l);
533  assert(l);
534  n=GWEN_XMLNode_FindFirstTag(node, "plugin", "lang", l);
535  if (n)
536  break;
538  } /* while */
539  } /* if language list available */
540 
541  if (!n)
542  n=GWEN_XMLNode_FindFirstTag(node, "plugin", 0, 0);
543  if (n) {
545  int loadIt;
546 
547  loadIt=1;
548  if (type) {
549  const char *ft;
550 
551  ft=GWEN_XMLNode_GetProperty(n, "type", 0);
552  if (!ft)
553  loadIt=0;
554  else if (strcasecmp(ft, type)!=0) {
555  loadIt=0;
556  }
557  } /* if type specified */
558  if (loadIt) {
560  if (!pd) {
561  DBG_WARN(GWEN_LOGDOMAIN, "Bad plugin description");
562  }
563  else {
565  (pd, GWEN_Buffer_GetStart(nbuf));
566  GWEN_Buffer_Crop(nbuf, 0, pathLen);
567  GWEN_Buffer_SetPos(nbuf, pathLen);
569  (pd, GWEN_Buffer_GetStart(nbuf));
571  }
572  } /* if loadIt */
573  else {
575  "Ignoring file \"%s\" (bad/missing type)",
576  GWEN_Buffer_GetStart(nbuf));
577  }
578  }
579  else {
581  "File \"%s\" does not contain a plugin "
582  "description",
583  GWEN_Buffer_GetStart(nbuf));
584  }
585  }
586  GWEN_XMLNode_free(fileNode);
587  } /* if !dir */
588  } /* if stat was ok */
589  } /* if XML */
590  } /* if name has more than 3 chars */
591  } /* if not "." and not ".." */
592  } /* while */
595  GWEN_Buffer_free(nbuf);
596 
597  return 0;
598 }
599 
600 
601 
602 
603 
604 
605 
606 
607 
608 
609 
610 
GWENHYWFAR_API const char * fmt
Definition: buffer.h:283
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
GWENHYWFAR_API void GWEN_Directory_free(GWEN_DIRECTORY *d)
struct GWEN_STRINGLISTENTRYSTRUCT GWEN_STRINGLISTENTRY
Definition: stringlist.h:53
#define GWEN_LIST2_FUNCTIONS(t, pr)
Definition: list2.h:99
GWENHYWFAR_API int GWEN_XMLNode_toBuffer(const GWEN_XMLNODE *n, GWEN_BUFFER *buf, uint32_t flags)
Definition: xmlrw.c:626
#define GWEN_XML_FLAGS_DEFAULT
Definition: xml.h:117
int GWEN_PluginDescription__GetLongDescrByFormat(const GWEN_PLUGIN_DESCRIPTION *pd, const char *s, GWEN_BUFFER *buf)
Definition: plugindescr.c:280
#define DBG_MEM_INC(o, attach)
Definition: debug.h:87
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:277
const char * GWEN_XMLNode_GetProperty(const GWEN_XMLNODE *n, const char *name, const char *defaultValue)
Definition: xml.c:239
const char * GWEN_PluginDescription_GetPath(const GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:211
struct GWEN_PLUGIN_DESCRIPTION GWEN_PLUGIN_DESCRIPTION
Definition: plugindescr.h:41
const char * GWEN_PluginDescription_GetType(const GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:240
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_PluginDescription_GetLongDescr(const GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:272
#define DBG_NOTICE(dbg_logger, format, args...)
Definition: debug.h:152
const char * GWEN_PluginDescription_GetFileName(const GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:391
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define NULL
Definition: binreloc.c:300
GWENHYWFAR_API int GWEN_Directory_Close(GWEN_DIRECTORY *d)
GWENHYWFAR_API int GWEN_XML_ReadFile(GWEN_XMLNODE *n, const char *filepath, uint32_t flags)
Definition: xmlrw.c:1297
void GWEN_PluginDescription_Attach(GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:134
#define DBG_WARN(dbg_logger, format, args...)
Definition: debug.h:125
int GWEN_PluginDescription_GetLongDescrByFormat(const GWEN_PLUGIN_DESCRIPTION *pd, const char *s, GWEN_BUFFER *buf)
Definition: plugindescr.c:349
#define GWEN_LOGDOMAIN
Definition: logger.h:35
void GWEN_PluginDescription_List2_freeAll(GWEN_PLUGIN_DESCRIPTION_LIST2 *pdl)
Definition: plugindescr.c:200
GWEN_XMLNODE * GWEN_XMLNode_new(GWEN_XMLNODE_TYPE t, const char *data)
Definition: xml.c:144
GWENHYWFAR_API GWEN_DIRECTORY * GWEN_Directory_new(void)
GWEN_PLUGIN_DESCRIPTION_LIST2 * GWEN_LoadPluginDescrs(const char *path)
Definition: plugindescr.c:420
void GWEN_PluginDescription_SetPath(GWEN_PLUGIN_DESCRIPTION *pd, const char *s)
Definition: plugindescr.c:219
GWEN_PLUGIN_DESCRIPTION * GWEN_PluginDescription_List2_ForEach(GWEN_PLUGIN_DESCRIPTION_LIST2 *list, GWEN_PLUGIN_DESCRIPTION_LIST2_FOREACH func, void *user_data)
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
GWEN_STRINGLISTENTRY * GWEN_StringList_FirstEntry(const GWEN_STRINGLIST *sl)
Definition: stringlist.c:390
const char * GWEN_StringListEntry_Data(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:406
struct GWEN_DIRECTORY GWEN_DIRECTORY
Definition: directory.h:41
const char * GWEN_PluginDescription_GetVersion(const GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:264
GWEN_XMLNODE * GWEN_XMLNode_FindFirstTag(const GWEN_XMLNODE *n, const char *tname, const char *pname, const char *pvalue)
Definition: xml.c:776
GWEN_PLUGIN_DESCRIPTION_LIST2 * GWEN_PluginDescription_List2_new()
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
void GWEN_PluginDescription_List2_PushBack(GWEN_PLUGIN_DESCRIPTION_LIST2 *l, GWEN_PLUGIN_DESCRIPTION *p)
void GWEN_PluginDescription_SetFileName(GWEN_PLUGIN_DESCRIPTION *pd, const char *s)
Definition: plugindescr.c:399
const char * GWEN_XMLNode_GetCharValue(const GWEN_XMLNODE *n, const char *name, const char *defValue)
Definition: xml.c:812
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:214
unsigned int GWEN_PluginDescription_List2_GetSize(GWEN_PLUGIN_DESCRIPTION_LIST2 *l)
GWEN_PLUGIN_DESCRIPTION * GWEN_PluginDescription_dup(const GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:143
int GWEN_LoadPluginDescrsByType(const char *path, const char *type, GWEN_PLUGIN_DESCRIPTION_LIST2 *pdl)
Definition: plugindescr.c:452
GWEN_PLUGIN_DESCRIPTION * GWEN_PluginDescription_List2_freeAll_cb(GWEN_PLUGIN_DESCRIPTION *pd, __attribute__((unused)) void *user_data)
Definition: plugindescr.c:191
void GWEN_PluginDescription_List2_free(GWEN_PLUGIN_DESCRIPTION_LIST2 *l)
void GWEN_PluginDescription_free(GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:107
#define GWEN_XML_FLAGS_TOLERANT_ENDTAGS
Definition: xml.h:103
const char * GWEN_PluginDescription_GetShortDescr(const GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:248
GWEN_PLUGIN_DESCRIPTION * GWEN_PluginDescription_new(GWEN_XMLNODE *node)
Definition: plugindescr.c:57
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition: stringlist.h:56
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition: buffer.c:394
const char * GWEN_PluginDescription_GetAuthor(const GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:256
struct GWEN_PLUGIN_DESCRIPTION_LIST2 GWEN_PLUGIN_DESCRIPTION_LIST2
Definition: listdoc.h:6388
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
void GWEN_XMLNode_free(GWEN_XMLNODE *n)
Definition: xml.c:160
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
void GWEN_PluginDescription_SetIsActive(GWEN_PLUGIN_DESCRIPTION *pd, int i)
Definition: plugindescr.c:444
int GWEN_Buffer_Crop(GWEN_BUFFER *bf, uint32_t pos, uint32_t l)
Definition: buffer.c:947
GWEN_XMLNODE * GWEN_PluginDescription_GetXmlNode(const GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:412
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
#define GWEN_XML_FLAGS_HANDLE_OPEN_HTMLTAGS
Definition: xml.h:73
int GWEN_Buffer_SetPos(GWEN_BUFFER *bf, uint32_t i)
Definition: buffer.c:261
int GWEN_PluginDescription_IsActive(const GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:436
#define GWEN_DIR_SEPARATOR
GWEN_STRINGLISTENTRY * GWEN_StringListEntry_Next(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:398
const char * GWEN_PluginDescription_GetName(const GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:232
const char * GWEN_I18N_Translate(const char *txtdom, const char *text)
Definition: i18n.c:255
GWEN_XMLNODE * GWEN_XMLNode_dup(const GWEN_XMLNODE *n)
Definition: xml.c:187
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:181
int GWEN_PluginDescription__GetLocalizedLongDescrByFormat(const GWEN_PLUGIN_DESCRIPTION *pd, const char *s, const char *lang, GWEN_BUFFER *buf)
Definition: plugindescr.c:312
#define GWEN_LIST_INIT(t, element)
Definition: list1.h:465
#define GWEN_XML_FLAGS_HANDLE_HEADERS
Definition: xml.h:94
#define GWEN_LIST_FUNCTIONS(t, pr)
Definition: list1.h:366
GWENHYWFAR_API int GWEN_Directory_Read(GWEN_DIRECTORY *d, char *buffer, unsigned int len)
GWEN_STRINGLIST * GWEN_I18N_GetCurrentLocaleList(void)
Definition: i18n.c:241
#define DBG_MEM_DEC(o)
Definition: debug.h:88
#define GWEN_LIST_FINI(t, element)
Definition: list1.h:474
struct GWEN__XMLNODE GWEN_XMLNODE
Definition: xml.h:156
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:989
GWENHYWFAR_API int GWEN_Directory_Open(GWEN_DIRECTORY *d, const char *n)