gwenhywfar  5.4.1
xml.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Sat Jun 28 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 #include "xml_p.h"
32 #include "xmlctx_l.h"
33 #include "i18n_l.h"
34 
35 #include <gwenhywfar/debug.h>
36 #include <gwenhywfar/misc.h>
37 #include <gwenhywfar/text.h>
38 #include <gwenhywfar/path.h>
39 #include <gwenhywfar/fastbuffer.h>
40 #include <gwenhywfar/syncio_file.h>
41 #include <gwenhywfar/syncio_memory.h>
42 
43 #include <stdlib.h>
44 #include <assert.h>
45 #include <string.h>
46 #include <ctype.h>
47 #include <sys/types.h>
48 #ifdef HAVE_SYS_STAT_H
49 # include <sys/stat.h>
50 #endif
51 #ifdef HAVE_FCNTL_H
52 # include <fcntl.h>
53 #endif
54 #include <errno.h>
55 #ifdef HAVE_UNISTD_H
56 # include <unistd.h>
57 #endif
58 
59 
60 #define GWEN_XML_BUFFERSIZE 512
61 
62 
63 
64 GWEN_LIST_FUNCTIONS(GWEN_XMLNODE, GWEN_XMLNode)
66 
67 GWEN_LIST_FUNCTIONS(GWEN_XMLNODE_NAMESPACE, GWEN_XMLNode_NameSpace)
68 
69 
70 
71 
72 GWEN_XMLPROPERTY *GWEN_XMLProperty_new(const char *name, const char *value)
73 {
75 
77  if (name)
78  p->name=GWEN_Memory_strdup(name);
79  if (value)
80  p->value=GWEN_Memory_strdup(value);
81  return p;
82 }
83 
84 
85 
87 {
88  if (p) {
89  GWEN_Memory_dealloc(p->name);
90  GWEN_Memory_dealloc(p->value);
91  GWEN_Memory_dealloc(p->nameSpace);
93  }
94 }
95 
96 
97 
99 {
100  GWEN_XMLPROPERTY *pp;
101 
102  pp=GWEN_XMLProperty_new(p->name, p->value);
103  if (p->nameSpace)
104  pp->nameSpace=strdup(p->nameSpace);
105 
106  return pp;
107 }
108 
109 
110 
112 {
114 }
115 
116 
117 
119 {
121 }
122 
123 
125 {
127 }
128 
129 
131 {
132  while (p) {
133  GWEN_XMLPROPERTY *next;
134 
135  next=p->next;
137  p=next;
138  } /* while */
139 }
140 
141 
142 
143 
145 {
146  GWEN_XMLNODE *n;
147 
150  n->type=t;
151  n->children=GWEN_XMLNode_List_new();
152  n->headers=GWEN_XMLNode_List_new();
153  if (data)
154  n->data=GWEN_Memory_strdup(data);
155  n->nameSpaces=GWEN_XMLNode_NameSpace_List_new();
156  return n;
157 }
158 
159 
161 {
162  if (n) {
164  GWEN_XMLProperty_freeAll(n->properties);
165  GWEN_Memory_dealloc(n->nameSpace);
166  GWEN_Memory_dealloc(n->data);
167  GWEN_XMLNode_List_free(n->headers);
168  GWEN_XMLNode_List_free(n->children);
169  GWEN_XMLNode_NameSpace_List_free(n->nameSpaces);
170  GWEN_FREE_OBJECT(n);
171  }
172 }
173 
174 
176 {
177  while (n) {
178  GWEN_XMLNODE *next;
179 
180  next=GWEN_XMLNode_List_Next(n);
182  n=next;
183  } /* while */
184 }
185 
186 
188 {
189  GWEN_XMLNODE *nn, *cn, *ncn;
190  const GWEN_XMLPROPERTY *p;
191  const GWEN_XMLNODE_NAMESPACE *nns;
192 
193  /* duplicate node itself */
194  nn=GWEN_XMLNode_new(n->type, n->data);
195  if (n->nameSpace)
196  nn->nameSpace=strdup(n->nameSpace);
197 
198  /* duplicate properties */
199  p=n->properties;
200  while (p) {
201  GWEN_XMLPROPERTY *np;
202 
203  np=GWEN_XMLProperty_dup(p);
204  GWEN_XMLProperty_add(np, &(nn->properties));
205  p=p->next;
206  } /* while */
207 
208  /* duplicate children */
209  cn=GWEN_XMLNode_List_First(n->children);
210  while (cn) {
211  ncn=GWEN_XMLNode_dup(cn);
212  GWEN_XMLNode_AddChild(nn, ncn);
213  cn=GWEN_XMLNode_Next(cn);
214  } /* while */
215 
216  /* duplicate headers */
217  cn=GWEN_XMLNode_List_First(n->headers);
218  while (cn) {
219  ncn=GWEN_XMLNode_dup(cn);
220  GWEN_XMLNode_AddHeader(nn, ncn);
221  cn=GWEN_XMLNode_Next(cn);
222  } /* while */
223 
224  /* duplicate namespaces */
225  nns=GWEN_XMLNode_NameSpace_List_First(n->nameSpaces);
226  while (nns) {
228 
229  nnns=GWEN_XMLNode_NameSpace_dup(nns);
230  GWEN_XMLNode_NameSpace_List_Add(nnns, nn->nameSpaces);
232  }
233 
234  return nn;
235 }
236 
237 
238 
239 const char *GWEN_XMLNode_GetProperty(const GWEN_XMLNODE *n, const char *name,
240  const char *defaultValue)
241 {
242  GWEN_XMLPROPERTY *p;
243 
244  assert(n);
245  assert(name);
246  p=n->properties;
247  while (p) {
248  assert(p->name);
249  if (strcasecmp(p->name, name)==0)
250  break;
251  p=p->next;
252  } /* while */
253 
254  if (p) {
255  if (p->value)
256  return p->value;
257  }
258  return defaultValue;
259 }
260 
261 
262 
263 int GWEN_XMLNode_GetIntProperty(const GWEN_XMLNODE *n, const char *name,
264  int defaultValue)
265 {
266  GWEN_XMLPROPERTY *p;
267 
268  assert(n);
269  assert(name);
270  p=n->properties;
271  while (p) {
272  assert(p->name);
273  if (strcasecmp(p->name, name)==0)
274  break;
275  p=p->next;
276  } /* while */
277 
278  if (p) {
279  if (p->value) {
280  int i;
281 
282  if (1==sscanf(p->value, "%i", &i))
283  return i;
284  }
285  }
286  return defaultValue;
287 }
288 
289 
291  const char *name, const char *value,
292  int doInsert)
293 {
294  GWEN_XMLPROPERTY *p;
295 
296  p=n->properties;
297  while (p) {
298  assert(p->name);
299  if (strcasecmp(p->name, name)==0)
300  break;
301  p=p->next;
302  } /* while */
303 
304  if (p) {
305  GWEN_Memory_dealloc(p->value);
306  if (value)
307  p->value=GWEN_Memory_strdup(value);
308  else
309  p->value=0;
310  }
311  else {
312  p=GWEN_XMLProperty_new(name, value);
313  if (doInsert)
314  GWEN_XMLProperty_insert(p, &(n->properties));
315  else
316  GWEN_XMLProperty_add(p, &(n->properties));
317  }
318 }
319 
320 
321 
323  const char *name, const char *value)
324 {
325  GWEN_XMLNode__SetProperty(n, name, value, 0);
326 }
327 
328 
329 
331  const char *name, int value)
332 {
333  char numbuf[256];
334 
335  snprintf(numbuf, sizeof(numbuf)-1, "%i", value);
336  numbuf[sizeof(numbuf)-1]=0;
337  GWEN_XMLNode__SetProperty(n, name, numbuf, 0);
338 }
339 
340 
341 
343 {
344  assert(n);
345  n->usage++;
346 }
347 
348 
349 
351 {
352  assert(n);
353  if (n->usage==0) {
354  DBG_WARN(GWEN_LOGDOMAIN, "Node usage already is zero");
355  }
356  else
357  n->usage--;
358 }
359 
360 
361 
363 {
364  assert(n);
365  return n->usage;
366 }
367 
368 
369 
370 const char *GWEN_XMLNode_GetData(const GWEN_XMLNODE *n)
371 {
372  assert(n);
373  return n->data;
374 }
375 
376 
377 void GWEN_XMLNode_SetData(GWEN_XMLNODE *n, const char *data)
378 {
379  assert(n);
380  GWEN_Memory_dealloc(n->data);
381  if (data)
382  n->data=GWEN_Memory_strdup(data);
383  else
384  n->data=0;
385 }
386 
387 
388 
390 {
391  assert(n);
392  return n->nameSpace;
393 }
394 
395 
396 
398 {
399  assert(n);
400  GWEN_Memory_dealloc(n->nameSpace);
401  if (s)
402  n->nameSpace=GWEN_Memory_strdup(s);
403  else
404  n->nameSpace=NULL;
405 }
406 
407 
408 
410 {
411  assert(n);
412  return GWEN_XMLNode_List_First(n->children);
413 }
414 
415 
417 {
418  assert(n);
419  return n->parent;
420 }
421 
422 
424 {
425  assert(n);
426  GWEN_XMLNode_List_Add(child, n->children);
427  child->parent=n;
428 }
429 
430 
431 
433  int copythem)
434 {
435  GWEN_XMLNODE *ch;
436 
437  assert(n);
438  assert(nn);
439 
440  ch=GWEN_XMLNode_GetChild(nn);
441  while (ch) {
442  GWEN_XMLNODE *nc;
443 
444  nc=GWEN_XMLNode_Next(ch);
445  if (!copythem) {
446  GWEN_XMLNode_UnlinkChild(nn, ch);
447  GWEN_XMLNode_AddChild(n, ch);
448  }
449  else {
451  }
452  ch=nc;
453  } /* while */
454 }
455 
456 
457 
459 {
460  assert(n);
461  return n->type;
462 }
463 
464 
466 {
467  assert(n);
468  return GWEN_XMLNode_List_Next(n);
469 }
470 
471 
472 void GWEN_XMLNode_Dump(const GWEN_XMLNODE *n, int ind)
473 {
474  GWEN_XMLPROPERTY *p;
475  GWEN_XMLNODE *c;
476  int i;
477  int simpleTag;
478 
479  assert(n);
480 
481  for (i=0; i<ind; i++)
482  fprintf(stderr, " ");
483 
484  simpleTag=0;
485  if (n->type==GWEN_XMLNodeTypeTag) {
486  if (n->data)
487  fprintf(stderr, "<%s", n->data);
488  else
489  fprintf(stderr, "<UNKNOWN");
490  p=n->properties;
491  while (p) {
492  if (p->value)
493  fprintf(stderr, " %s=\"%s\"", p->name, p->value);
494  else
495  fprintf(stderr, " %s", p->name);
496  p=p->next;
497  }
498 
499  if (n->data) {
500  if (n->data[0]=='?') {
501  simpleTag=1;
502  fprintf(stderr, "?");
503  }
504  else if (n->data[0]=='!') {
505  simpleTag=1;
506  }
507  }
508 
509  fprintf(stderr, ">\n");
510  if (!simpleTag) {
512  while (c) {
513  GWEN_XMLNode_Dump(c, ind+2);
514  c=GWEN_XMLNode_Next(c);
515  }
516  for (i=0; i<ind; i++)
517  fprintf(stderr, " ");
518  if (n->data)
519  fprintf(stderr, "</%s>\n", n->data);
520  else
521  fprintf(stderr, "</UNKNOWN>\n");
522  }
523  }
524  else if (n->type==GWEN_XMLNodeTypeData) {
525  if (n->data) {
526  fprintf(stderr, "%s\n", n->data);
527  }
528  }
529  else if (n->type==GWEN_XMLNodeTypeComment) {
530  fprintf(stderr, "<!--");
531  if (n->data) {
532  fprintf(stderr, "%s", n->data);
533  }
534  fprintf(stderr, "-->\n");
535  }
536  else {
537  DBG_ERROR(GWEN_LOGDOMAIN, "Unknown tag type (%d)", n->type);
538  }
539 }
540 
541 
542 
544  GWEN_XMLNODE_TYPE t, const char *data)
545 {
546  GWEN_XMLNODE *n;
547 
548  assert(node);
549  assert(data);
550 
551  n=GWEN_XMLNode_GetChild(node);
552  while (n) {
553  if (n->type==t)
554  if (n->data)
555  if (strcasecmp(n->data, data)==0)
556  break;
557  n=GWEN_XMLNode_Next(n);
558  } /* while */
559 
560  if (!n) {
561  DBG_DEBUG(GWEN_LOGDOMAIN, "Node %d:\"%s\" not found", t, data);
562  return 0;
563  }
564 
565  return n;
566 }
567 
568 
569 
571 {
572  assert(n);
573  assert(child);
574  GWEN_XMLNode_List_Del(child);
575  child->parent=0;
576 }
577 
578 
579 
581 {
582  assert(n);
583  GWEN_XMLNode_List_Clear(n->children);
584 }
585 
586 
587 
589  const GWEN_XMLNODE *sn,
590  int overwrite)
591 {
592  const GWEN_XMLPROPERTY *sp;
593  GWEN_XMLPROPERTY *tp;
594 
595  assert(tn);
596  assert(sn);
597 
598  sp=sn->properties;
599  while (sp) {
600  GWEN_XMLPROPERTY *np;
601 
602  assert(sp->name);
603  tp=tn->properties;
604  /* lookup property in target */
605  while (tp) {
606 
607  assert(tp->name);
608  if (strcasecmp(tp->name, sp->name)==0) {
609  /* property already exists */
610  if (overwrite) {
611  /* overwrite old property */
612  GWEN_Memory_dealloc(tp->value);
613  tp->value=0;
614  if (sp->value)
615  tp->value=GWEN_Memory_strdup(sp->value);
616  }
617  break;
618  }
619  tp=tp->next;
620  } /* while */
621 
622  if (!tp) {
623  /* property not found, simply copy and add it */
624  np=GWEN_XMLProperty_dup(sp);
625  GWEN_XMLProperty_add(np, &(tn->properties));
626  }
627 
628  sp=sp->next;
629  } /* while */
630 }
631 
632 
633 
636 {
637  GWEN_XMLNODE *nn;
638 
639  assert(n);
640  nn=GWEN_XMLNode_GetChild(n);
641  while (nn) {
642  if (nn->type==t)
643  return nn;
644  nn=GWEN_XMLNode_Next(nn);
645  } /* while */
646  return 0;
647 }
648 
649 
650 
653 {
654  assert(n);
655  while (n) {
656  if (n->type==t)
657  return (GWEN_XMLNODE *)n;
658  n=GWEN_XMLNode_Next(n);
659  } /* while */
660  return 0;
661 }
662 
663 
664 
666 {
668 }
669 
670 
671 
673 {
674  GWEN_XMLNODE *next;
675 
676  next=GWEN_XMLNode_Next(n);
677  if (!next)
678  return 0;
680 }
681 
682 
683 
685 {
687 }
688 
689 
690 
692 {
693  GWEN_XMLNODE *next;
694 
695  next=GWEN_XMLNode_Next(n);
696  if (!next)
697  return 0;
699 }
700 
701 
702 
704  const char *tname,
705  const char *pname,
706  const char *pvalue)
707 {
708  while (n) {
709  if (-1!=GWEN_Text_ComparePattern(n->data, tname, 0)) {
710  if (pname) {
711  const char *p;
712 
713  p=GWEN_XMLNode_GetProperty(n, pname, 0);
714  if (p) {
715  if (!pvalue)
716  return (GWEN_XMLNODE *)n;
717  if (-1!=GWEN_Text_ComparePattern(pvalue, p, 0))
718  return (GWEN_XMLNODE *)n;
719  }
720  else {
721  /* return this node if pvalue is 0 an the property does not exist */
722  if (!pvalue)
723  return (GWEN_XMLNODE *)n;
724  }
725  } /* if pname */
726  else
727  return (GWEN_XMLNODE *)n;
728  }
730  } /* while */
731  return 0;
732 }
733 
734 
735 
737  const char *tname,
738  const char *pname,
739  const char *pvalue)
740 {
741  GWEN_XMLNODE *nn;
742 
744  if (!nn)
745  return 0;
746  return GWEN_XMLNode_FindTag(nn,
747  tname,
748  pname,
749  pvalue);
750 }
751 
752 
753 
755  const char *tname,
756  const char *pname,
757  const char *pvalue)
758 {
759  GWEN_XMLNODE *nn;
760 
762  if (!nn)
763  return 0;
764  return GWEN_XMLNode_FindTag(nn,
765  tname,
766  pname,
767  pvalue);
768 }
769 
770 
771 
773  const char *name,
774  const char *defValue)
775 {
776  GWEN_XMLNODE *nn;
777 
778  if (name && *name) {
779  nn=GWEN_XMLNode_FindFirstTag(n, name, 0, 0);
780 
781  while (nn) {
782  GWEN_XMLNODE *dn;
783 
785  if (dn) {
786  if (dn->data)
787  return dn->data;
788  }
789  nn=GWEN_XMLNode_FindNextTag(nn, name, 0, 0);
790  }
791  }
792  else {
793  GWEN_XMLNODE *dn;
794 
796  if (dn) {
797  if (dn->data)
798  return dn->data;
799  }
800  }
801  return defValue;
802 }
803 
804 
805 
807  const char *name,
808  const char *defValue)
809 {
810  GWEN_XMLNODE *nn=0;
811  GWEN_STRINGLIST *langl;
812 
814  if (langl) {
816 
817  se=GWEN_StringList_FirstEntry(langl);
818  while (se) {
819  const char *l;
820 
822  DBG_DEBUG(GWEN_LOGDOMAIN, "Trying locale \"%s\"", l);
823  assert(l);
824  nn=GWEN_XMLNode_FindFirstTag(n, name, "lang", l);
825  while (nn) {
826  GWEN_XMLNODE *dn;
827 
829  if (dn) {
830  if (dn->data && *(dn->data))
831  return dn->data;
832  }
833  nn=GWEN_XMLNode_FindNextTag(nn, name, "lang", l);
834  } /* while nn */
836  } /* while */
837  } /* if language list available */
838 
839  /* otherwise try without locale */
840  nn=GWEN_XMLNode_FindFirstTag(n, name, 0, 0);
841  while (nn) {
842  GWEN_XMLNODE *dn;
843 
845  if (dn) {
846  if (dn->data)
847  return dn->data;
848  }
849  nn=GWEN_XMLNode_FindNextTag(nn, name, 0, 0);
850  }
851 
852  return defValue;
853 }
854 
855 
856 
858  const char *name,
859  const char *value)
860 {
861  if (name && *name) {
862  GWEN_XMLNODE *nn;
863 
865  if (value) {
866  GWEN_XMLNODE *nnn;
867 
869  GWEN_XMLNode_AddChild(nn, nnn);
870  }
871  GWEN_XMLNode_AddChild(n, nn);
872  }
873  else {
874  GWEN_XMLNODE *nn;
875 
877  GWEN_XMLNode_AddChild(n, nn);
878  }
879 }
880 
881 
882 
884  const char *name,
885  int defValue)
886 {
887  const char *p;
888  int res;
889 
890  p=GWEN_XMLNode_GetCharValue(n, name, 0);
891  if (!p)
892  return defValue;
893  if (1!=sscanf(p, "%i", &res))
894  return defValue;
895  return res;
896 }
897 
898 
899 
901  const char *name,
902  int value)
903 {
904  char numbuf[32];
905 
906  snprintf(numbuf, sizeof(numbuf)-1, "%d", value);
907  numbuf[sizeof(numbuf)-1]=0;
908  GWEN_XMLNode_SetCharValue(n, name, numbuf);
909 }
910 
911 
912 
914  const char *name,
915  const char *value)
916 {
917  GWEN_XMLNODE *nn;
918 
919  nn=GWEN_XMLNode_GetNodeByXPath(n, name, 0);
920  if (nn) {
921  GWEN_XMLNODE *nnn;
922 
923  /* clear current entries */
925  GWEN_XMLNode_List_Clear(nn->children);
926 
927  /* create value node */
929  GWEN_XMLNode_AddChild(nn, nnn);
930 
931  return 0;
932  }
933  else {
934  DBG_ERROR(GWEN_LOGDOMAIN, "Unable to create node [%s]", name);
935  return GWEN_ERROR_INVALID;
936  }
937 }
938 
939 
940 
942  const char *name,
943  const char *defValue)
944 {
945  GWEN_XMLNODE *nn;
946 
947  nn=GWEN_XMLNode_GetNodeByXPath(n, name, 0);
948  if (nn) {
949  GWEN_XMLNODE *dn;
950 
952  if (dn) {
953  if (dn->data)
954  return dn->data;
955  }
956  }
957 
958  return defValue;
959 }
960 
961 
962 
964  const char *name,
965  int value)
966 {
967  char numbuf[32];
968  int rv;
969 
970  /* create int value */
971  snprintf(numbuf, sizeof(numbuf)-1, "%d", value);
972  numbuf[sizeof(numbuf)-1]=0;
973 
974  rv=GWEN_XMLNode_SetCharValueByPath(n, flags, name, numbuf);
975  if (rv<0) {
976  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
977  return rv;
978  }
979 
980  return rv;
981 }
982 
983 
984 
986  const char *name,
987  int defValue)
988 {
989  const char *p;
990  int res;
991 
993  if (!p)
994  return defValue;
995  if (1!=sscanf(p, "%i", &res))
996  return defValue;
997  return res;
998 }
999 
1000 
1001 
1002 
1003 
1004 
1006 {
1007  assert(n);
1008  return n->properties;
1009 }
1010 
1011 
1012 
1014  const GWEN_XMLPROPERTY *pr)
1015 {
1016  assert(n);
1017  assert(pr);
1018  return pr->next;
1019 }
1020 
1021 
1022 
1024 {
1025  assert(pr);
1026  return pr->name;
1027 }
1028 
1029 
1030 
1032 {
1033  assert(pr);
1034  return pr->value;
1035 }
1036 
1037 
1038 
1040  const GWEN_XMLNODE *child)
1041 {
1042  GWEN_XMLNODE *n;
1043 
1044  if (!child || !parent || child==parent)
1045  return 0;
1046  n=child->parent;
1047  while (n) {
1048  if (n==parent)
1049  return 1;
1050  n=n->parent;
1051  }
1052  return 0;
1053 }
1054 
1055 
1056 
1058  const GWEN_XMLNODE *n2,
1059  GWEN_BUFFER *nbuf)
1060 {
1061  GWEN_BUFFER *lbuf;
1062  const GWEN_XMLNODE *ln1;
1063  const GWEN_XMLNODE *ln2;
1064 
1065  if (!n1 && !n2) {
1066  DBG_ERROR(GWEN_LOGDOMAIN, "Both nodes are NULL");
1067  return -1;
1068  }
1069 
1070  if (!n1) {
1071  n1=n2;
1072  while (n1->parent)
1073  n1=n1->parent;
1074  }
1075 
1076  if (!n2) {
1077  n2=n1;
1078  while (n2->parent)
1079  n2=n2->parent;
1080  }
1081 
1082  if (n2==n1) {
1083  GWEN_Buffer_AppendString(nbuf, "here()");
1084  return 0;
1085  }
1086 
1087  lbuf=GWEN_Buffer_new(0, 256, 0, 1);
1088  GWEN_Buffer_ReserveBytes(lbuf, 128);
1089 
1090  ln1=n1->parent;
1091  if (ln1) {
1092  GWEN_Buffer_AppendString(lbuf, "../");
1093  while (ln1) {
1094  if (ln1==n2) {
1095  /* found n2 */
1096  GWEN_Buffer_AppendBuffer(nbuf, lbuf);
1097  GWEN_Buffer_free(lbuf);
1098  return 0;
1099  }
1100  if (GWEN_XMLNode_IsChildOf(ln1, n2))
1101  break;
1102  ln1=ln1->parent;
1103  GWEN_Buffer_AppendString(lbuf, "../");
1104  }
1105 
1106  if (!ln1) {
1107  DBG_ERROR(GWEN_LOGDOMAIN, "Nodes do not share root node");
1108  GWEN_Buffer_free(lbuf);
1109  return -1;
1110  }
1111 
1112  /* append path to n1 */
1113  GWEN_Buffer_AppendBuffer(nbuf, lbuf);
1114  }
1115  DBG_DEBUG(GWEN_LOGDOMAIN, "Path so far: %s", GWEN_Buffer_GetStart(lbuf));
1116 
1117  /* get path to n2 */
1118  GWEN_Buffer_Reset(lbuf);
1119 
1120  ln2=n2;
1121  while (ln2) {
1122  GWEN_XMLNODE *tn;
1123  int idx;
1124  char idxbuf[32];
1125 
1126  if (ln2->parent==ln1)
1127  break;
1128 
1129  /* count occurences of this tag in this level */
1130  idx=1;
1131  tn=ln2->parent;
1132  if (tn) {
1133  tn=GWEN_XMLNode_FindFirstTag(tn, ln2->data, 0, 0);
1134 
1135  while (tn) {
1136  if (tn==ln2)
1137  break;
1138  idx++;
1139  tn=GWEN_XMLNode_FindNextTag(tn, ln2->data, 0, 0);
1140  }
1141  }
1142 
1143  snprintf(idxbuf, sizeof(idxbuf), "[%d]", idx);
1144  idxbuf[sizeof(idxbuf)-1]=0;
1145  GWEN_Buffer_InsertString(lbuf, idxbuf);
1147  GWEN_Buffer_InsertByte(lbuf, '/');
1148  ln2=ln2->parent;
1149  }
1150  /*DBG_ERROR(GWEN_LOGDOMAIN, "Path so far: %s", GWEN_Buffer_GetStart(lbuf)); */
1151  assert(ln2);
1152 
1153  /* append path to n2 */
1154  GWEN_Buffer_AppendBuffer(nbuf, lbuf);
1155  GWEN_Buffer_free(lbuf);
1156  return 0;
1157 }
1158 
1159 
1160 
1161 void *GWEN_XMLNode_HandlePath(const char *entry,
1162  void *data,
1163  int idx,
1164  uint32_t flags)
1165 {
1166  GWEN_XMLNODE *n;
1167  GWEN_XMLNODE *nn;
1168  int i;
1169 
1170  n=(GWEN_XMLNODE *)data;
1171 
1172  if (flags & GWEN_PATH_FLAGS_VARIABLE) {
1174  "GWEN_PATH_FLAGS_VARIABLE not allowed for XPATH");
1175  return 0;
1176  }
1177 
1178  if (flags & GWEN_PATH_FLAGS_ROOT) {
1179  while (n->parent)
1180  n=n->parent;
1181  if (*entry=='/')
1182  entry++;
1183  }
1184 
1185  if (strcasecmp(entry, "..")==0) {
1186  return n->parent;
1187  }
1188  else if (strcasecmp(entry, ".")==0 ||
1189  strcasecmp(entry, "here()")==0) {
1190  return n;
1191  }
1192 
1193  /* check whether we are allowed to simply create the node */
1194  if (
1195  ((flags & GWEN_PATH_FLAGS_LAST) &&
1196  (((flags & GWEN_PATH_FLAGS_VARIABLE) &&
1197  (flags & GWEN_PATH_FLAGS_CREATE_VAR)) ||
1198  (!(flags & GWEN_PATH_FLAGS_VARIABLE) &&
1199  (flags & GWEN_PATH_FLAGS_CREATE_GROUP)))
1200  ) ||
1201  (
1202  !(flags & GWEN_PATH_FLAGS_LAST) &&
1203  (flags & GWEN_PATH_FLAGS_PATHCREATE))
1204  ) {
1205  /* simply create the new variable/group */
1206  if (flags & GWEN_PATH_FLAGS_VARIABLE) {
1207  /* not allowed for now */
1208  return 0;
1209  }
1210  else {
1211  if (idx!=0) {
1213  "Can not create tag with index!=1 (%s)", entry);
1214  return 0;
1215  }
1217  "Unconditionally creating tag \"%s\"", entry);
1219  GWEN_XMLNode_AddChild(n, nn);
1220  return nn;
1221  }
1222  }
1223 
1224  /* find the node */
1225  i=idx;
1226  nn=GWEN_XMLNode_FindFirstTag(n, entry, 0, 0);
1227  while (nn && i--) {
1228  nn=GWEN_XMLNode_FindNextTag(nn, entry, 0, 0);
1229  }
1230 
1231  if (!nn) {
1232  /* node not found, check, if we are allowed to create it */
1233  if (
1234  (!(flags & GWEN_PATH_FLAGS_LAST) &&
1235  (flags & GWEN_PATH_FLAGS_PATHMUSTEXIST)) ||
1237  ) {
1239  "Tag \"%s\" does not exist", entry);
1240  return 0;
1241  }
1242  /* create the new variable/group */
1243  if (idx!=0) {
1245  "Can not create tag with index!=1 (%s)", entry);
1246  return 0;
1247  }
1249  "Tag \"%s\" not found, creating", entry);
1251  GWEN_XMLNode_AddChild(n, nn);
1252  } /* if node not found */
1253  else {
1254  /* node does exist, check whether this is ok */
1255  if (
1256  ((flags & GWEN_PATH_FLAGS_LAST) &&
1257  (flags & GWEN_PATH_FLAGS_NAMEMUSTNOTEXIST)) ||
1258  (!(flags & GWEN_PATH_FLAGS_LAST) &&
1260  ) {
1261  DBG_VERBOUS(GWEN_LOGDOMAIN, "Entry \"%s\" already exists", entry);
1262  return 0;
1263  }
1264  }
1265 
1266  return nn;
1267 }
1268 
1269 
1270 
1272  const char *path,
1273  uint32_t flags)
1274 {
1275  return (GWEN_XMLNODE *)GWEN_Path_HandleWithIdx(path,
1276  (void *)n,
1277  flags,
1279 }
1280 
1281 
1282 
1284 {
1285  assert(n);
1286  return GWEN_XMLNode_List_First(n->headers);
1287 }
1288 
1289 
1290 
1292 {
1293  assert(n);
1294  assert(nh);
1295  GWEN_XMLNode_List_Add(nh, n->headers);
1296 }
1297 
1298 
1299 
1301 {
1302  assert(n);
1303  assert(nh);
1305 }
1306 
1307 
1308 
1310 {
1311  assert(n);
1312  GWEN_XMLNode_List_Clear(n->headers);
1313 }
1314 
1315 
1316 
1318 {
1319  assert(n);
1320  return n->nameSpaces;
1321 }
1322 
1323 
1324 
1326  const char *s)
1327 {
1329 
1330  assert(n);
1331  ns=GWEN_XMLNode_NameSpace_List_First(n->nameSpaces);
1332  while (ns) {
1333  const char *d;
1334 
1336  if (d && strcasecmp(d, s)==0)
1337  return ns;
1339  }
1340 
1341  return NULL;
1342 }
1343 
1344 
1345 
1347  const char *s)
1348 {
1350 
1351  assert(n);
1352  ns=GWEN_XMLNode_NameSpace_List_First(n->nameSpaces);
1353  while (ns) {
1354  const char *d;
1355 
1357  if (d && strcasecmp(d, s)==0)
1358  return ns;
1360  }
1361 
1362  return NULL;
1363 }
1364 
1365 
1366 
1368 {
1369  assert(n);
1370  assert(ns);
1372 }
1373 
1374 
1375 
1376 
1377 
1378 
1379 
1380 
1381 
1382 
1383 
1385  const char *prefix,
1386  const char *name)
1387 {
1388  GWEN_BUFFER *nbuf;
1389  int rv;
1390 
1391  nbuf=GWEN_Buffer_new(0, 32, 0, 1);
1392  if (prefix)
1393  GWEN_Buffer_AppendString(nbuf, prefix);
1394  GWEN_Buffer_AppendByte(nbuf, ':');
1395  GWEN_Buffer_AppendString(nbuf, name);
1398  GWEN_Buffer_free(nbuf);
1399  return rv;
1400 }
1401 
1402 
1403 
1405  const char *s)
1406 {
1408 
1409  it=GWEN_StringList2_First(sl);
1410  if (it) {
1411  const char *t;
1412 
1414  assert(t);
1415  while (t) {
1416  const char *p;
1417 
1418  p=strchr(t, ':');
1419  assert(p);
1420  if ((s==0 && p==t) || (s && strncasecmp(t, s, p-t)==0))
1421  return t;
1423  } /* while */
1425  }
1426  return 0;
1427 }
1428 
1429 
1430 
1432  const char *s)
1433 {
1435 
1436  it=GWEN_StringList2_First(sl);
1437  if (it) {
1438  const char *t;
1439 
1441  assert(t);
1442  while (t) {
1443  const char *p;
1444 
1445  p=strchr(t, ':');
1446  assert(p);
1447  p++;
1448  if (strcasecmp(p, s)==0) {
1450  return t;
1451  }
1453  } /* while */
1455  }
1456  return 0;
1457 }
1458 
1459 
1460 
1462  const char *prefix,
1463  const char *name)
1464 {
1465  GWEN_BUFFER *nbuf;
1467 
1468  nbuf=GWEN_Buffer_new(0, 32, 0, 1);
1469  if (prefix)
1470  GWEN_Buffer_AppendString(nbuf, prefix);
1471  GWEN_Buffer_AppendByte(nbuf, ':');
1472  GWEN_Buffer_AppendString(nbuf, name);
1473 
1474  it=GWEN_StringList2_First(sl);
1475  if (it) {
1476  const char *t;
1477 
1479  assert(t);
1480  while (t) {
1481  const char *p;
1482 
1483  p=strchr(t, ':');
1484  assert(p);
1485  p++;
1486  if (strcasecmp(p, GWEN_Buffer_GetStart(nbuf))==0) {
1488  GWEN_Buffer_free(nbuf);
1489  return t;
1490  }
1492  } /* while */
1494  }
1495 
1496  GWEN_Buffer_free(nbuf);
1497  return 0;
1498 }
1499 
1500 
1501 
1503  GWEN_STRINGLIST2 *sl,
1504  const char *currentNameSpace)
1505 {
1506  GWEN_XMLPROPERTY *pr;
1507  GWEN_XMLNODE *nn;
1508  char *localNameSpace;
1509 
1510  localNameSpace=0;
1511 
1512  /* remove all unnecessary namespace declarations from this node */
1513  pr=n->properties;
1514  while (pr) {
1515  GWEN_XMLPROPERTY *prNext;
1516 
1517  prNext=pr->next;
1518  if (strcasecmp(pr->name, "xmlns")==0) {
1519  /* default namespace changed ? */
1520  if (localNameSpace) {
1521  if (strcasecmp(pr->value, localNameSpace)==0) {
1522  /* already mentioned name space, remove duplicate property */
1523  GWEN_XMLProperty_del(pr, &n->properties);
1525  }
1526  else {
1527  /* current namespace changed */
1528  GWEN_Memory_dealloc(localNameSpace);
1529  localNameSpace=GWEN_Memory_strdup(pr->value);
1530  }
1531  }
1532  else if (currentNameSpace) {
1533  if (strcasecmp(pr->value, currentNameSpace)==0) {
1534  /* already active name space, remove property */
1535  GWEN_XMLProperty_del(pr, &n->properties);
1537  }
1538  else {
1539  /* current namespace changed */
1540  GWEN_Memory_dealloc(localNameSpace);
1541  localNameSpace=GWEN_Memory_strdup(pr->value);
1542  }
1543  }
1544  else {
1545  /* set current namespace */
1546  GWEN_Memory_dealloc(localNameSpace);
1547  localNameSpace=GWEN_Memory_strdup(pr->value);
1548  }
1549  }
1550  else if (strncasecmp(pr->name, "xmlns:", 6)==0) {
1551  const char *prefix;
1552  const char *x;
1553 
1554  prefix=strchr(pr->name, ':');
1555  prefix++;
1556 
1557  /* check for redefinition */
1558  x=GWEN_XML_FindNameSpaceByName(sl, prefix);
1559  if (x) {
1560  const char *p;
1561 
1562  /* prefix already in use, check whether it is the same namespace */
1563  p=strchr(x, ':');
1564  assert(p);
1565  p++;
1566  if (strcasecmp(p, pr->value)!=0) {
1567  GWEN_BUFFER *xpath;
1568 
1569  /* same prefix, different namespace */
1570  xpath=GWEN_Buffer_new(0, 256, 0, 1);
1571  GWEN_XMLNode_GetXPath(0, n, xpath);
1573  "Redefinition of namespace prefix \"%s\" in \"%s\"",
1574  prefix, GWEN_Buffer_GetStart(xpath));
1575  GWEN_Buffer_free(xpath);
1576  return -1;
1577  } /* if different namespace for same prefix */
1578  else {
1579  /* already in list, remove property here */
1580  GWEN_XMLProperty_del(pr, &n->properties);
1582  }
1583  }
1584  else {
1585  GWEN_XML_AddNameSpace(sl, prefix, pr->value);
1586  }
1587  }
1588  pr=prNext;
1589  } /* while */
1590 
1591  /* do the same on all sub nodes */
1593  while (nn) {
1594  int rv;
1595 
1597  localNameSpace?localNameSpace:
1598  currentNameSpace);
1599  if (rv) {
1600  GWEN_Memory_dealloc(localNameSpace);
1601  return rv;
1602  }
1603  nn=GWEN_XMLNode_GetNextTag(nn);
1604  }
1605 
1606  GWEN_Memory_dealloc(localNameSpace);
1607  return 0;
1608 }
1609 
1610 
1611 
1613  const char *prefix,
1614  const char *nspace)
1615 {
1616  GWEN_XMLPROPERTY *pr;
1617  const char *p;
1618  int inUse;
1619 
1620  inUse=0;
1621  /* check current tag for prefix */
1622  if (prefix) {
1623  p=strchr(n->data, ':');
1624  if (p) {
1625  if (strncasecmp(n->data, prefix, p-n->data)==0) {
1626  DBG_DEBUG(GWEN_LOGDOMAIN, "Prefix \"%s\" used in tag \"%s\"",
1627  prefix, n->data);
1628  inUse=1;
1629  }
1630  }
1631 
1632  if (!inUse) {
1633  /* check all attributes for prefixes */
1634  pr=n->properties;
1635  while (pr) {
1636  p=strchr(pr->name, ':');
1637  if (p) {
1638  if (strncasecmp(pr->name, prefix, p-pr->name)==0) {
1640  "Prefix \"%s\" used in attribute \"%s\" of tag \"%s\"",
1641  prefix, pr->name, n->data);
1642  inUse=1;
1643  break;
1644  }
1645  else {
1647  "Prefix \"%s\" not used in attribute \"%s\" of tag \"%s\"",
1648  prefix, pr->name, n->data);
1649  }
1650  }
1651  pr=pr->next;
1652  } /* while */
1653  }
1654  } /* if prefix */
1655  else {
1656  /* no prefix, check whether the current element hasn't any */
1657  p=strchr(n->data, ':');
1658  if (!p) {
1659  /* current tag has no prefix, check whether we have a namespace
1660  * declaration here */
1661  if (GWEN_XMLNode_GetProperty(n, "xmlns", 0)==0) {
1662  /* no, so the current namespace from above is used */
1664  "No prefix, current namespace is used");
1665  inUse=1;
1666  }
1667  }
1668  } /* if no prefix */
1669 
1670  if (inUse) {
1671  GWEN_BUFFER *nbuf;
1672 
1673  nbuf=GWEN_Buffer_new(0, 32, 0, 1);
1674  GWEN_Buffer_AppendString(nbuf, "xmlns");
1675  if (prefix) {
1676  GWEN_Buffer_AppendByte(nbuf, ':');
1677  GWEN_Buffer_AppendString(nbuf, prefix);
1678  }
1679  GWEN_XMLNode__SetProperty(n, GWEN_Buffer_GetStart(nbuf), nspace, 1);
1680  GWEN_Buffer_free(nbuf);
1681  return 1;
1682  }
1683 
1684  return 0;
1685 }
1686 
1687 
1688 
1690  const char *prefix,
1691  const char *nspace)
1692 {
1693  GWEN_XMLNODE *nn;
1694  int rv;
1695 
1696  rv=GWEN_XMLNode__CheckAndSetNameSpace(n, prefix, nspace);
1697  if (rv)
1698  return rv;
1699 
1701  while (nn) {
1702  rv=GWEN_XMLNode__CheckAndSetNameSpace(nn, prefix, nspace);
1703  if (rv==-1)
1704  return rv;
1705  else if (rv==0) {
1706  /* check children */
1707  rv=GWEN_XMLNode__SetNameSpaces(nn, prefix, nspace);
1708  if (rv)
1709  return rv;
1710  }
1711 
1712  nn=GWEN_XMLNode_GetNextTag(nn);
1713  }
1714 
1715  return 0;
1716 }
1717 
1718 
1719 
1721 {
1722  GWEN_XMLPROPERTY *pr;
1723  GWEN_XMLNODE *nn;
1724  int rv;
1725 
1726  /* move all namespace declarations from this node to the nodes
1727  * of first use */
1728  pr=n->properties;
1729  while (pr) {
1730  GWEN_XMLPROPERTY *prNext;
1731 
1732  prNext=pr->next;
1733  if (strcasecmp(pr->name, "xmlns")==0 ||
1734  strncasecmp(pr->name, "xmlns:", 6)==0) {
1735  const char *prefix;
1736 
1737  prefix=strchr(pr->name, ':');
1738  if (prefix)
1739  prefix++;
1740 
1741  GWEN_XMLProperty_del(pr, &n->properties);
1742  rv=GWEN_XMLNode__SetNameSpaces(n, prefix, pr->value);
1743  DBG_DEBUG(GWEN_LOGDOMAIN, "Removing property \"%s\"",
1744  pr->name);
1746  if (rv==-1)
1747  return rv;
1748  }
1749  pr=prNext;
1750  } /* while */
1751 
1752  /* do the same on all sub nodes */
1754  while (nn) {
1756  if (rv) {
1757  return rv;
1758  }
1759  nn=GWEN_XMLNode_GetNextTag(nn);
1760  }
1761 
1762  return 0;
1763 }
1764 
1765 
1766 
1767 
1769 {
1770  const char *ns;
1771  int rv;
1772  GWEN_STRINGLIST2 *sl;
1773 
1774  ns=GWEN_XMLNode_GetProperty(n, "xmlns", 0);
1775  sl=GWEN_StringList2_new();
1776  rv=GWEN_XMLNode__CheckNameSpaceDecls1(n, sl, ns);
1778  if (rv) {
1779  DBG_INFO(GWEN_LOGDOMAIN, "here");
1780  return rv;
1781  }
1782 
1783  //rv=GWEN_XMLNode__CheckNameSpaceDecls2(n, ns);
1785  if (rv==-1)
1786  return rv;
1787  return 0;
1788 }
1789 
1790 
1791 
1793 {
1794  if (n && n->type==GWEN_XMLNodeTypeTag && n->data) {
1795  GWEN_XMLNODE *nn;
1796  GWEN_XMLPROPERTY *pp;
1797 
1798  if (n->nameSpace==0) {
1799  char *p;
1800 
1801  p=strchr(n->data, ':');
1802  if (p) {
1803  int len=p-n->data;
1804  char *s;
1805 
1806  n->nameSpace=(char *)GWEN_Memory_malloc(len);
1807  assert(n->nameSpace);
1808  memmove(n->nameSpace, n->data, len);
1809  n->nameSpace[len-1]=0;
1810  s=GWEN_Memory_strdup(p+1);
1811  free(n->data);
1812  n->data=s;
1813  }
1814  }
1815 
1816  pp=n->properties;
1817  while (pp) {
1818  if (pp->nameSpace==0) {
1819  char *p;
1820 
1821  p=strchr(pp->name, ':');
1822  if (p) {
1823  int len=p-pp->name;
1824  char *s;
1825 
1826  pp->nameSpace=(char *)GWEN_Memory_malloc(len);
1827  assert(pp->nameSpace);
1828  memmove(pp->nameSpace, pp->name, len);
1829  pp->nameSpace[len-1]=0;
1830  s=GWEN_Memory_strdup(p+1);
1831  free(pp->name);
1832  pp->name=s;
1833  }
1834  }
1835 
1836  pp=pp->next;
1837  }
1838 
1839  nn=GWEN_XMLNode_List_First(n->children);
1840  while (nn) {
1841  int rv;
1842 
1844  if (rv<0) {
1845  DBG_DEBUG(GWEN_LOGDOMAIN, "here (%d)", rv);
1846  return rv;
1847  }
1848  nn=GWEN_XMLNode_List_Next(nn);
1849  }
1850  }
1851 
1852  return 0;
1853 }
1854 
1855 
1856 
1857 
1858 
1859 
1860 
1861 
1862 
1864 {
1865  GWEN_XMLNODE_PATH *p;
1866 
1868  return p;
1869 }
1870 
1871 
1872 
1874 {
1875  GWEN_XMLNODE_PATH *p;
1876  unsigned int i;
1877 
1879  p->pos=np->pos;
1880  for (i=0; i<np->pos; i++) {
1881  p->nodes[i]=np->nodes[i];
1882  }
1883  return p;
1884 }
1885 
1886 
1887 
1889 {
1890  GWEN_FREE_OBJECT(np);
1891 }
1892 
1893 
1894 
1896  GWEN_XMLNODE *n)
1897 {
1898  unsigned int i;
1899 
1900  if (np->pos>=GWEN_XML_MAX_DEPTH) {
1901  DBG_ERROR(GWEN_LOGDOMAIN, "Path too deep");
1902  return 1;
1903  }
1904 
1905  /* check for double entries */
1906  for (i=0; i<np->pos; i++) {
1907  assert(np->nodes[i]!=n);
1908  }
1909  np->nodes[np->pos++]=n;
1910  DBG_DEBUG(GWEN_LOGDOMAIN, "Dived to %d", np->pos);
1911  return 0;
1912 }
1913 
1914 
1915 
1917 {
1918  if (np->pos==0) {
1919  DBG_DEBUG(GWEN_LOGDOMAIN, "Root reached");
1920  return 0;
1921  }
1922  DBG_DEBUG(GWEN_LOGDOMAIN, "Surfaced to %d", np->pos-1);
1923  return np->nodes[--np->pos];
1924 }
1925 
1926 
1927 
1929 {
1930  unsigned int i;
1931 
1932  if (np->pos==0) {
1933  DBG_NOTICE(GWEN_LOGDOMAIN, "Empty path");
1934  }
1935  for (i=0; i<np->pos; i++) {
1936  DBG_NOTICE(GWEN_LOGDOMAIN, "Path entry %d:", i);
1937  GWEN_XMLNode_Dump(np->nodes[i], 1);
1938  }
1939 }
1940 
1941 
1942 
1943 
1944 
1945 
1946 
1947 
1948 
1949 
1950 
1952  const char *url)
1953 {
1955 
1958 
1959  if (name)
1960  ns->name=GWEN_Memory_strdup(name);
1961  if (url)
1962  ns->url=GWEN_Memory_strdup(url);
1963 
1964  return ns;
1965 }
1966 
1967 
1968 
1970 {
1971  if (ns) {
1973  free(ns->url);
1974  free(ns->name);
1975  GWEN_FREE_OBJECT(ns);
1976  }
1977 }
1978 
1979 
1980 
1982 {
1984 
1985  assert(ns);
1986  nns=GWEN_XMLNode_NameSpace_new(ns->name, ns->url);
1987  return nns;
1988 }
1989 
1990 
1991 
1993 {
1994  assert(ns);
1995  return ns->name;
1996 }
1997 
1998 
1999 
2001 {
2002  assert(ns);
2003  return ns->url;
2004 }
2005 
2006 
2007 
2008 
2009 
2010 
2011 #include "xmlrw.c"
2012 #include "xmlglobalize.c"
2013 
2014 
2015 
GWEN_XMLNODE * GWEN_XMLNode_GetHeader(const GWEN_XMLNODE *n)
Definition: xml.c:1283
uint32_t GWEN_XMLNode_GetUsage(const GWEN_XMLNODE *n)
Definition: xml.c:362
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
struct GWEN_STRINGLISTENTRYSTRUCT GWEN_STRINGLISTENTRY
Definition: stringlist.h:51
int GWEN_Buffer_InsertString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:999
struct GWEN_XMLNODE_NAMESPACE GWEN_XMLNODE_NAMESPACE
Definition: xml.h:150
void GWEN_XMLNode_AddHeader(GWEN_XMLNODE *n, GWEN_XMLNODE *nh)
Definition: xml.c:1291
const char * GWEN_XML_FindNameSpace(GWEN_STRINGLIST2 *sl, const char *prefix, const char *name)
Definition: xml.c:1461
GWEN_XMLNODE_NAMESPACE_LIST * GWEN_XMLNode_GetNameSpaces(const GWEN_XMLNODE *n)
Definition: xml.c:1317
#define GWEN_ERROR_INVALID
Definition: error.h:67
const char * GWEN_XMLNode_GetProperty(const GWEN_XMLNODE *n, const char *name, const char *defaultValue)
Definition: xml.c:239
const char * GWEN_XMLNode_NameSpace_GetName(const GWEN_XMLNODE_NAMESPACE *ns)
Definition: xml.c:1992
GWEN_XMLNODE * GWEN_XMLNode_GetNextData(const GWEN_XMLNODE *n)
Definition: xml.c:691
GWEN_XMLNODE_NAMESPACE * GWEN_XMLNode_FindNameSpaceByName(const GWEN_XMLNODE *n, const char *s)
Definition: xml.c:1325
int GWEN_XML_AddNameSpace(GWEN_STRINGLIST2 *sl, const char *prefix, const char *name)
Definition: xml.c:1384
void GWEN_XMLProperty_freeAll(GWEN_XMLPROPERTY *p)
Definition: xml.c:130
GWEN_XMLNODE * GWEN_XMLNode_FindNextTag(const GWEN_XMLNODE *n, const char *tname, const char *pname, const char *pvalue)
Definition: xml.c:754
char * GWEN_Memory_strdup(const char *s)
Definition: memory.c:76
int GWEN_XMLNode__SetNameSpaces(GWEN_XMLNODE *n, const char *prefix, const char *nspace)
Definition: xml.c:1689
#define DBG_NOTICE(dbg_logger, format, args...)
Definition: debug.h:151
GWEN_XMLNODE * GWEN_XMLNode_GetFirstData(const GWEN_XMLNODE *n)
Definition: xml.c:684
struct GWEN__XMLPROPERTY GWEN_XMLPROPERTY
Definition: xml_l.h:37
const char * GWEN_XMLNode_NameSpace_GetUrl(const GWEN_XMLNODE_NAMESPACE *ns)
Definition: xml.c:2000
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define NULL
Definition: binreloc.c:300
void GWEN_Memory_dealloc(void *p)
Definition: memory.c:69
#define GWEN_PATH_FLAGS_CREATE_GROUP
Definition: path.h:96
GWEN_XMLNODE * GWEN_XMLNode_GetFirstOfType(const GWEN_XMLNODE *n, GWEN_XMLNODE_TYPE t)
Definition: xml.c:634
#define DBG_VERBOUS(dbg_logger, format, args...)
Definition: debug.h:217
void GWEN_XMLNode_SetProperty(GWEN_XMLNODE *n, const char *name, const char *value)
Definition: xml.c:322
void GWEN_XMLNode_Path_Dump(GWEN_XMLNODE_PATH *np)
Definition: xml.c:1928
void GWEN_XMLNode_Dump(const GWEN_XMLNODE *n, int ind)
Definition: xml.c:472
#define DBG_WARN(dbg_logger, format, args...)
Definition: debug.h:124
GWEN_XMLNODE * GWEN_XMLNode_FindTag(const GWEN_XMLNODE *n, const char *tname, const char *pname, const char *pvalue)
Definition: xml.c:703
int GWEN_XMLNode_IsChildOf(const GWEN_XMLNODE *parent, const GWEN_XMLNODE *child)
Definition: xml.c:1039
void GWEN_XMLNode_RemoveChildren(GWEN_XMLNODE *n)
Definition: xml.c:580
void GWEN_XMLNode_SetCharValue(GWEN_XMLNODE *n, const char *name, const char *value)
Definition: xml.c:857
#define GWEN_LOGDOMAIN
Definition: logger.h:35
struct GWEN_XMLNODE_PATH GWEN_XMLNODE_PATH
Definition: xml.h:847
void GWEN_XMLNode_AddNameSpace(GWEN_XMLNODE *n, const GWEN_XMLNODE_NAMESPACE *ns)
Definition: xml.c:1367
GWEN_XMLNODE * GWEN_XMLNode_new(GWEN_XMLNODE_TYPE t, const char *data)
Definition: xml.c:144
int GWEN_Buffer_ReserveBytes(GWEN_BUFFER *bf, uint32_t res)
Definition: buffer.c:157
void GWEN_XMLNode_NameSpace_free(GWEN_XMLNODE_NAMESPACE *ns)
Definition: xml.c:1969
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
void GWEN_XMLNode_CopyProperties(GWEN_XMLNODE *tn, const GWEN_XMLNODE *sn, int overwrite)
Definition: xml.c:588
void GWEN_XMLNode_SetData(GWEN_XMLNODE *n, const char *data)
Definition: xml.c:377
GWEN_XMLPROPERTY * GWEN_XMLNode_GetFirstProperty(const GWEN_XMLNODE *n)
Definition: xml.c:1005
#define GWEN_LIST_DEL(typ, sr, head)
Definition: misc.h:116
GWEN_STRINGLISTENTRY * GWEN_StringList_FirstEntry(const GWEN_STRINGLIST *sl)
Definition: stringlist.c:386
const char * GWEN_StringList2Iterator_Data(GWEN_STRINGLIST2_ITERATOR *li)
Definition: stringlist2.c:456
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
Definition: buffer.c:650
GWEN_XMLNODE_NAMESPACE * GWEN_XMLNode_NameSpace_new(const char *name, const char *url)
Definition: xml.c:1951
const char * GWEN_StringListEntry_Data(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:402
int GWEN_XMLNode_GetIntValue(const GWEN_XMLNODE *n, const char *name, int defValue)
Definition: xml.c:883
GWEN_XMLNODE * GWEN_XMLNode_GetChild(const GWEN_XMLNODE *n)
Definition: xml.c:409
#define GWEN_PATH_FLAGS_LAST
Definition: path.h:166
const char * GWEN_XML_FindNameSpaceByPrefix(GWEN_STRINGLIST2 *sl, const char *s)
Definition: xml.c:1404
#define GWEN_PATH_FLAGS_NAMEMUSTNOTEXIST
Definition: path.h:89
GWEN_XMLNODE * GWEN_XMLNode_FindFirstTag(const GWEN_XMLNODE *n, const char *tname, const char *pname, const char *pvalue)
Definition: xml.c:736
GWEN_XMLNODE_NAMESPACE * GWEN_XMLNode_FindNameSpaceByUrl(const GWEN_XMLNODE *n, const char *s)
Definition: xml.c:1346
#define GWEN_PATH_FLAGS_ROOT
Definition: path.h:174
void GWEN_XMLNode_DelHeader(GWEN_XMLNODE *n, GWEN_XMLNODE *nh)
Definition: xml.c:1300
void GWEN_XMLProperty_insert(GWEN_XMLPROPERTY *p, GWEN_XMLPROPERTY **head)
Definition: xml.c:118
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
int GWEN_XMLNode_GetIntProperty(const GWEN_XMLNODE *n, const char *name, int defaultValue)
Definition: xml.c:263
GWEN_XMLNODE_TYPE GWEN_XMLNode_GetType(const GWEN_XMLNODE *n)
Definition: xml.c:458
GWEN_XMLNODE_PATH * GWEN_XMLNode_Path_new(void)
Definition: xml.c:1863
const char * GWEN_StringList2Iterator_Next(GWEN_STRINGLIST2_ITERATOR *li)
Definition: stringlist2.c:449
const char * GWEN_XMLNode_GetCharValue(const GWEN_XMLNODE *n, const char *name, const char *defValue)
Definition: xml.c:772
GWEN_XMLPROPERTY * GWEN_XMLNode_GetNextProperty(const GWEN_XMLNODE *n, const GWEN_XMLPROPERTY *pr)
Definition: xml.c:1013
int GWEN_XMLNode_SetIntValueByPath(GWEN_XMLNODE *n, uint32_t flags, const char *name, int value)
Definition: xml.c:963
int GWEN_XMLNode__CheckAndSetNameSpace(GWEN_XMLNODE *n, const char *prefix, const char *nspace)
Definition: xml.c:1612
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:209
int GWEN_Buffer_AppendBuffer(GWEN_BUFFER *bf, GWEN_BUFFER *sf)
Definition: buffer.c:507
int GWEN_XMLNode__CheckNameSpaceDecls3(GWEN_XMLNODE *n)
Definition: xml.c:1720
GWEN_XMLPROPERTY * GWEN_XMLProperty_new(const char *name, const char *value)
Definition: xml.c:72
void GWEN_StringList2_free(GWEN_STRINGLIST2 *sl2)
Definition: stringlist2.c:63
GWEN_XMLNODE * GWEN_XMLNode_GetNextTag(const GWEN_XMLNODE *n)
Definition: xml.c:672
const char * GWEN_XMLNode_GetNamespace(const GWEN_XMLNODE *n)
Definition: xml.c:389
int GWEN_Buffer_InsertByte(GWEN_BUFFER *bf, char c)
Definition: buffer.c:911
#define GWEN_PATH_FLAGS_VARIABLE
Definition: path.h:111
void * GWEN_Memory_malloc(size_t wsize)
Definition: memory.c:39
GWEN_XMLNODE * GWEN_XMLNode_Path_Surface(GWEN_XMLNODE_PATH *np)
Definition: xml.c:1916
GWEN_XMLNODE * GWEN_XMLNode_GetNodeByXPath(GWEN_XMLNODE *n, const char *path, uint32_t flags)
Definition: xml.c:1271
GWEN_XMLNODE * GWEN_XMLNode_Next(const GWEN_XMLNODE *n)
Definition: xml.c:465
GWEN_XMLNODE * GWEN_XMLNode_FindNode(const GWEN_XMLNODE *node, GWEN_XMLNODE_TYPE t, const char *data)
Definition: xml.c:543
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition: stringlist.h:54
void GWEN_XMLNode_SetNamespace(GWEN_XMLNODE *n, const char *s)
Definition: xml.c:397
GWEN_XMLNODE * GWEN_XMLNode_List_Next(const GWEN_XMLNODE *element)
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition: buffer.c:394
void * GWEN_XMLNode_HandlePath(const char *entry, void *data, int idx, uint32_t flags)
Definition: xml.c:1161
void GWEN_XMLNode_List_Del(GWEN_XMLNODE *element)
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
void GWEN_XMLNode_free(GWEN_XMLNODE *n)
Definition: xml.c:160
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
GWEN_LIST2_FUNCTIONS(TYPEMAKER2_TYPE, Typemaker2_Type)
GWEN_XMLNODE * GWEN_XMLNode_GetParent(const GWEN_XMLNODE *n)
Definition: xml.c:416
void GWEN_XMLNode_DecUsage(GWEN_XMLNODE *n)
Definition: xml.c:350
int GWEN_XMLNode_GetXPath(const GWEN_XMLNODE *n1, const GWEN_XMLNODE *n2, GWEN_BUFFER *nbuf)
Definition: xml.c:1057
#define GWEN_PATH_FLAGS_PATHCREATE
Definition: path.h:78
#define GWEN_PATH_FLAGS_CREATE_VAR
Definition: path.h:103
void GWEN_XMLNode_SetIntProperty(GWEN_XMLNODE *n, const char *name, int value)
Definition: xml.c:330
GWEN_XMLNODE_TYPE
Definition: xml.h:135
#define GWEN_PATH_FLAGS_PATHMUSTNOTEXIST
Definition: path.h:70
void GWEN_XMLNode_NameSpace_List_free(GWEN_XMLNODE_NAMESPACE_LIST *l)
#define GWEN_LIST_INSERT(typ, sr, head)
Definition: misc.h:100
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
GWEN_XMLNODE * GWEN_XMLNode_GetFirstTag(const GWEN_XMLNODE *n)
Definition: xml.c:665
int GWEN_XMLNode_SetCharValueByPath(GWEN_XMLNODE *n, uint32_t flags, const char *name, const char *value)
Definition: xml.c:913
const char * GWEN_XMLNode_GetData(const GWEN_XMLNODE *n)
Definition: xml.c:370
GWEN_XMLNODE_NAMESPACE * GWEN_XMLNode_NameSpace_dup(const GWEN_XMLNODE_NAMESPACE *ns)
Definition: xml.c:1981
const char * GWEN_XMLNode_GetLocalizedCharValue(const GWEN_XMLNODE *n, const char *name, const char *defValue)
Definition: xml.c:806
struct GWEN_STRINGLIST2 GWEN_STRINGLIST2
Definition: stringlist2.h:43
void GWEN_XMLProperty_del(GWEN_XMLPROPERTY *p, GWEN_XMLPROPERTY **head)
Definition: xml.c:124
void GWEN_XMLNode__SetProperty(GWEN_XMLNODE *n, const char *name, const char *value, int doInsert)
Definition: xml.c:290
int GWEN_Text_ComparePattern(const char *w, const char *p, int sensecase)
Definition: text.c:1208
GWEN_XMLNODE * GWEN_XMLNode_GetNextOfType(const GWEN_XMLNODE *n, GWEN_XMLNODE_TYPE t)
Definition: xml.c:651
GWEN_STRINGLISTENTRY * GWEN_StringListEntry_Next(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:394
GWEN_XMLNODE_PATH * GWEN_XMLNode_Path_dup(const GWEN_XMLNODE_PATH *np)
Definition: xml.c:1873
void GWEN_XMLNode_List_Add(GWEN_XMLNODE *element, GWEN_XMLNODE_LIST *list)
#define GWEN_PATH_FLAGS_PATHMUSTEXIST
Definition: path.h:66
GWEN_STRINGLIST2 * GWEN_StringList2_new(void)
Definition: stringlist2.c:45
GWEN_XMLNODE * GWEN_XMLNode_dup(const GWEN_XMLNODE *n)
Definition: xml.c:187
void GWEN_XMLNode_List_free(GWEN_XMLNODE_LIST *l)
int GWEN_XMLNode__CheckNameSpaceDecls1(GWEN_XMLNODE *n, GWEN_STRINGLIST2 *sl, const char *currentNameSpace)
Definition: xml.c:1502
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:178
int GWEN_XMLNode_Path_Dive(GWEN_XMLNODE_PATH *np, GWEN_XMLNODE *n)
Definition: xml.c:1895
void GWEN_StringList2Iterator_free(GWEN_STRINGLIST2_ITERATOR *li)
Definition: stringlist2.c:435
void GWEN_XMLNode_NameSpace_List_Add(GWEN_XMLNODE_NAMESPACE *element, GWEN_XMLNODE_NAMESPACE_LIST *list)
int GWEN_XMLNode_GetIntValueByPath(GWEN_XMLNODE *n, const char *name, int defValue)
Definition: xml.c:985
#define GWEN_LIST_INIT(t, element)
Definition: list1.h:465
const char * GWEN_XMLProperty_GetName(const GWEN_XMLPROPERTY *pr)
Definition: xml.c:1023
int GWEN_XMLNode_NormalizeNameSpaces(GWEN_XMLNODE *n)
Definition: xml.c:1768
void GWEN_XMLNode_ClearHeaders(GWEN_XMLNODE *n)
Definition: xml.c:1309
const char * GWEN_XMLNode_GetCharValueByPath(GWEN_XMLNODE *n, const char *name, const char *defValue)
Definition: xml.c:941
void GWEN_XMLNode_AddChildrenOnly(GWEN_XMLNODE *n, GWEN_XMLNODE *nn, int copythem)
Definition: xml.c:432
void GWEN_XMLNode_Path_free(GWEN_XMLNODE_PATH *np)
Definition: xml.c:1888
const char * GWEN_XMLProperty_GetValue(const GWEN_XMLPROPERTY *pr)
Definition: xml.c:1031
#define GWEN_LIST_ADD(typ, sr, head)
Definition: misc.h:82
#define GWEN_LIST_FUNCTIONS(t, pr)
Definition: list1.h:366
void * GWEN_Path_HandleWithIdx(const char *path, void *data, uint32_t flags, GWEN_PATHIDXHANDLERPTR elementFunction)
Definition: path.c:206
void GWEN_XMLNode_IncUsage(GWEN_XMLNODE *n)
Definition: xml.c:342
void GWEN_XMLProperty_free(GWEN_XMLPROPERTY *p)
Definition: xml.c:86
void GWEN_XMLNode_List_Clear(GWEN_XMLNODE_LIST *l)
GWEN_STRINGLIST2_ITERATOR * GWEN_StringList2_First(const GWEN_STRINGLIST2 *l)
Definition: stringlist2.c:419
GWEN_STRINGLIST * GWEN_I18N_GetCurrentLocaleList(void)
Definition: i18n.c:241
const char * GWEN_XML_FindNameSpaceByName(GWEN_STRINGLIST2 *sl, const char *s)
Definition: xml.c:1431
GWEN_XMLNODE_NAMESPACE * GWEN_XMLNode_NameSpace_List_Next(const GWEN_XMLNODE_NAMESPACE *element)
GWEN_XMLPROPERTY * GWEN_XMLProperty_dup(const GWEN_XMLPROPERTY *p)
Definition: xml.c:98
GWEN_XMLNODE_LIST * GWEN_XMLNode_List_new()
#define GWEN_PATH_FLAGS_NAMEMUSTEXIST
Definition: path.h:84
#define GWEN_LIST_FINI(t, element)
Definition: list1.h:474
GWEN_XMLNODE_NAMESPACE_LIST * GWEN_XMLNode_NameSpace_List_new()
int GWEN_StringList2_AppendString(GWEN_STRINGLIST2 *sl2, const char *s, int take, GWEN_STRINGLIST2_INSERTMODE m)
Definition: stringlist2.c:196
struct GWEN__XMLNODE GWEN_XMLNODE
Definition: xml.h:149
GWEN_XMLNODE * GWEN_XMLNode_List_First(const GWEN_XMLNODE_LIST *l)
void GWEN_XMLProperty_add(GWEN_XMLPROPERTY *p, GWEN_XMLPROPERTY **head)
Definition: xml.c:111
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:989
GWEN_LIST_ITERATOR GWEN_STRINGLIST2_ITERATOR
Definition: stringlist2.h:44
#define GWEN_XML_PATH_FLAGS_OVERWRITE_VALUES
Definition: xml.h:126
GWEN_XMLNODE_NAMESPACE * GWEN_XMLNode_NameSpace_List_First(const GWEN_XMLNODE_NAMESPACE_LIST *l)
int GWEN_XMLNode_StripNamespaces(GWEN_XMLNODE *n)
Definition: xml.c:1792
void GWEN_XMLNode_AddChild(GWEN_XMLNODE *n, GWEN_XMLNODE *child)
Definition: xml.c:423
void GWEN_XMLNode_SetIntValue(GWEN_XMLNODE *n, const char *name, int value)
Definition: xml.c:900
void GWEN_XMLNode_freeAll(GWEN_XMLNODE *n)
Definition: xml.c:175