gwenhywfar  4.99.8beta
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 
57 GWEN_PLUGIN_DESCRIPTION *GWEN_PluginDescription_new(GWEN_XMLNODE *node) {
58  GWEN_PLUGIN_DESCRIPTION *pd;
59  const char *p;
60 
61  GWEN_NEW_OBJECT(GWEN_PLUGIN_DESCRIPTION, pd);
62  pd->refCount=1;
63  DBG_MEM_INC("GWEN_PLUGIN_DESCRIPTION", 0);
64  GWEN_LIST_INIT(GWEN_PLUGIN_DESCRIPTION, pd);
65  p=GWEN_XMLNode_GetProperty(node, "name", 0);
66  if (!p) {
67  DBG_ERROR(GWEN_LOGDOMAIN, "Unnamed plugin");
69  return 0;
70  }
71  pd->name=strdup(p);
72  pd->xmlNode=GWEN_XMLNode_dup(node);
73 
74  p=GWEN_XMLNode_GetProperty(node, "i18n", NULL);
75  if (!p) {
76  DBG_NOTICE(GWEN_LOGDOMAIN, "Plugin has no I18N domain, using GWEN");
77  p="gwenhywfar";
78  }
79  pd->langDomain=strdup(p);
80 
81  p=GWEN_XMLNode_GetProperty(node, "type", 0);
82  if (!p) {
83  DBG_ERROR(GWEN_LOGDOMAIN, "Plugin has no type");
85  return 0;
86  }
87  pd->type=strdup(p);
88 
89  p=GWEN_XMLNode_GetCharValue(node, "version", 0);
90  if (p)
91  pd->version=strdup(p);
92  p=GWEN_XMLNode_GetCharValue(node, "author", 0);
93  if (p)
94  pd->author=strdup(p);
95  p=GWEN_XMLNode_GetCharValue(node, "short", 0);
96  if (p)
97  pd->shortDescr=strdup(p);
98  p=GWEN_XMLNode_GetCharValue(node, "descr", 0);
99  if (p)
100  pd->longDescr=strdup(p);
101  return pd;
102 }
103 
104 
105 
107  if (pd) {
108  assert(pd->refCount);
109  if (pd->refCount==1) {
110  DBG_MEM_DEC("GWEN_PLUGIN_DESCRIPTION");
112  free(pd->path);
113  GWEN_XMLNode_free(pd->xmlNode);
114  free(pd->fileName);
115  free(pd->longDescr);
116  free(pd->shortDescr);
117  free(pd->author);
118  free(pd->version);
119  free(pd->langDomain);
120  free(pd->type);
121  free(pd->name);
122  pd->refCount=0;
123  GWEN_FREE_OBJECT(pd);
124  }
125  else
126  pd->refCount--;
127  }
128 }
129 
130 
131 
133  assert(pd);
134  assert(pd->refCount);
135  pd->refCount++;
136 }
137 
138 
139 
143  const char *s;
144 
145  assert(pd);
147  np->refCount=1;
148  DBG_MEM_INC("GWEN_PLUGIN_DESCRIPTION", 0);
150 
151  s=pd->fileName;
152  if (s) np->fileName=strdup(s);
153 
154  s=pd->path;
155  if (s) np->path=strdup(s);
156  s=pd->name;
157  if (s) np->name=strdup(s);
158  s=pd->type;
159  if (s) np->type=strdup(s);
160  s=pd->langDomain;
161  if (s) np->langDomain=strdup(s);
162  s=pd->shortDescr;
163  if (s) np->shortDescr=strdup(s);
164  s=pd->author;
165  if (s) np->author=strdup(s);
166  s=pd->version;
167  if (s) np->version=strdup(s);
168  s=pd->longDescr;
169  if (s) np->longDescr=strdup(s);
170  np->isActive=pd->isActive;
171  if (pd->xmlNode)
172  np->xmlNode=GWEN_XMLNode_dup(pd->xmlNode);
173 
174  return np;
175 }
176 
177 
178 
181  __attribute__((unused)) void *user_data) {
183  return 0;
184 }
185 
186 
187 
190  (pdl,
192  0);
194 }
195 
196 
197 
199  assert(pd);
200  return pd->path;
201 }
202 
203 
204 
206  const char *s) {
207  assert(pd);
208  free(pd->path);
209  if (s) pd->path=strdup(s);
210  else pd->path=0;
211 }
212 
213 
214 
216  assert(pd);
217  return pd->name;
218 }
219 
220 
221 
223  assert(pd);
224  return pd->type;
225 }
226 
227 
228 
229 const char*
231  assert(pd);
232  return GWEN_I18N_Translate(pd->langDomain, pd->shortDescr);
233 }
234 
235 
236 
237 const char*
239  assert(pd);
240  return pd->author;
241 }
242 
243 
244 
245 const char*
247  assert(pd);
248  return pd->version;
249 }
250 
251 
252 
253 const char*
255  assert(pd);
256  return GWEN_I18N_Translate(pd->langDomain, pd->longDescr);
257 }
258 
259 
260 
261 int
263  const char *s,
264  GWEN_BUFFER *buf) {
265  GWEN_XMLNODE *n;
266 
267  assert(pd);
268  assert(pd->xmlNode);
269 
270  n=GWEN_XMLNode_FindFirstTag(pd->xmlNode, "descr", 0, 0);
271  if (n) {
272  n=GWEN_XMLNode_FindFirstTag(n, "text", "format", s);
273  while (n) {
274  if (0==GWEN_XMLNode_GetProperty(n, "lang", 0)) {
275  int rv;
276 
278  if (rv) {
279  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
280  return rv;
281  }
282  return 0;
283  }
284  n=GWEN_XMLNode_FindNextTag(n, "text", "format", s);
285  } /* while */
286  }
287 
288  return -1;
289 }
290 
291 
292 
293 int
295  const char *s,
296  const char *lang,
297  GWEN_BUFFER *buf) {
298  GWEN_XMLNODE *n;
299 
300  assert(pd);
301  assert(pd->xmlNode);
302 
303  n=GWEN_XMLNode_FindFirstTag(pd->xmlNode, "descr", 0, 0);
304  if (n) {
305  n=GWEN_XMLNode_FindFirstTag(n, "text", "lang", lang);
306  while (n) {
307  const char *fmt;
308 
309  fmt=GWEN_XMLNode_GetProperty(n, "format", 0);
310  if (fmt && strcasecmp(fmt, s)==0) {
311  int rv;
312 
314  if (rv) {
315  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
316  return rv;
317  }
318  return 0;
319  }
320  n=GWEN_XMLNode_FindNextTag(n, "text", "lang", lang);
321  } /* while */
322  }
323 
324  return -1;
325 }
326 
327 
328 
329 #ifndef NO_DEPRECATED_SYMBOLS
330 int
332  const char *s,
333  GWEN_BUFFER *buf) {
334  GWEN_STRINGLIST *langl;
335  int rv;
336 
338  if (langl) {
340 
341  se=GWEN_StringList_FirstEntry(langl);
342  while(se) {
343  const char *l;
344 
346  DBG_NOTICE(GWEN_LOGDOMAIN, "Trying locale \"%s\"", l);
347  assert(l);
348 
350  s,
351  l,
352  buf);
353  if (rv==0)
354  return rv;
355 
357  } /* while */
358  } /* if language list available */
359 
360  /* no localized version found, return text for default language */
362  if (rv) {
363  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
364  return rv;
365  }
366 
367  return 0;
368 }
369 #endif // ifndef NO_DEPRECATED_SYMBOLS
370 
371 
372 const char*
374  assert(pd);
375  return pd->fileName;
376 }
377 
378 
379 
381  const char *s) {
382  assert(pd);
383  free(pd->fileName);
384  if (s) pd->fileName=strdup(s);
385  else pd->fileName=0;
386 }
387 
388 
389 
392  assert(pd);
393  return pd->xmlNode;
394 }
395 
396 
397 
400 
402 
403  GWEN_LoadPluginDescrsByType(path, 0, pl);
406  return 0;
407  }
408  return pl;
409 }
410 
411 
412 
414  assert(pd);
415  return pd->isActive;
416 }
417 
418 
419 
421  assert(pd);
422  pd->isActive=i;
423 }
424 
425 
426 
427 int GWEN_LoadPluginDescrsByType(const char *path,
428  const char *type,
430  GWEN_DIRECTORY *d;
431  GWEN_BUFFER *nbuf;
432  char nbuffer[64];
433  unsigned int pathLen;
434 
435  if (!path)
436  path="";
437 
438  /* create path */
439  nbuf=GWEN_Buffer_new(0, 256, 0, 1);
440  GWEN_Buffer_AppendString(nbuf, path);
441  pathLen=GWEN_Buffer_GetUsedBytes(nbuf);
442 
443  d=GWEN_Directory_new();
446  "Path \"%s\" is not available",
447  GWEN_Buffer_GetStart(nbuf));
448  GWEN_Buffer_free(nbuf);
450  return -1;
451  }
452 
453  while(!GWEN_Directory_Read(d,
454  nbuffer,
455  sizeof(nbuffer))) {
456  if (strcmp(nbuffer, ".") &&
457  strcmp(nbuffer, "..")) {
458  int nlen;
459 
460  nlen=strlen(nbuffer);
461  if (nlen>3) {
462  if (strcasecmp(nbuffer+nlen-4, ".xml")==0) {
463  struct stat st;
464 
465  GWEN_Buffer_Crop(nbuf, 0, pathLen);
466  GWEN_Buffer_SetPos(nbuf, pathLen);
468  GWEN_Buffer_AppendString(nbuf, nbuffer);
469 
470  if (stat(GWEN_Buffer_GetStart(nbuf), &st)) {
471  DBG_ERROR(GWEN_LOGDOMAIN, "stat(%s): %s",
472  GWEN_Buffer_GetStart(nbuf),
473  strerror(errno));
474  }
475  else {
476  if (!S_ISDIR(st.st_mode)) {
477  GWEN_XMLNODE *fileNode;
478 
479  fileNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "root");
480  if (GWEN_XML_ReadFile(fileNode,
481  GWEN_Buffer_GetStart(nbuf),
486  "Bad file \"%s\"", GWEN_Buffer_GetStart(nbuf));
487  }
488  else {
489  GWEN_XMLNODE *node;
490  GWEN_XMLNODE *n;
491  GWEN_STRINGLIST *langl;
492 
493  n=0;
494  node=GWEN_XMLNode_FindFirstTag(fileNode, "PluginDescr", 0, 0);
495  if (!node)
496  node=fileNode;
498  if (langl) {
500 
501  se=GWEN_StringList_FirstEntry(langl);
502  while(se) {
503  const char *l;
504 
506  DBG_DEBUG(GWEN_LOGDOMAIN, "Trying locale \"%s\"", l);
507  assert(l);
508  n=GWEN_XMLNode_FindFirstTag(node, "plugin", "lang", l);
509  if (n)
510  break;
512  } /* while */
513  } /* if language list available */
514 
515  if (!n)
516  n=GWEN_XMLNode_FindFirstTag(node, "plugin", 0, 0);
517  if (n) {
519  int loadIt;
520 
521  loadIt=1;
522  if (type) {
523  const char *ft;
524 
525  ft=GWEN_XMLNode_GetProperty(n, "type", 0);
526  if (!ft)
527  loadIt=0;
528  else if (strcasecmp(ft, type)!=0) {
529  loadIt=0;
530  }
531  } /* if type specified */
532  if (loadIt) {
534  if (!pd) {
535  DBG_WARN(GWEN_LOGDOMAIN, "Bad plugin description");
536  }
537  else {
539  (pd, GWEN_Buffer_GetStart(nbuf));
540  GWEN_Buffer_Crop(nbuf, 0, pathLen);
541  GWEN_Buffer_SetPos(nbuf, pathLen);
543  (pd, GWEN_Buffer_GetStart(nbuf));
545  }
546  } /* if loadIt */
547  else {
549  "Ignoring file \"%s\" (bad/missing type)",
550  GWEN_Buffer_GetStart(nbuf));
551  }
552  }
553  else {
555  "File \"%s\" does not contain a plugin "
556  "description",
557  GWEN_Buffer_GetStart(nbuf));
558  }
559  }
560  GWEN_XMLNode_free(fileNode);
561  } /* if !dir */
562  } /* if stat was ok */
563  } /* if XML */
564  } /* if name has more than 3 chars */
565  } /* if not "." and not ".." */
566  } /* while */
569  GWEN_Buffer_free(nbuf);
570 
571  return 0;
572 }
573 
574 
575 
576 
577 
578 
579 
580 
581 
582 
583 
584 
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:223
GWENHYWFAR_API void GWEN_Directory_free(GWEN_DIRECTORY *d)
struct GWEN_STRINGLISTENTRYSTRUCT GWEN_STRINGLISTENTRY
Definition: stringlist.h:51
GWENHYWFAR_API int GWEN_XMLNode_toBuffer(const GWEN_XMLNODE *n, GWEN_BUFFER *buf, uint32_t flags)
Definition: xmlrw.c:351
#define GWEN_XML_FLAGS_DEFAULT
Definition: xml.h:110
int GWEN_PluginDescription__GetLongDescrByFormat(const GWEN_PLUGIN_DESCRIPTION *pd, const char *s, GWEN_BUFFER *buf)
Definition: plugindescr.c:262
#define DBG_MEM_INC(o, attach)
Definition: debug.h:87
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:266
const char * GWEN_XMLNode_GetProperty(const GWEN_XMLNODE *n, const char *name, const char *defaultValue)
Definition: xml.c:228
const char * GWEN_PluginDescription_GetPath(const GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:198
struct GWEN_PLUGIN_DESCRIPTION GWEN_PLUGIN_DESCRIPTION
Definition: plugindescr.h:41
const char * GWEN_PluginDescription_GetType(const GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:222
GWEN_XMLNODE * GWEN_XMLNode_FindNextTag(const GWEN_XMLNODE *n, const char *tname, const char *pname, const char *pvalue)
Definition: xml.c:712
const char * GWEN_PluginDescription_GetLongDescr(const GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:254
#define DBG_NOTICE(dbg_logger, format, args...)
Definition: debug.h:140
const char * GWEN_PluginDescription_GetFileName(const GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:373
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:92
#define NULL
Definition: binreloc.c:290
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:973
void GWEN_PluginDescription_Attach(GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:132
#define DBG_WARN(dbg_logger, format, args...)
Definition: debug.h:118
int GWEN_PluginDescription_GetLongDescrByFormat(const GWEN_PLUGIN_DESCRIPTION *pd, const char *s, GWEN_BUFFER *buf)
Definition: plugindescr.c:331
#define GWEN_LOGDOMAIN
Definition: logger.h:35
void GWEN_PluginDescription_List2_freeAll(GWEN_PLUGIN_DESCRIPTION_LIST2 *pdl)
Definition: plugindescr.c:188
GWEN_XMLNODE * GWEN_XMLNode_new(GWEN_XMLNODE_TYPE t, const char *data)
Definition: xml.c:137
GWENHYWFAR_API GWEN_DIRECTORY * GWEN_Directory_new(void)
GWEN_PLUGIN_DESCRIPTION_LIST2 * GWEN_LoadPluginDescrs(const char *path)
Definition: plugindescr.c:398
void GWEN_PluginDescription_SetPath(GWEN_PLUGIN_DESCRIPTION *pd, const char *s)
Definition: plugindescr.c:205
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:38
GWEN_STRINGLISTENTRY * GWEN_StringList_FirstEntry(const GWEN_STRINGLIST *sl)
Definition: stringlist.c:352
const char * GWEN_StringListEntry_Data(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:366
struct GWEN_DIRECTORY GWEN_DIRECTORY
Definition: directory.h:41
const char * GWEN_PluginDescription_GetVersion(const GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:246
GWEN_XMLNODE * GWEN_XMLNode_FindFirstTag(const GWEN_XMLNODE *n, const char *tname, const char *pname, const char *pvalue)
Definition: xml.c:695
GWEN_PLUGIN_DESCRIPTION_LIST2 * GWEN_PluginDescription_List2_new()
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:86
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:380
const char * GWEN_XMLNode_GetCharValue(const GWEN_XMLNODE *n, const char *name, const char *defValue)
Definition: xml.c:729
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:192
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:141
int GWEN_LoadPluginDescrsByType(const char *path, const char *type, GWEN_PLUGIN_DESCRIPTION_LIST2 *pdl)
Definition: plugindescr.c:427
GWEN_PLUGIN_DESCRIPTION * GWEN_PluginDescription_List2_freeAll_cb(GWEN_PLUGIN_DESCRIPTION *pd, __attribute__((unused)) void *user_data)
Definition: plugindescr.c:180
void GWEN_PluginDescription_List2_free(GWEN_PLUGIN_DESCRIPTION_LIST2 *l)
void GWEN_PluginDescription_free(GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:106
#define GWEN_XML_FLAGS_TOLERANT_ENDTAGS
Definition: xml.h:103
const char * GWEN_PluginDescription_GetShortDescr(const GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:230
GWEN_PLUGIN_DESCRIPTION * GWEN_PluginDescription_new(GWEN_XMLNODE *node)
Definition: plugindescr.c:57
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition: stringlist.h:54
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition: buffer.c:380
const char * GWEN_PluginDescription_GetAuthor(const GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:238
struct GWEN_PLUGIN_DESCRIPTION_LIST2 GWEN_PLUGIN_DESCRIPTION_LIST2
Definition: listdoc.h:6238
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:83
void GWEN_XMLNode_free(GWEN_XMLNODE *n)
Definition: xml.c:152
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:41
GWEN_LIST2_FUNCTIONS(TYPEMAKER2_TYPE, Typemaker2_Type)
void GWEN_PluginDescription_SetIsActive(GWEN_PLUGIN_DESCRIPTION *pd, int i)
Definition: plugindescr.c:420
int GWEN_Buffer_Crop(GWEN_BUFFER *bf, uint32_t pos, uint32_t l)
Definition: buffer.c:973
GWEN_XMLNODE * GWEN_PluginDescription_GetXmlNode(const GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:391
#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:246
int GWEN_PluginDescription_IsActive(const GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:413
#define GWEN_DIR_SEPARATOR
GWEN_STRINGLISTENTRY * GWEN_StringListEntry_Next(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:359
const char * GWEN_PluginDescription_GetName(const GWEN_PLUGIN_DESCRIPTION *pd)
Definition: plugindescr.c:215
const char * GWEN_I18N_Translate(const char *txtdom, const char *text)
Definition: i18n.c:247
GWEN_XMLNODE * GWEN_XMLNode_dup(const GWEN_XMLNODE *n)
Definition: xml.c:177
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:164
int GWEN_PluginDescription__GetLocalizedLongDescrByFormat(const GWEN_PLUGIN_DESCRIPTION *pd, const char *s, const char *lang, GWEN_BUFFER *buf)
Definition: plugindescr.c:294
#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:235
#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:148
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:1014
GWENHYWFAR_API int GWEN_Directory_Open(GWEN_DIRECTORY *d, const char *n)