gwenhywfar  5.10.1
xmlctx.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Sat Jun 28 2003
3  copyright : (C) 2021 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 
30 #include "xmlctx_p.h"
31 #include "gwenhywfar/debug.h"
32 #include "gwenhywfar/misc.h"
33 #include "gwenhywfar/text.h"
34 #include "gwenhywfar/path.h"
35 #include "i18n_l.h"
36 
37 #include <stdlib.h>
38 #include <assert.h>
39 #include <string.h>
40 #include <ctype.h>
41 
42 
43 
45 
46 
47 
48 /* ------------------------------------------------------------------------------------------------
49  * forward declarations
50  * ------------------------------------------------------------------------------------------------
51  */
52 
53 
55 static void _moveSubTagsUpOneLevel(GWEN_XMLNODE *currNode);
56 
57 
58 
59 /* ------------------------------------------------------------------------------------------------
60  * implementations
61  * ------------------------------------------------------------------------------------------------
62  */
63 
64 
65 
67 {
68  GWEN_XML_CONTEXT *ctx;
69 
71  ctx->_refCount=1;
73 
74  ctx->flags=flags;
75 
76  return ctx;
77 }
78 
79 
80 
82 {
83  if (ctx) {
84  assert(ctx->_refCount);
85  if (ctx->_refCount==1) {
87  if (ctx->encoding)
88  free(ctx->encoding);
89  ctx->_refCount=0;
90  GWEN_FREE_OBJECT(ctx);
91  }
92  else
93  ctx->_refCount--;
94  }
95 }
96 
97 
98 
100 {
101  assert(ctx);
102  assert(ctx->_refCount);
103  ctx->_refCount++;
104 }
105 
106 
107 
109 {
110  assert(ctx);
111  return ctx->flags;
112 }
113 
114 
115 
117 {
118  assert(ctx);
119  ctx->flags=f;
120 }
121 
122 
123 
125 {
126  assert(ctx);
127  return ctx->encoding;
128 }
129 
130 
131 
132 void GWEN_XmlCtx_SetEncoding(GWEN_XML_CONTEXT *ctx, const char *encoding)
133 {
134  char *s;
135 
136  assert(ctx);
137  if (encoding) {
138  s=strdup(encoding);
139  assert(s);
140  }
141  else
142  s=NULL;
143  if (ctx->encoding)
144  free(ctx->encoding);
145  ctx->encoding=s;
146 }
147 
148 
149 
151 {
152  assert(ctx);
153  return ctx->depth;
154 }
155 
156 
157 
159 {
160  assert(ctx);
161  ctx->depth=i;
162 }
163 
164 
165 
167 {
168  assert(ctx);
169  ctx->depth++;
170 }
171 
172 
173 
175 {
176  assert(ctx);
177  if (ctx->depth<1)
178  return -1;
179  ctx->depth--;
180  return 0;
181 }
182 
183 
184 
186 {
187  assert(ctx);
188  return ctx->finishedElements;
189 }
190 
191 
192 
194 {
195  assert(ctx);
196  ctx->finishedElements++;
197 }
198 
199 
200 
202 {
203  assert(ctx);
204  ctx->finishedElements=0;
205 }
206 
207 
208 
210 {
211  assert(ctx);
212  ctx->currentNode=n;
213 }
214 
215 
216 
218 {
219  assert(ctx);
220  return ctx->currentNode;
221 }
222 
223 
224 
226 {
227  assert(ctx);
228  ctx->currentHeader=n;
229 }
230 
231 
232 
234 {
235  assert(ctx);
236  return ctx->currentHeader;
237 }
238 
239 
240 
243 {
245 
246  assert(ctx);
247  of=ctx->startTagFn;
248  ctx->startTagFn=f;
249  return of;
250 }
251 
252 
253 
256 {
258 
259  assert(ctx);
260  of=ctx->endTagFn;
261  ctx->endTagFn=f;
262  return of;
263 }
264 
265 
266 
269 {
271 
272  assert(ctx);
273  of=ctx->addDataFn;
274  ctx->addDataFn=f;
275  return of;
276 }
277 
278 
279 
282 {
284 
285  assert(ctx);
286  of=ctx->addAttrFn;
287  ctx->addAttrFn=f;
288  return of;
289 }
290 
291 
292 
295 {
297 
298  assert(ctx);
299  of=ctx->addCommentFn;
300  ctx->addCommentFn=f;
301  return of;
302 }
303 
304 
305 
306 
307 int GWEN_XmlCtx_StartTag(GWEN_XML_CONTEXT *ctx, const char *tagName)
308 {
309  assert(ctx);
310 
311  if (ctx->startTagFn)
312  return ctx->startTagFn(ctx, tagName);
313  else {
314  DBG_INFO(GWEN_LOGDOMAIN, "Starting tag: [%s]", tagName);
315  return 0;
316  }
317 }
318 
319 
320 
321 int GWEN_XmlCtx_EndTag(GWEN_XML_CONTEXT *ctx, int closing)
322 {
323  assert(ctx);
324 
325  if (ctx->endTagFn)
326  return ctx->endTagFn(ctx, closing);
327  else {
328  DBG_INFO(GWEN_LOGDOMAIN, "Ending tag (%s)", closing?"closing":"not closing");
329  return 0;
330  }
331 }
332 
333 
334 
335 int GWEN_XmlCtx_AddData(GWEN_XML_CONTEXT *ctx, const char *data)
336 {
337  assert(ctx);
338 
339  if (ctx->addDataFn)
340  return ctx->addDataFn(ctx, data);
341  else {
342  DBG_INFO(GWEN_LOGDOMAIN, "Adding data: [%s]", data);
343  return 0;
344  }
345 }
346 
347 
348 
349 int GWEN_XmlCtx_AddComment(GWEN_XML_CONTEXT *ctx, const char *data)
350 {
351  assert(ctx);
352 
353  if (ctx->addCommentFn)
354  return ctx->addCommentFn(ctx, data);
355  else {
356  DBG_INFO(GWEN_LOGDOMAIN, "Adding comment: [%s]", data);
357  return 0;
358  }
359 }
360 
361 
362 
364  const char *attrName,
365  const char *attrData)
366 {
367  assert(ctx);
368 
369  if (ctx->addAttrFn)
370  return ctx->addAttrFn(ctx, attrName, attrData);
371  else {
372  DBG_INFO(GWEN_LOGDOMAIN, "Adding attribute: [%s]=[%s]",
373  attrName, attrData);
374  return 0;
375  }
376 }
377 
378 
379 
380 
381 
382 
383 
384 
386 {
387  GWEN_XML_CONTEXT *ctx;
388 
389  ctx=GWEN_XmlCtx_new(flags);
390  assert(ctx);
391 
393 
399 
400  return ctx;
401 }
402 
403 
404 
405 int GWEN_XmlCtxStore_StartTag(GWEN_XML_CONTEXT *ctx, const char *tagName)
406 {
407  GWEN_XMLNODE *currNode;
408  GWEN_XMLNODE *newNode;
409 
410  currNode=GWEN_XmlCtx_GetCurrentNode(ctx);
411  if (currNode==NULL)
412  return GWEN_ERROR_INVALID;
413 
414  if (*tagName=='?' && (GWEN_XmlCtx_GetFlags(ctx) & GWEN_XML_FLAGS_HANDLE_HEADERS)) {
415  newNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, tagName);
416  assert(newNode);
417  DBG_VERBOUS(GWEN_LOGDOMAIN, "Adding header [%s] to [%s]",
418  GWEN_XMLNode_GetData(newNode),
419  GWEN_XMLNode_GetData(currNode));
420  GWEN_XMLNode_AddHeader(currNode, newNode);
421  GWEN_XmlCtx_SetCurrentHeader(ctx, newNode);
422  }
423  else if (strcasecmp(tagName, "!DOCTYPE")==0) {
424  newNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, tagName);
425  assert(newNode);
426  DBG_VERBOUS(GWEN_LOGDOMAIN, "Adding header [%s] to [%s]",
427  GWEN_XMLNode_GetData(newNode),
428  GWEN_XMLNode_GetData(currNode));
429  GWEN_XMLNode_AddHeader(currNode, newNode);
430  GWEN_XmlCtx_SetCurrentHeader(ctx, newNode);
431  }
432  else if (*tagName=='/') {
433  const char *s;
434 
435  tagName++;
436  DBG_VERBOUS(GWEN_LOGDOMAIN, "Finishing tag [%s]", tagName);
437  s=GWEN_XMLNode_GetData(currNode);
438  if (s==NULL) {
439  DBG_INFO(GWEN_LOGDOMAIN, "Current node tag has no name");
440  return GWEN_ERROR_BAD_DATA;
441  }
442 
443  if (strcasecmp(s, tagName)!=0) {
444  /* current closing tag doesn't match currently open tag, check further */
446  DBG_INFO(GWEN_LOGDOMAIN, "Endtag does not match curent tag (%s != %s)", s, tagName);
447  return GWEN_ERROR_BAD_DATA;
448  }
449  else {
450  newNode=_findTagForClosingTagAndcloseAndMoveSubTags(ctx, currNode, tagName);
451  if (newNode==NULL) {
452  DBG_INFO(GWEN_LOGDOMAIN, "here");
453  return GWEN_ERROR_BAD_DATA;
454  }
455  }
456  }
457  else {
458  newNode=GWEN_XMLNode_GetParent(currNode);
459  if (newNode==NULL) {
460  DBG_INFO(GWEN_LOGDOMAIN, "No parent node at [%s]", tagName);
461  return GWEN_ERROR_BAD_DATA;
462  }
463  GWEN_XmlCtx_SetCurrentNode(ctx, newNode);
465  }
466  /* one more element finished */
468  }
469  else {
470  newNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, tagName);
471  assert(newNode);
472  GWEN_XMLNode_AddChild(currNode, newNode);
473  GWEN_XmlCtx_SetCurrentNode(ctx, newNode);
475  DBG_VERBOUS(GWEN_LOGDOMAIN, "Starting tag [%s]", tagName);
476  }
477 
478  return 0;
479 }
480 
481 
482 
484 {
485  GWEN_XMLNODE *newNode;
486 
487  newNode=currNode;
488 
490  _moveSubTagsUpOneLevel(currNode);
491 
492  while ((newNode=GWEN_XMLNode_GetParent(newNode))) {
493  const char *s;
494 
496  s=GWEN_XMLNode_GetData(newNode);
497  if (strcasecmp(s, tagName)==0)
498  break;
500  _moveSubTagsUpOneLevel(newNode);
501  }
502  if (newNode)
503  newNode=GWEN_XMLNode_GetParent(newNode);
504  if (newNode) {
505  GWEN_XmlCtx_SetCurrentNode(ctx, newNode);
507  return newNode;
508  }
509  else {
510  DBG_INFO(GWEN_LOGDOMAIN, "No matching parent node for [%s]", tagName);
511  return NULL;
512  }
513 }
514 
515 
516 
518 {
519  GWEN_XMLNODE *childNode;
520  GWEN_XMLNODE *parentNode;
521 
522  parentNode=GWEN_XMLNode_GetParent(currNode);
523  if (parentNode) {
524  while( (childNode=GWEN_XMLNode_GetFirstTag(currNode)) ) {
525  GWEN_XMLNode_UnlinkChild(currNode, childNode);
526  GWEN_XMLNode_AddChild(parentNode, childNode);
527  }
528  }
529 }
530 
531 
532 
534 {
535  GWEN_XMLNODE *currNode;
536 
537  currNode=GWEN_XmlCtx_GetCurrentHeader(ctx);
538  if (currNode) {
539  DBG_VERBOUS(GWEN_LOGDOMAIN, "Ending header [%s]", GWEN_XMLNode_GetData(currNode));
541  }
542  else {
543  currNode=GWEN_XmlCtx_GetCurrentNode(ctx);
544  if (currNode==NULL)
545  return GWEN_ERROR_INVALID;
546  DBG_VERBOUS(GWEN_LOGDOMAIN, "Ending tag [%s] (%s)",
547  GWEN_XMLNode_GetData(currNode),
548  closing?"closing":"not closing");
549 
550  if (closing) {
551  GWEN_XMLNODE *newNode;
552 
553  newNode=GWEN_XMLNode_GetParent(currNode);
554  if (newNode==NULL) {
555  DBG_INFO(GWEN_LOGDOMAIN, "No parent node at [%s]", GWEN_XMLNode_GetData(currNode));
556  return GWEN_ERROR_BAD_DATA;
557  }
558  GWEN_XmlCtx_SetCurrentNode(ctx, newNode);
559  /* one more element finished */
562  }
563  }
564 
565  return 0;
566 }
567 
568 
569 
570 int GWEN_XmlCtxStore_AddData(GWEN_XML_CONTEXT *ctx, const char *data)
571 {
572  GWEN_XMLNODE *currNode;
573  GWEN_BUFFER *buf;
574  uint32_t flags;
575 
576  flags=GWEN_XmlCtx_GetFlags(ctx);
577  currNode=GWEN_XmlCtx_GetCurrentNode(ctx);
578  if (currNode==NULL)
579  return GWEN_ERROR_INVALID;
580 
581  buf=GWEN_Buffer_new(0, 64, 0, 1);
582  if (GWEN_Text_UnescapeXmlToBuffer(data, buf)) {
583  GWEN_Buffer_free(buf);
584  DBG_INFO(GWEN_LOGDOMAIN, "here");
585  return GWEN_ERROR_BAD_DATA;
586  }
587 
588  if (!(flags & GWEN_XML_FLAGS_NO_CONDENSE) ||
589  (flags & GWEN_XML_FLAGS_KEEP_CNTRL) ||
590  (flags & GWEN_XML_FLAGS_KEEP_BLANKS)) {
591  const uint8_t *p;
592  uint8_t *dst;
593  uint8_t *src;
594  unsigned int size;
595  unsigned int i;
596  int lastWasBlank;
597  uint8_t *lastBlankPos;
598  uint32_t bStart=0;
599 
600  dst=(uint8_t *)GWEN_Buffer_GetStart(buf);
601  src=dst;
602  if (!(flags & GWEN_XML_FLAGS_KEEP_BLANKS)) {
603  if (flags & GWEN_XML_FLAGS_KEEP_CNTRL) {
604  while (*src && (*src==32 || *src==9))
605  src++;
606  }
607  else {
608  while (*src && *src<33)
609  src++;
610  }
611  }
612 
613  p=src;
614  bStart=src-((uint8_t *)GWEN_Buffer_GetStart(buf));
615  size=GWEN_Buffer_GetUsedBytes(buf)-bStart;
616  lastWasBlank=0;
617  lastBlankPos=0;
618 
619  for (i=0; i<size; i++) {
620  uint8_t c;
621 
622  c=*p;
623  if (!(flags & GWEN_XML_FLAGS_KEEP_CNTRL) && c<32)
624  c=32;
625 
626  /* remember next loop whether this char was a blank */
627  if (!(flags & GWEN_XML_FLAGS_NO_CONDENSE) && c==32) {
628  if (!lastWasBlank) {
629  /* store only one blank */
630  lastWasBlank=1;
631  lastBlankPos=dst;
632  *(dst++)=c;
633  }
634  }
635  else {
636  lastWasBlank=0;
637  lastBlankPos=0;
638  *(dst++)=c;
639  }
640  p++;
641  }
642 
643  /* remove trailing blanks */
644  if (lastBlankPos!=0)
645  dst=lastBlankPos;
646 
647  size=dst-(uint8_t *)GWEN_Buffer_GetStart(buf);
648  GWEN_Buffer_Crop(buf, 0, size);
649  }
650 
651  if (GWEN_Buffer_GetUsedBytes(buf)) {
652  GWEN_XMLNODE *newNode;
653 
655  assert(newNode);
656  GWEN_XMLNode_AddChild(currNode, newNode);
657  DBG_VERBOUS(GWEN_LOGDOMAIN, "Setting this data: [%s]", GWEN_Buffer_GetStart(buf));
658  }
659  GWEN_Buffer_free(buf);
660 
661  return 0;
662 }
663 
664 
665 
667 {
668  return 0;
669 }
670 
671 
672 
674  const char *attrName,
675  const char *attrData)
676 {
677  GWEN_XMLNODE *currNode;
678 
679  currNode=GWEN_XmlCtx_GetCurrentHeader(ctx);
680  if (currNode) {
681  if ((strcmp(GWEN_XMLNode_GetData(currNode), "?xml")==0)
682  && (strcmp(attrName, "encoding")==0)) {
683  if (strcasecmp(attrData, "UTF-8")==0)
685  else
686  GWEN_XmlCtx_SetEncoding(ctx, attrData);
687  }
688  DBG_VERBOUS(GWEN_LOGDOMAIN, "Setting attribute of header [%s]: [%s]=[%s]",
689  GWEN_XMLNode_GetData(currNode), attrName, attrData);
690  GWEN_XMLNode_SetProperty(currNode, attrName, attrData);
691  }
692  else {
693  int isNormalProperty=1;
694 
695  currNode=GWEN_XmlCtx_GetCurrentNode(ctx);
696  if (currNode==NULL)
697  return GWEN_ERROR_INVALID;
698  if (attrData==NULL)
699  attrData="";
700 
701  if (ctx->flags & GWEN_XML_FLAGS_HANDLE_NAMESPACES) {
702  if (strcasecmp(attrName, "xmlns")==0) {
704 
705  DBG_VERBOUS(GWEN_LOGDOMAIN, "Adding namespace [%s] to node [%s]",
706  attrData, GWEN_XMLNode_GetData(currNode));
707  ns=GWEN_XMLNode_NameSpace_new("", attrData);
708  GWEN_XMLNode_AddNameSpace(currNode, ns);
710  isNormalProperty=0;
711  }
712  else if (strncasecmp(attrName, "xmlns:", 6)==0) {
713  const char *name;
714 
715  name=strchr(attrName, ':');
716  if (name) {
717  name++;
718  if (*name) {
720 
721  DBG_VERBOUS(GWEN_LOGDOMAIN, "Adding namespace [%s]=[%s]",
722  name, attrData);
723  ns=GWEN_XMLNode_NameSpace_new(name, attrData);
724  GWEN_XMLNode_AddNameSpace(currNode, ns);
726  isNormalProperty=0;
727  }
728  }
729  }
730  }
731 
732  if (isNormalProperty) {
733  GWEN_BUFFER *buf;
734 
735  DBG_VERBOUS(GWEN_LOGDOMAIN, "Setting attribute of tag [%s]: [%s]=[%s]",
736  GWEN_XMLNode_GetData(currNode), attrName, attrData);
737  buf=GWEN_Buffer_new(0, 64, 0, 1);
738  if (GWEN_Text_UnescapeXmlToBuffer(attrData, buf)) {
739  GWEN_Buffer_free(buf);
740  DBG_INFO(GWEN_LOGDOMAIN, "here");
741  return GWEN_ERROR_BAD_DATA;
742  }
743  GWEN_XMLNode_SetProperty(currNode, attrName, GWEN_Buffer_GetStart(buf));
744  GWEN_Buffer_free(buf);
745  }
746  }
747 
748  return 0;
749 }
750 
751 
752 
753 
754 
755 
int(* GWEN_XMLCTX_ADDATTR_FN)(GWEN_XML_CONTEXT *ctx, const char *attrName, const char *attrData)
Definition: xmlctx.h:54
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
struct GWEN_XMLNODE_NAMESPACE GWEN_XMLNODE_NAMESPACE
Definition: xml.h:157
void GWEN_XMLNode_AddHeader(GWEN_XMLNODE *n, GWEN_XMLNODE *nh)
Definition: xml.c:1331
#define GWEN_INHERIT_FINI(t, element)
Definition: inherit.h:238
#define GWEN_ERROR_INVALID
Definition: error.h:67
GWEN_XMLCTX_ADDATTR_FN GWEN_XmlCtx_SetAddAttrFn(GWEN_XML_CONTEXT *ctx, GWEN_XMLCTX_ADDATTR_FN f)
Definition: xmlctx.c:280
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:277
GWEN_XMLCTX_STARTTAG_FN GWEN_XmlCtx_SetStartTagFn(GWEN_XML_CONTEXT *ctx, GWEN_XMLCTX_STARTTAG_FN f)
Definition: xmlctx.c:241
#define GWEN_XML_FLAGS_KEEP_BLANKS
Definition: xml.h:87
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define NULL
Definition: binreloc.c:300
void GWEN_XmlCtx_ResetFinishedElement(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:201
#define DBG_VERBOUS(dbg_logger, format, args...)
Definition: debug.h:224
int GWEN_XmlCtx_AddAttr(GWEN_XML_CONTEXT *ctx, const char *attrName, const char *attrData)
Definition: xmlctx.c:363
void GWEN_XMLNode_SetProperty(GWEN_XMLNODE *n, const char *name, const char *value)
Definition: xml.c:322
int GWEN_XmlCtx_StartTag(GWEN_XML_CONTEXT *ctx, const char *tagName)
Definition: xmlctx.c:307
GWEN_XML_CONTEXT * GWEN_XmlCtx_new(uint32_t flags)
Definition: xmlctx.c:66
static void _moveSubTagsUpOneLevel(GWEN_XMLNODE *currNode)
Definition: xmlctx.c:517
int(* GWEN_XMLCTX_ADDCOMMENT_FN)(GWEN_XML_CONTEXT *ctx, const char *data)
Definition: xmlctx.h:52
#define GWEN_LOGDOMAIN
Definition: logger.h:35
GWEN_XMLCTX_ENDTAG_FN GWEN_XmlCtx_SetEndTagFn(GWEN_XML_CONTEXT *ctx, GWEN_XMLCTX_ENDTAG_FN f)
Definition: xmlctx.c:254
void GWEN_XMLNode_AddNameSpace(GWEN_XMLNODE *n, const GWEN_XMLNODE_NAMESPACE *ns)
Definition: xml.c:1407
int GWEN_XmlCtx_GetDepth(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:150
void GWEN_XmlCtx_Attach(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:99
GWEN_XMLNODE * GWEN_XMLNode_new(GWEN_XMLNODE_TYPE t, const char *data)
Definition: xml.c:144
void GWEN_XMLNode_NameSpace_free(GWEN_XMLNODE_NAMESPACE *ns)
Definition: xml.c:2009
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
int(* GWEN_XMLCTX_ENDTAG_FN)(GWEN_XML_CONTEXT *ctx, int closing)
Definition: xmlctx.h:49
uint32_t GWEN_XmlCtx_GetFinishedElement(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:185
GWEN_XMLNODE_NAMESPACE * GWEN_XMLNode_NameSpace_new(const char *name, const char *url)
Definition: xml.c:1991
void GWEN_XmlCtx_free(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:81
#define GWEN_ERROR_BAD_DATA
Definition: error.h:121
static GWEN_XMLNODE * _findTagForClosingTagAndcloseAndMoveSubTags(GWEN_XML_CONTEXT *ctx, GWEN_XMLNODE *currNode, const char *tagName)
Definition: xmlctx.c:483
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
void GWEN_XmlCtx_SetCurrentHeader(GWEN_XML_CONTEXT *ctx, GWEN_XMLNODE *n)
Definition: xmlctx.c:225
int GWEN_XmlCtx_EndTag(GWEN_XML_CONTEXT *ctx, int closing)
Definition: xmlctx.c:321
int GWEN_XmlCtxStore_StartTag(GWEN_XML_CONTEXT *ctx, const char *tagName)
Definition: xmlctx.c:405
#define GWEN_XML_FLAGS_NO_CONDENSE
Definition: xml.h:79
void GWEN_XmlCtx_SetDepth(GWEN_XML_CONTEXT *ctx, int i)
Definition: xmlctx.c:158
int GWEN_XmlCtx_AddData(GWEN_XML_CONTEXT *ctx, const char *data)
Definition: xmlctx.c:335
void GWEN_XmlCtx_SetEncoding(GWEN_XML_CONTEXT *ctx, const char *encoding)
Definition: xmlctx.c:132
GWEN_XMLCTX_ADDCOMMENT_FN GWEN_XmlCtx_SetAddCommentFn(GWEN_XML_CONTEXT *ctx, GWEN_XMLCTX_ADDCOMMENT_FN f)
Definition: xmlctx.c:293
void GWEN_XmlCtx_IncDepth(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:166
#define GWEN_XML_FLAGS_TOLERANT_ENDTAGS
Definition: xml.h:103
void GWEN_XmlCtx_IncFinishedElement(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:193
GWEN_XMLNODE * GWEN_XmlCtx_GetCurrentHeader(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:233
GWEN_XML_CONTEXT * GWEN_XmlCtxStore_new(GWEN_XMLNODE *n, uint32_t flags)
Definition: xmlctx.c:385
#define GWEN_INHERIT_INIT(t, element)
Definition: inherit.h:223
int GWEN_Text_UnescapeXmlToBuffer(const char *src, GWEN_BUFFER *buf)
Definition: text.c:1856
int GWEN_XmlCtxStore_AddComment(GWEN_UNUSED GWEN_XML_CONTEXT *ctx, GWEN_UNUSED const char *data)
Definition: xmlctx.c:666
void GWEN_XmlCtx_SetFlags(GWEN_XML_CONTEXT *ctx, uint32_t f)
Definition: xmlctx.c:116
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
void GWEN_XMLNode_UnlinkChild(GWEN_XMLNODE *n, GWEN_XMLNODE *child)
Definition: xml.c:570
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
int(* GWEN_XMLCTX_STARTTAG_FN)(GWEN_XML_CONTEXT *ctx, const char *tagName)
Definition: xmlctx.h:47
#define GWEN_XML_FLAGS_KEEP_CNTRL
Definition: xml.h:85
GWEN_XMLNODE * GWEN_XMLNode_GetParent(const GWEN_XMLNODE *n)
Definition: xml.c:416
int GWEN_XmlCtxStore_AddAttr(GWEN_XML_CONTEXT *ctx, const char *attrName, const char *attrData)
Definition: xmlctx.c:673
int GWEN_Buffer_Crop(GWEN_BUFFER *bf, uint32_t pos, uint32_t l)
Definition: buffer.c:947
int(* GWEN_XMLCTX_ADDDATA_FN)(GWEN_XML_CONTEXT *ctx, const char *data)
Definition: xmlctx.h:50
int GWEN_XmlCtx_DecDepth(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:174
GWEN_XMLNODE * GWEN_XMLNode_GetFirstTag(const GWEN_XMLNODE *n)
Definition: xml.c:705
uint32_t GWEN_XmlCtx_GetFlags(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:108
void GWEN_XmlCtx_SetCurrentNode(GWEN_XML_CONTEXT *ctx, GWEN_XMLNODE *n)
Definition: xmlctx.c:209
const char * GWEN_XMLNode_GetData(const GWEN_XMLNODE *n)
Definition: xml.c:370
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:181
int GWEN_XmlCtx_AddComment(GWEN_XML_CONTEXT *ctx, const char *data)
Definition: xmlctx.c:349
GWEN_XMLCTX_ADDDATA_FN GWEN_XmlCtx_SetAddDataFn(GWEN_XML_CONTEXT *ctx, GWEN_XMLCTX_ADDDATA_FN f)
Definition: xmlctx.c:267
#define GWEN_XML_FLAGS_SGML
Definition: xml.h:112
const char * GWEN_XmlCtx_GetEncoding(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:124
int GWEN_XmlCtxStore_EndTag(GWEN_XML_CONTEXT *ctx, int closing)
Definition: xmlctx.c:533
#define GWEN_XML_FLAGS_HANDLE_HEADERS
Definition: xml.h:94
#define GWEN_XML_FLAGS_HANDLE_NAMESPACES
Definition: xml.h:105
GWEN_XMLNODE * GWEN_XmlCtx_GetCurrentNode(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:217
#define GWEN_INHERIT_FUNCTIONS(t)
Definition: inherit.h:163
struct GWEN__XMLNODE GWEN_XMLNODE
Definition: xml.h:156
struct GWEN_XML_CONTEXT GWEN_XML_CONTEXT
Definition: xmlctx.h:39
#define GWEN_UNUSED
void GWEN_XMLNode_AddChild(GWEN_XMLNODE *n, GWEN_XMLNODE *child)
Definition: xml.c:423
int GWEN_XmlCtxStore_AddData(GWEN_XML_CONTEXT *ctx, const char *data)
Definition: xmlctx.c:570