VPR-7.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
ezxml.h File Reference
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <fcntl.h>
+ Include dependency graph for ezxml.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ezxml
 
struct  ezxml_root
 

Macros

#define EZXML_BUFSIZE   1024 /* size of internal memory buffers */
 
#define EZXML_NAMEM   0x80 /* name is malloced */
 
#define EZXML_TXTM   0x40 /* txt is malloced */
 
#define EZXML_DUP   0x20 /* attribute name and value are strduped */
 
#define EZXML_ERRL   128 /* maximum error string length */
 
#define ezxml_next(xml)   ((xml) ? xml->next : NULL)
 
#define ezxml_name(xml)   ((xml) ? xml->name : NULL)
 
#define ezxml_txt(xml)   ((xml) ? xml->txt : "")
 
#define ezxml_new_d(name)   ezxml_set_flag(ezxml_new(strdup(name)), EZXML_NAMEM)
 
#define ezxml_add_child_d(xml, name, off)   ezxml_set_flag(ezxml_add_child(xml, strdup(name), off), EZXML_NAMEM)
 
#define ezxml_set_txt_d(xml, txt)   ezxml_set_flag(ezxml_set_txt(xml, strdup(txt)), EZXML_TXTM)
 
#define ezxml_set_attr_d(xml, name, value)   ezxml_set_attr(ezxml_set_flag(xml, EZXML_DUP), strdup(name), strdup(value))
 
#define ezxml_move(xml, dest, off)   ezxml_insert(ezxml_cut(xml), dest, off)
 
#define ezxml_remove(xml)   ezxml_free(ezxml_cut(xml))
 

Typedefs

typedef struct ezxmlezxml_t
 
typedef struct ezxml_rootezxml_root_t
 

Functions

ezxml_t ezxml_parse_str (char *s, size_t len)
 
ezxml_t ezxml_parse_fd (int fd)
 
ezxml_t ezxml_parse_file (const char *file)
 
ezxml_t ezxml_parse_fp (FILE *fp)
 
ezxml_t ezxml_child (ezxml_t xml, const char *name)
 
ezxml_t ezxml_idx (ezxml_t xml, int idx)
 
const char * ezxml_attr (ezxml_t xml, const char *attr)
 
ezxml_t ezxml_get (ezxml_t xml,...)
 
char * ezxml_toxml (ezxml_t xml)
 
char ** ezxml_pi (ezxml_t xml, const char *target)
 
void ezxml_free (ezxml_t xml)
 
const char * ezxml_error (ezxml_t xml)
 
ezxml_t ezxml_new (char *name)
 
ezxml_t ezxml_add_child (ezxml_t xml, char *name, size_t off)
 
ezxml_t ezxml_set_txt (ezxml_t xml, char *txt)
 
ezxml_t ezxml_set_attr (ezxml_t xml, char *name, char *value)
 
ezxml_t ezxml_set_flag (ezxml_t xml, short flag)
 
ezxml_t ezxml_cut (ezxml_t xml)
 
ezxml_t ezxml_insert (ezxml_t xml, ezxml_t dest, size_t off)
 

Macro Definition Documentation

#define ezxml_add_child_d (   xml,
  name,
  off 
)    ezxml_set_flag(ezxml_add_child(xml, strdup(name), off), EZXML_NAMEM)

Definition at line 149 of file ezxml.h.

#define EZXML_BUFSIZE   1024 /* size of internal memory buffers */

Definition at line 37 of file ezxml.h.

#define EZXML_DUP   0x20 /* attribute name and value are strduped */

Definition at line 40 of file ezxml.h.

#define EZXML_ERRL   128 /* maximum error string length */

Definition at line 41 of file ezxml.h.

#define ezxml_move (   xml,
  dest,
  off 
)    ezxml_insert(ezxml_cut(xml), dest, off)

Definition at line 178 of file ezxml.h.

#define ezxml_name (   xml)    ((xml) ? xml->name : NULL)

Definition at line 108 of file ezxml.h.

#define EZXML_NAMEM   0x80 /* name is malloced */

Definition at line 38 of file ezxml.h.

#define ezxml_new_d (   name)    ezxml_set_flag(ezxml_new(strdup(name)), EZXML_NAMEM)

Definition at line 142 of file ezxml.h.

#define ezxml_next (   xml)    ((xml) ? xml->next : NULL)

Definition at line 101 of file ezxml.h.

#define ezxml_remove (   xml)    ezxml_free(ezxml_cut(xml))

Definition at line 181 of file ezxml.h.

#define ezxml_set_attr_d (   xml,
  name,
  value 
)    ezxml_set_attr(ezxml_set_flag(xml, EZXML_DUP), strdup(name), strdup(value))

Definition at line 164 of file ezxml.h.

#define ezxml_set_txt_d (   xml,
  txt 
)    ezxml_set_flag(ezxml_set_txt(xml, strdup(txt)), EZXML_TXTM)

Definition at line 156 of file ezxml.h.

#define ezxml_txt (   xml)    ((xml) ? xml->txt : "")

Definition at line 111 of file ezxml.h.

#define EZXML_TXTM   0x40 /* txt is malloced */

Definition at line 39 of file ezxml.h.

Typedef Documentation

typedef struct ezxml_root* ezxml_root_t

Definition at line 60 of file ezxml.h.

typedef struct ezxml* ezxml_t

Definition at line 43 of file ezxml.h.

Function Documentation

ezxml_t ezxml_add_child ( ezxml_t  xml,
char *  name,
size_t  off 
)

Definition at line 1137 of file ezxml.c.

1137  {
1138  ezxml_t child;
1139 
1140  if (!xml)
1141  return NULL;
1142  child = (ezxml_t) memset(malloc(sizeof(struct ezxml)), '\0',
1143  sizeof(struct ezxml));
1144  child->name = name;
1145  child->attr = EZXML_NIL;
1146  child->txt = "";
1147 
1148  return ezxml_insert(child, xml, off);
1149 }
Definition: ezxml.h:44
char * txt
Definition: ezxml.h:47
char * EZXML_NIL[]
Definition: ezxml.c:65
ezxml_t ezxml_insert(ezxml_t xml, ezxml_t dest, size_t off)
Definition: ezxml.c:1089
char * name
Definition: ezxml.h:45
char ** attr
Definition: ezxml.h:46
size_t off
Definition: ezxml.h:48
struct ezxml * ezxml_t
Definition: ezxml.h:43

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

const char* ezxml_attr ( ezxml_t  xml,
const char *  attr 
)

Definition at line 102 of file ezxml.c.

102  {
103  int i = 0, j = 1;
104  ezxml_root_t root = (ezxml_root_t) xml;
105 
106  if (!xml || !xml->attr)
107  return NULL;
108  while (xml->attr[i] && strcmp(attr, xml->attr[i]))
109  i += 2;
110  if (xml->attr[i])
111  return xml->attr[i + 1]; /* found attribute */
112 
113  while (root->xml.parent)
114  root = (ezxml_root_t) root->xml.parent; /* root tag */
115  for (i = 0; root->attr[i] && strcmp(xml->name, root->attr[i][0]); i++)
116  ;
117  if (!root->attr[i])
118  return NULL; /* no matching default attributes */
119  while (root->attr[i][j] && strcmp(attr, root->attr[i][j]))
120  j += 3;
121  return (root->attr[i][j]) ? root->attr[i][j + 1] : NULL; /* found default */
122 }
struct ezxml_root * ezxml_root_t
Definition: ezxml.h:60
char *** attr
Definition: ezxml.h:70
ezxml_t parent
Definition: ezxml.h:53
struct ezxml xml
Definition: ezxml.h:62
char * name
Definition: ezxml.h:45
char ** attr
Definition: ezxml.h:46

+ Here is the caller graph for this function:

ezxml_t ezxml_child ( ezxml_t  xml,
const char *  name 
)

Definition at line 85 of file ezxml.c.

85  {
86  xml = (xml) ? xml->child : NULL;
87  while (xml && strcmp(name, xml->name))
88  xml = xml->sibling;
89  return xml;
90 }
ezxml_t sibling
Definition: ezxml.h:50
char * name
Definition: ezxml.h:45
ezxml_t child
Definition: ezxml.h:52

+ Here is the caller graph for this function:

ezxml_t ezxml_cut ( ezxml_t  xml)

Definition at line 1227 of file ezxml.c.

1227  {
1228  ezxml_t cur;
1229 
1230  if (!xml)
1231  return NULL; /* nothing to do */
1232  if (xml->next)
1233  xml->next->sibling = xml->sibling; /* patch sibling list */
1234 
1235  if (xml->parent) { /* not root tag */
1236  cur = xml->parent->child; /* find head of subtag list */
1237  if (cur == xml)
1238  xml->parent->child = xml->ordered; /* first subtag */
1239  else { /* not first subtag */
1240  while (cur->ordered != xml)
1241  cur = cur->ordered;
1242  cur->ordered = cur->ordered->ordered; /* patch ordered list */
1243 
1244  cur = xml->parent->child; /* go back to head of subtag list */
1245  if (strcmp(cur->name, xml->name)) { /* not in first sibling list */
1246  while (strcmp(cur->sibling->name, xml->name))
1247  cur = cur->sibling;
1248  if (cur->sibling == xml) { /* first of a sibling list */
1249  cur->sibling =
1250  (xml->next) ? xml->next : cur->sibling->sibling;
1251  } else
1252  cur = cur->sibling; /* not first of a sibling list */
1253  }
1254 
1255  while (cur->next && cur->next != xml)
1256  cur = cur->next;
1257  if (cur->next)
1258  cur->next = cur->next->next; /* patch next list */
1259  }
1260  }
1261  xml->ordered = xml->sibling = xml->next = NULL;
1262  return xml;
1263 }
Definition: ezxml.h:44
ezxml_t next
Definition: ezxml.h:49
ezxml_t sibling
Definition: ezxml.h:50
ezxml_t ordered
Definition: ezxml.h:51
ezxml_t parent
Definition: ezxml.h:53
char * name
Definition: ezxml.h:45
ezxml_t child
Definition: ezxml.h:52
const char* ezxml_error ( ezxml_t  xml)

Definition at line 1067 of file ezxml.c.

1067  {
1068  while (xml && xml->parent)
1069  xml = xml->parent; /* find root tag */
1070  return (xml) ? ((ezxml_root_t) xml)->err : "";
1071 }
struct ezxml_root * ezxml_root_t
Definition: ezxml.h:60
ezxml_t parent
Definition: ezxml.h:53
void ezxml_free ( ezxml_t  xml)

Definition at line 1011 of file ezxml.c.

1011  {
1012  ezxml_root_t root = (ezxml_root_t) xml;
1013  int i, j;
1014  char **a, *s;
1015 
1016  if (!xml)
1017  return;
1018  ezxml_free(xml->child);
1019  ezxml_free(xml->ordered);
1020 
1021  if (!xml->parent) { /* free root tag allocations */
1022  for (i = 10; root->ent[i]; i += 2) /* 0 - 9 are default entites (<>&"') */
1023  if ((s = root->ent[i + 1]) < root->s || s > root->e)
1024  free(s);
1025  free(root->ent); /* free list of general entities */
1026 
1027  for (i = 0; root->attr[i]; i++) {
1028  /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */
1029  a = root->attr[i];
1030  for (j = 1; a[j++]; j += 2) /* free malloced attribute values */
1031  if (a[j] && (a[j] < root->s || a[j] > root->e))
1032  free(a[j]);
1033  free(a);
1034  }
1035  if (root->attr[0])
1036  free(root->attr); /* free default attribute list */
1037 
1038  for (i = 0; root->pi[i]; i++) {
1039  for (j = 1; root->pi[i][j]; j++)
1040  ;
1041  free(root->pi[i][j + 1]);
1042  free(root->pi[i]);
1043  }
1044  if (root->pi[0])
1045  free(root->pi); /* free processing instructions */
1046 
1047  if (root->len == (size_t)-1)
1048  free(root->m); /* malloced xml data */
1049 #ifndef EZXML_NOMMAP
1050  else if (root->len)
1051  munmap(root->m, root->len); /* mem mapped xml data */
1052 #endif /* EZXML_NOMMAP */
1053  if (root->u)
1054  free(root->u); /* utf8 conversion */
1055  }
1056 
1057  ezxml_free_attr(xml->attr); /* tag attributes */
1058  if ((xml->flags & EZXML_TXTM))
1059  free(xml->txt); /* character content */
1060  if ((xml->flags & EZXML_NAMEM))
1061  free(xml->name); /* tag name */
1062  free(xml);
1063 }
size_t len
Definition: ezxml.h:65
char * u
Definition: ezxml.h:66
struct ezxml_root * ezxml_root_t
Definition: ezxml.h:60
#define EZXML_TXTM
Definition: ezxml.h:39
char * txt
Definition: ezxml.h:47
static void ezxml_free_attr(char **attr)
Definition: ezxml.c:575
#define EZXML_NAMEM
Definition: ezxml.h:38
void ezxml_free(ezxml_t xml)
Definition: ezxml.c:1011
char *** attr
Definition: ezxml.h:70
char * e
Definition: ezxml.h:68
char ** ent
Definition: ezxml.h:69
ezxml_t ordered
Definition: ezxml.h:51
char * m
Definition: ezxml.h:64
ezxml_t parent
Definition: ezxml.h:53
char * name
Definition: ezxml.h:45
char * s
Definition: ezxml.h:67
char ** attr
Definition: ezxml.h:46
short flags
Definition: ezxml.h:54
char *** pi
Definition: ezxml.h:71
ezxml_t child
Definition: ezxml.h:52

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ezxml_t ezxml_get ( ezxml_t  xml,
  ... 
)

Definition at line 143 of file ezxml.c.

143  {
144  va_list ap;
145  ezxml_t r;
146 
147  va_start(ap, xml);
148  r = ezxml_vget(xml, ap);
149  va_end(ap);
150  return r;
151 }
static ezxml_t ezxml_vget(ezxml_t xml, va_list ap)
Definition: ezxml.c:125
Definition: ezxml.h:44

+ Here is the call graph for this function:

ezxml_t ezxml_idx ( ezxml_t  xml,
int  idx 
)

Definition at line 94 of file ezxml.c.

94  {
95  for (; xml && idx; idx--)
96  xml = xml->next;
97  return xml;
98 }
ezxml_t next
Definition: ezxml.h:49

+ Here is the caller graph for this function:

ezxml_t ezxml_insert ( ezxml_t  xml,
ezxml_t  dest,
size_t  off 
)

Definition at line 1089 of file ezxml.c.

1089  {
1090  ezxml_t cur, prev, head;
1091 
1092  xml->next = xml->sibling = xml->ordered = NULL;
1093  xml->off = off;
1094  xml->parent = dest;
1095 
1096  /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */
1097  head = dest->child;
1098  if (head) { /* already have sub tags */
1099  if (head->off <= off) { /* not first subtag */
1100  for (cur = head; cur->ordered && cur->ordered->off <= off;
1101  cur = cur->ordered)
1102  ;
1103  xml->ordered = cur->ordered;
1104  cur->ordered = xml;
1105  } else { /* first subtag */
1106  xml->ordered = head;
1107  dest->child = xml;
1108  }
1109 
1110  for (cur = head, prev = NULL; cur && strcmp(cur->name, xml->name);
1111  prev = cur, cur = cur->sibling)
1112  ; /* find tag type */
1113  if (cur && cur->off <= off) { /* not first of type */
1114  while (cur->next && cur->next->off <= off)
1115  cur = cur->next;
1116  xml->next = cur->next;
1117  cur->next = xml;
1118  } else { /* first tag of this type */
1119  if (prev && cur)
1120  prev->sibling = cur->sibling; /* remove old first */
1121  xml->next = cur; /* old first tag is now next */
1122  for (cur = head, prev = NULL; cur && cur->off <= off;
1123  prev = cur, cur = cur->sibling)
1124  ; /* new sibling insert point */
1125  xml->sibling = cur;
1126  if (prev)
1127  prev->sibling = xml;
1128  }
1129  } else
1130  dest->child = xml; /* only sub tag */
1131 
1132  return xml;
1133 }
Definition: ezxml.h:44
ezxml_t next
Definition: ezxml.h:49
ezxml_t sibling
Definition: ezxml.h:50
ezxml_t ordered
Definition: ezxml.h:51
ezxml_t parent
Definition: ezxml.h:53
char * name
Definition: ezxml.h:45
size_t off
Definition: ezxml.h:48
ezxml_t child
Definition: ezxml.h:52

+ Here is the caller graph for this function:

ezxml_t ezxml_new ( char *  name)

Definition at line 1074 of file ezxml.c.

1074  {
1075  static char *ent[] = { "lt;", "&#60;", "gt;", "&#62;", "quot;", "&#34;",
1076  "apos;", "&#39;", "amp;", "&#38;", NULL };
1077  ezxml_root_t root = (ezxml_root_t) memset(malloc(sizeof(struct ezxml_root)),
1078  '\0', sizeof(struct ezxml_root));
1079 
1080  root->xml.name = name;
1081  root->cur = &root->xml;
1082  strcpy(root->err, root->xml.txt = "");
1083  root->ent = (char**)memcpy(malloc(sizeof(ent)), ent, sizeof(ent));
1084  root->attr = root->pi = (char ***) (root->xml.attr = EZXML_NIL);
1085  return &root->xml;
1086 }
char err[EZXML_ERRL]
Definition: ezxml.h:73
struct ezxml_root * ezxml_root_t
Definition: ezxml.h:60
char * txt
Definition: ezxml.h:47
char * EZXML_NIL[]
Definition: ezxml.c:65
char *** attr
Definition: ezxml.h:70
ezxml_t cur
Definition: ezxml.h:63
char ** ent
Definition: ezxml.h:69
struct ezxml xml
Definition: ezxml.h:62
char * name
Definition: ezxml.h:45
char ** attr
Definition: ezxml.h:46
char *** pi
Definition: ezxml.h:71

+ Here is the caller graph for this function:

ezxml_t ezxml_parse_fd ( int  fd)

Definition at line 816 of file ezxml.c.

816  {
817  ezxml_root_t root;
818  struct stat st;
819  size_t l;
820  void *m;
821 
822  if (fd < 0)
823  return NULL;
824  fstat(fd, &st);
825 
826 #ifndef EZXML_NOMMAP
827  l = (st.st_size + sysconf(_SC_PAGESIZE) - 1) & ~(sysconf(_SC_PAGESIZE) - 1);
828  if ((m = mmap(NULL, l, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0))
829  != MAP_FAILED) {
830  madvise(m, l, MADV_SEQUENTIAL); /* optimize for sequential access */
831  root = (ezxml_root_t) ezxml_parse_str((char*)m, st.st_size);
832  madvise(m, root->len = l, MADV_NORMAL); /* put it back to normal */
833  } else { /* mmap failed, read file into memory */
834 #endif /* EZXML_NOMMAP */
835  l = read(fd, m = malloc(st.st_size), st.st_size);
836  root = (ezxml_root_t) ezxml_parse_str((char*)m, l);
837  /* Ted Campbell, Aug 14, 2007. Added explicit cast. */
838  root->len = (size_t) (-1); /* so we know to free s in ezxml_free() */
839 #ifndef EZXML_NOMMAP
840  }
841 #endif /* EZXML_NOMMAP */
842  return &root->xml;
843 }
size_t len
Definition: ezxml.h:65
struct ezxml_root * ezxml_root_t
Definition: ezxml.h:60
struct ezxml xml
Definition: ezxml.h:62
ezxml_t ezxml_parse_str(char *s, size_t len)
Definition: ezxml.c:596

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ezxml_t ezxml_parse_file ( const char *  file)

Definition at line 846 of file ezxml.c.

846  {
847  int fd = open(file, O_RDONLY, 0);
848  ezxml_t xml = ezxml_parse_fd(fd);
849 
850  if (fd >= 0)
851  close(fd);
852  return xml;
853 }
Definition: ezxml.h:44
ezxml_t ezxml_parse_fd(int fd)
Definition: ezxml.c:816

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ezxml_t ezxml_parse_fp ( FILE *  fp)

Definition at line 790 of file ezxml.c.

790  {
791  ezxml_root_t root;
792  size_t l, len = 0;
793  char *s;
794 
795  /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */
796  s = (char*)malloc(EZXML_BUFSIZE);
797  if (!s)
798  return NULL;
799  do {
800  len += (l = fread((s + len), 1, EZXML_BUFSIZE, fp));
801  if (l == EZXML_BUFSIZE)
802  s = (char*)realloc(s, len + EZXML_BUFSIZE);
803  } while (s && l == EZXML_BUFSIZE);
804 
805  if (!s)
806  return NULL;
807  root = (ezxml_root_t) ezxml_parse_str(s, len);
808  /* Ted Campbell, Aug 14, 2007. Added explicit cast. */
809  root->len = (size_t) (-1); /* so we know to free s in ezxml_free() */
810  return &root->xml;
811 }
size_t len
Definition: ezxml.h:65
struct ezxml_root * ezxml_root_t
Definition: ezxml.h:60
#define EZXML_BUFSIZE
Definition: ezxml.h:37
struct ezxml xml
Definition: ezxml.h:62
ezxml_t ezxml_parse_str(char *s, size_t len)
Definition: ezxml.c:596

+ Here is the call graph for this function:

ezxml_t ezxml_parse_str ( char *  s,
size_t  len 
)

Definition at line 596 of file ezxml.c.

596  {
597  ezxml_root_t root = (ezxml_root_t) ezxml_new(0);
598  char q, e, *d, *temp, **attr, **a = NULL; /* initialize a to avoid compile warning */
599  int l, i, j;
600  int line = 1;
601 
602  root->m = s;
603  if (!len)
604  return ezxml_err(root, NULL, "root tag missing");
605  root->u = ezxml_str2utf8(&s, &len); /* convert utf-16 to utf-8 */
606  root->e = (root->s = s) + len; /* record start and end of work area */
607 
608  e = s[len - 1]; /* save end char */
609  s[len - 1] = '\0'; /* turn end char into null terminator */
610 
611  while (*s && *s != '<')
612  s++; /* find first tag */
613  if (!*s)
614  return ezxml_err(root, s, "root tag missing");
615 
616  for (;;) {
617  attr = (char **) EZXML_NIL;
618  d = ++s;
619 
620  if (isalpha(*s) || *s == '_' || *s == ':' || *s < '\0') { /* new tag */
621  if (!root->cur)
622  return ezxml_err(root, d, "markup outside of root element");
623 
624  s += strcspn(s, EZXML_WS "/>");
625  while (isspace(*s)) {
626  if (*s == '\n')
627  line++;
628  *(s++) = '\0'; /* null terminate tag name */
629  }
630 
631  if (*s && *s != '/' && *s != '>') { /* find tag in default attr list */
632  /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */
633  a = root->attr[0];
634  for (i = 0; a && strcmp(a[0], d); i++) {
635  a = root->attr[i];
636  }
637  }
638 
639  for (l = 0; *s && *s != '/' && *s != '>'; l += 2) { /* new attrib */
640  attr = (l) ?
641  (char**)realloc(attr, (l + 4) * sizeof(char *)) :
642  (char**)malloc(4 * sizeof(char *)); /* allocate space */
643  attr[l + 3] =
644  (l) ? (char*)realloc(attr[l + 1], (l / 2) + 2) : (char*)malloc(2); /* mem for list of maloced vals */
645  strcpy(attr[l + 3] + (l / 2), " "); /* value is not malloced */
646  attr[l + 2] = NULL; /* null terminate list */
647  attr[l + 1] = ""; /* temporary attribute value */
648  attr[l] = s; /* set attribute name */
649 
650  s += strcspn(s, EZXML_WS "=/>");
651  if (*s == '=' || isspace(*s)) {
652  if (*s == '\n')
653  line++;
654  *(s++) = '\0'; /* null terminate tag attribute name */
655  q = *(s += strspn(s, EZXML_WS "="));
656  if (q == '"' || q == '\'') { /* attribute value */
657  attr[l + 1] = ++s;
658  while (*s && *s != q)
659  s++;
660  if (*s)
661  *(s++) = '\0'; /* null terminate attribute val */
662  else {
663  ezxml_free_attr(attr);
664  return ezxml_err(root, d, "missing %c", q);
665  }
666 
667  for (j = 1; a && a[j] && strcmp(a[j], attr[l]); j += 3)
668  ;
669  attr[l + 1] = ezxml_decode(attr[l + 1],
670  root->ent, (a && a[j]) ? *a[j + 2] : ' ');
671  if (attr[l + 1] < d || attr[l + 1] > s)
672  attr[l + 3][l / 2] = EZXML_TXTM; /* value malloced */
673  }
674  }
675  while (isspace(*s)) {
676  if (*s == '\n')
677  line++;
678  s++;
679  }
680  }
681 
682  if (*s == '/') { /* self closing tag */
683  *(s++) = '\0';
684  if ((*s && *s != '>') || (!*s && e != '>')) {
685  if (l)
686  ezxml_free_attr(attr);
687  return ezxml_err(root, d, "missing >");
688  }
689  ezxml_open_tag(root, line, d, attr);
690  ezxml_close_tag(root, d, s);
691  } else if ((q = *s) == '>' || (!*s && e == '>')) { /* open tag */
692  *s = '\0'; /* temporarily null terminate tag name */
693  ezxml_open_tag(root, line, d, attr);
694  *s = q;
695  } else {
696  if (l)
697  ezxml_free_attr(attr);
698  return ezxml_err(root, d, "missing >");
699  }
700  } else if (*s == '/') { /* close tag */
701  s += strcspn(d = s + 1, EZXML_WS ">") + 1;
702  /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */
703  q = *s;
704  if (!q && e != '>')
705  return ezxml_err(root, d, "missing >");
706  *s = '\0'; /* temporarily null terminate tag name */
707  if (ezxml_close_tag(root, d, s))
708  return &root->xml;
709  if (isspace(*s = q)) {
710  if (*s == '\n')
711  line++;
712  s += strspn(s, EZXML_WS);
713  }
714  } else if (!strncmp(s, "!--", 3)) { /* xml comment */
715  temp = s;
716  s = strstr(s + 3, "--");
717  if (!s || (*(s += 2) != '>' && *s) || (!*s && e != '>'))
718  return ezxml_err(root, d, "unclosed <!--");
719  while (temp != s && *temp != '\0') {
720  if (*temp == '\n') {
721  line++;
722  }
723  temp++;
724  }
725  } else if (!strncmp(s, "![CDATA[", 8)) { /* cdata */
726  /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */
727  s = strstr(s, "]]>");
728  if (s)
729  ezxml_char_content(root, d + 8, (s += 2) - d - 10, 'c');
730  else
731  return ezxml_err(root, d, "unclosed <![CDATA[");
732  } else if (!strncmp(s, "!DOCTYPE", 8)) { /* dtd */
733  for (l = 0;
734  *s
735  && ((!l && *s != '>')
736  || (l
737  && (*s != ']'
738  || *(s
739  + strspn(s + 1,
740  EZXML_WS)
741  + 1) != '>')));
742  l = (*s == '[') ? 1 : l)
743  s += strcspn(s + 1, "[]>") + 1;
744  if (!*s && e != '>')
745  return ezxml_err(root, d, "unclosed <!DOCTYPE");
746  d = (l) ? strchr(d, '[') + 1 : d;
747  if (l && !ezxml_internal_dtd(root, d, s++ - d))
748  return &root->xml;
749  } else if (*s == '?') { /* <?...?> processing instructions */
750  do {
751  s = strchr(s, '?');
752  } while (s && *(++s) && *s != '>');
753  if (!s || (!*s && e != '>'))
754  return ezxml_err(root, d, "unclosed <?");
755  else
756  ezxml_proc_inst(root, d + 1, s - d - 2);
757  } else
758  return ezxml_err(root, d, "unexpected <");
759 
760  if (!s || !*s)
761  break;
762  *s = '\0';
763  d = ++s;
764  if (*s && *s != '<') { /* tag character content */
765  while (*s && *s != '<') {
766  if (*s == '\n') {
767  line++;
768  }
769  s++;
770  }
771  if (*s)
772  ezxml_char_content(root, d, s - d, '&');
773  else
774  break;
775  } else if (!*s)
776  break;
777  }
778 
779  if (!root->cur)
780  return &root->xml;
781  else if (!root->cur->name)
782  return ezxml_err(root, d, "root tag missing");
783  else
784  return ezxml_err(root, d, "unclosed tag <%s>", root->cur->name);
785 }
char * u
Definition: ezxml.h:66
struct ezxml_root * ezxml_root_t
Definition: ezxml.h:60
#define EZXML_TXTM
Definition: ezxml.h:39
static void ezxml_char_content(ezxml_root_t root, char *s, size_t len, char t)
Definition: ezxml.c:290
static void ezxml_open_tag(ezxml_root_t root, int line, char *name, char **attr)
Definition: ezxml.c:275
static ezxml_t ezxml_close_tag(ezxml_root_t root, char *name, char *s)
Definition: ezxml.c:318
char * EZXML_NIL[]
Definition: ezxml.c:65
ezxml_t ezxml_new(char *name)
Definition: ezxml.c:1074
static void ezxml_free_attr(char **attr)
Definition: ezxml.c:575
char *** attr
Definition: ezxml.h:70
static char * ezxml_decode(char *s, char **ent, char t)
Definition: ezxml.c:195
ezxml_t cur
Definition: ezxml.h:63
char * e
Definition: ezxml.h:68
static char * ezxml_str2utf8(char **s, size_t *len)
Definition: ezxml.c:537
char ** ent
Definition: ezxml.h:69
#define EZXML_WS
Definition: ezxml.c:64
char * m
Definition: ezxml.h:64
struct ezxml xml
Definition: ezxml.h:62
char * name
Definition: ezxml.h:45
static short ezxml_internal_dtd(ezxml_root_t root, char *s, size_t len)
Definition: ezxml.c:389
char * s
Definition: ezxml.h:67
static void ezxml_proc_inst(ezxml_root_t root, char *s, size_t len)
Definition: ezxml.c:346
static ezxml_t ezxml_err(ezxml_root_t root, char *s, const char *err,...)
Definition: ezxml.c:170

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

char** ezxml_pi ( ezxml_t  xml,
const char *  target 
)

Definition at line 156 of file ezxml.c.

156  {
157  ezxml_root_t root = (ezxml_root_t) xml;
158  int i = 0;
159 
160  if (!root)
161  return EZXML_NIL;
162  while (root->xml.parent)
163  root = (ezxml_root_t) root->xml.parent; /* root tag */
164  while (root->pi[i] && strcmp(target, root->pi[i][0]))
165  i++; /* find target */
166  return ((root->pi[i]) ? root->pi[i] + 1 : EZXML_NIL);
167 }
struct ezxml_root * ezxml_root_t
Definition: ezxml.h:60
char * EZXML_NIL[]
Definition: ezxml.c:65
ezxml_t parent
Definition: ezxml.h:53
struct ezxml xml
Definition: ezxml.h:62
char *** pi
Definition: ezxml.h:71
ezxml_t ezxml_set_attr ( ezxml_t  xml,
char *  name,
char *  value 
)

Definition at line 1165 of file ezxml.c.

1165  {
1166  int l = 0, c;
1167 
1168  if (!xml)
1169  return NULL;
1170  while (xml->attr[l] && strcmp(xml->attr[l], name))
1171  l += 2;
1172  if (!xml->attr[l]) { /* not found, add as new attribute */
1173  if (!value)
1174  return xml; /* nothing to do */
1175  if (xml->attr == EZXML_NIL) { /* first attribute */
1176  xml->attr = (char**)malloc(4 * sizeof(char *));
1177  /* Ted Campbell, Aug 14, 2007. Changed to use 'my_strdup' */
1178  xml->attr[1] = my_strdup(""); /* empty list of malloced names/vals */
1179  } else
1180  xml->attr = (char**)realloc(xml->attr, (l + 4) * sizeof(char *));
1181 
1182  xml->attr[l] = name; /*set attribute name */
1183  xml->attr[l + 2] = NULL; /* null terminate attribute list */
1184  xml->attr[l + 3] = (char*)realloc(xml->attr[l + 1],
1185  (c = strlen(xml->attr[l + 1])) + 2);
1186  strcpy(xml->attr[l + 3] + c, " "); /* set name/value as not malloced */
1187  if (xml->flags & EZXML_DUP)
1188  xml->attr[l + 3][c] = (char) (unsigned char) EZXML_NAMEM;
1189  } else if (xml->flags & EZXML_DUP)
1190  free(name); /* name was strduped */
1191  for (c = l; xml->attr[c]; c += 2)
1192  ; /* find end of attribute list */
1193  if (xml->attr[c + 1][l / 2] & EZXML_TXTM)
1194  free(xml->attr[l + 1]); /*old val */
1195  if (xml->flags & EZXML_DUP)
1196  xml->attr[c + 1][l / 2] |= EZXML_TXTM;
1197  else
1198  xml->attr[c + 1][l / 2] &= ~EZXML_TXTM;
1199 
1200  if (value)
1201  xml->attr[l + 1] = value; /* set attribute value */
1202  else { /* remove attribute */
1203  if (xml->attr[c + 1][l / 2] & EZXML_NAMEM)
1204  free(xml->attr[l]);
1205  /* Ted Campbell, Aug 14, 2007. It seems that the size should be
1206  * (c + 2) - (l + 2) = (c - l) */
1207  memmove(xml->attr + l, xml->attr + l + 2, (c - l) * sizeof(char *));
1208  /* Ted Campbell, Aug 14, 2007. We need to adjust c to point to new
1209  * location it was moved to since its old location is undefined */
1210  c -= 2; /* We have one less elements */
1211  xml->attr = (char**)realloc(xml->attr, (c + 2) * sizeof(char *));
1212  memmove(xml->attr[c + 1] + (l / 2), xml->attr[c + 1] + (l / 2) + 1,
1213  (c / 2) - (l / 2)); /* fix list of which name/vals are malloced */
1214  }
1215  xml->flags &= ~EZXML_DUP; /* clear strdup() flag */
1216  return xml;
1217 }
#define EZXML_TXTM
Definition: ezxml.h:39
char * EZXML_NIL[]
Definition: ezxml.c:65
#define EZXML_NAMEM
Definition: ezxml.h:38
#define EZXML_DUP
Definition: ezxml.h:40
char ** attr
Definition: ezxml.h:46
short flags
Definition: ezxml.h:54
char * my_strdup(const char *str)
Definition: util.c:101

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ezxml_t ezxml_set_flag ( ezxml_t  xml,
short  flag 
)

Definition at line 1220 of file ezxml.c.

1220  {
1221  if (xml)
1222  xml->flags |= flag;
1223  return xml;
1224 }
short flags
Definition: ezxml.h:54

+ Here is the caller graph for this function:

ezxml_t ezxml_set_txt ( ezxml_t  xml,
char *  txt 
)

Definition at line 1152 of file ezxml.c.

1152  {
1153  if (!xml)
1154  return NULL;
1155  if (xml->flags & EZXML_TXTM)
1156  free(xml->txt); /* existing txt was malloced */
1157  xml->flags &= ~EZXML_TXTM;
1158  strcpy(xml->txt, txt);
1159  xml->txt = txt;
1160  return xml;
1161 }
#define EZXML_TXTM
Definition: ezxml.h:39
char * txt
Definition: ezxml.h:47
short flags
Definition: ezxml.h:54

+ Here is the caller graph for this function:

char* ezxml_toxml ( ezxml_t  xml)

Definition at line 963 of file ezxml.c.

963  {
964  ezxml_t p = (xml) ? xml->parent : NULL, o = (xml) ? xml->ordered : NULL;
965  ezxml_root_t root = (ezxml_root_t) xml;
966  size_t len = 0, max = EZXML_BUFSIZE;
967  char *s = strcpy((char*)malloc(max), ""), *t, *n;
968  int i, j, k;
969 
970  if (!xml || !xml->name)
971  return (char*)realloc(s, len + 1);
972  while (root->xml.parent)
973  root = (ezxml_root_t) root->xml.parent; /* root tag */
974 
975  for (i = 0; !p && root->pi[i]; i++) { /* pre-root processing instructions */
976  for (k = 2; root->pi[i][k - 1]; k++)
977  ;
978  for (j = 1; root->pi[i][j]; j++) {
979  /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */
980  n = root->pi[i][j];
981  if (root->pi[i][k][j - 1] == '>')
982  continue; /* not pre-root */
983  while (len + strlen(t = root->pi[i][0]) + strlen(n) + 7 > max)
984  s = (char*)realloc(s, max += EZXML_BUFSIZE);
985  len += sprintf(s + len, "<?%s%s%s?>\n", t, *n ? " " : "", n);
986  }
987  }
988 
989  xml->parent = xml->ordered = NULL;
990  s = ezxml_toxml_r(xml, &s, &len, &max, 0, root->attr);
991  xml->parent = p;
992  xml->ordered = o;
993 
994  for (i = 0; !p && root->pi[i]; i++) { /* post-root processing instructions */
995  for (k = 2; root->pi[i][k - 1]; k++)
996  ;
997  for (j = 1; root->pi[i][j]; j++) {
998  /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */
999  n = root->pi[i][j];
1000  if (root->pi[i][k][j - 1] == '<')
1001  continue; /* not post-root */
1002  while (len + strlen(t = root->pi[i][0]) + strlen(n) + 7 > max)
1003  s = (char*)realloc(s, max += EZXML_BUFSIZE);
1004  len += sprintf(s + len, "\n<?%s%s%s?>", t, *n ? " " : "", n);
1005  }
1006  }
1007  return (char*)realloc(s, len + 1);
1008 }
Definition: ezxml.h:44
struct ezxml_root * ezxml_root_t
Definition: ezxml.h:60
#define EZXML_BUFSIZE
Definition: ezxml.h:37
char *** attr
Definition: ezxml.h:70
#define max(a, b)
Definition: graphics.c:171
ezxml_t ordered
Definition: ezxml.h:51
ezxml_t parent
Definition: ezxml.h:53
struct ezxml xml
Definition: ezxml.h:62
char * name
Definition: ezxml.h:45
static char * ezxml_toxml_r(ezxml_t xml, char **s, size_t *len, size_t *max, size_t start, char ***attr)
Definition: ezxml.c:901
char *** pi
Definition: ezxml.h:71

+ Here is the call graph for this function: