SRC/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

Defines

#define EZXML_BUFSIZE   1024
#define EZXML_NAMEM   0x80
#define EZXML_TXTM   0x40
#define EZXML_DUP   0x20
#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

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)
const 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 (const char *name)
ezxml_t ezxml_add_child (ezxml_t xml, const char *name, size_t off)
ezxml_t ezxml_set_txt (ezxml_t xml, const char *txt)
ezxml_t ezxml_set_attr (ezxml_t xml, const char *name, const 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)

Define Documentation

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

Definition at line 139 of file ezxml.h.

#define EZXML_BUFSIZE   1024

Definition at line 38 of file ezxml.h.

#define EZXML_DUP   0x20

Definition at line 41 of file ezxml.h.

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

Definition at line 174 of file ezxml.h.

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

Definition at line 93 of file ezxml.h.

#define EZXML_NAMEM   0x80

Definition at line 39 of file ezxml.h.

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

Definition at line 130 of file ezxml.h.

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

Definition at line 85 of file ezxml.h.

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

Definition at line 177 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 157 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 147 of file ezxml.h.

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

Definition at line 96 of file ezxml.h.

#define EZXML_TXTM   0x40

Definition at line 40 of file ezxml.h.


Typedef Documentation

typedef struct ezxml* ezxml_t

Definition at line 43 of file ezxml.h.


Function Documentation

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

Definition at line 1293 of file ezxml.c.

01296 {
01297     ezxml_t child;
01298 
01299     if(!xml)
01300         return NULL;
01301     child = (ezxml_t) memset(malloc(sizeof(struct ezxml)), '\0',
01302                              sizeof(struct ezxml));
01303     child->name = (char *)name;
01304     child->attr = EZXML_NIL;
01305     child->txt = "";
01306 
01307     return ezxml_insert(child, xml, off);
01308 }

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 110 of file ezxml.c.

00112 {
00113     int i = 0, j = 1;
00114     ezxml_root_t root = (ezxml_root_t) xml;
00115 
00116     if(!xml || !xml->attr)
00117         return NULL;
00118     while(xml->attr[i] && strcmp(attr, xml->attr[i]))
00119         i += 2;
00120     if(xml->attr[i])
00121         return xml->attr[i + 1];        /* found attribute */
00122 
00123     while(root->xml.parent)
00124         root = (ezxml_root_t) root->xml.parent; /* root tag */
00125     for(i = 0; root->attr[i] && strcmp(xml->name, root->attr[i][0]); i++);
00126     if(!root->attr[i])
00127         return NULL;            /* no matching default attributes */
00128     while(root->attr[i][j] && strcmp(attr, root->attr[i][j]))
00129         j += 3;
00130     return (root->attr[i][j]) ? root->attr[i][j + 1] : NULL;    /* found default */
00131 }

Here is the caller graph for this function:

ezxml_t ezxml_child ( ezxml_t  xml,
const char *  name 
)

Definition at line 88 of file ezxml.c.

00090 {
00091     xml = (xml) ? xml->child : NULL;
00092     while(xml && strcmp(name, xml->name))
00093         xml = xml->sibling;
00094     return xml;
00095 }

Here is the caller graph for this function:

ezxml_t ezxml_cut ( ezxml_t  xml  ) 

Definition at line 1401 of file ezxml.c.

01402 {
01403     ezxml_t cur;
01404 
01405     if(!xml)
01406         return NULL;            /* nothing to do */
01407     if(xml->next)
01408         xml->next->sibling = xml->sibling;      /* patch sibling list */
01409 
01410     if(xml->parent)
01411         {                       /* not root tag */
01412             cur = xml->parent->child;   /* find head of subtag list */
01413             if(cur == xml)
01414                 xml->parent->child = xml->ordered;      /* first subtag */
01415             else
01416                 {               /* not first subtag */
01417                     while(cur->ordered != xml)
01418                         cur = cur->ordered;
01419                     cur->ordered = cur->ordered->ordered;       /* patch ordered list */
01420 
01421                     cur = xml->parent->child;   /* go back to head of subtag list */
01422                     if(strcmp(cur->name, xml->name))
01423                         {       /* not in first sibling list */
01424                             while(strcmp(cur->sibling->name, xml->name))
01425                                 cur = cur->sibling;
01426                             if(cur->sibling == xml)
01427                                 {       /* first of a sibling list */
01428                                     cur->sibling = (xml->next) ? xml->next
01429                                         : cur->sibling->sibling;
01430                                 }
01431                             else
01432                                 cur = cur->sibling;     /* not first of a sibling list */
01433                         }
01434 
01435                     while(cur->next && cur->next != xml)
01436                         cur = cur->next;
01437                     if(cur->next)
01438                         cur->next = cur->next->next;    /* patch next list */
01439                 }
01440         }
01441     xml->ordered = xml->sibling = xml->next = NULL;
01442     return xml;
01443 }

const char* ezxml_error ( ezxml_t  xml  ) 

Definition at line 1210 of file ezxml.c.

01211 {
01212     while(xml && xml->parent)
01213         xml = xml->parent;      /* find root tag */
01214     return (xml) ? ((ezxml_root_t) xml)->err : "";
01215 }

void ezxml_free ( ezxml_t  xml  ) 

Definition at line 1151 of file ezxml.c.

01152 {
01153     ezxml_root_t root = (ezxml_root_t) xml;
01154     int i, j;
01155     char **a, *s;
01156 
01157     if(!xml)
01158         return;
01159     ezxml_free(xml->child);
01160     ezxml_free(xml->ordered);
01161 
01162     if(!xml->parent)
01163         {                       /* free root tag allocations */
01164             for(i = 10; root->ent[i]; i += 2)   /* 0 - 9 are default entites (<>&"') */
01165                 if((s = root->ent[i + 1]) < root->s || s > root->e)
01166                     free(s);
01167             free(root->ent);    /* free list of general entities */
01168 
01169             for(i = 0; root->attr[i]; i++)
01170                 {
01171                     /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */
01172                     a = root->attr[i];
01173                     for(j = 1; a[j++]; j += 2)  /* free malloced attribute values */
01174                         if(a[j] && (a[j] < root->s || a[j] > root->e))
01175                             free(a[j]);
01176                     free(a);
01177                 }
01178             if(root->attr[0])
01179                 free(root->attr);       /* free default attribute list */
01180 
01181             for(i = 0; root->pi[i]; i++)
01182                 {
01183                     for(j = 1; root->pi[i][j]; j++);
01184                     free(root->pi[i][j + 1]);
01185                     free(root->pi[i]);
01186                 }
01187             if(root->pi[0])
01188                 free(root->pi); /* free processing instructions */
01189 
01190             if(root->len == -1)
01191                 free(root->m);  /* malloced xml data */
01192 #ifndef EZXML_NOMMAP
01193             else if(root->len)
01194                 munmap(root->m, root->len);     /* mem mapped xml data */
01195 #endif /* EZXML_NOMMAP */
01196             if(root->u)
01197                 free(root->u);  /* utf8 conversion */
01198         }
01199 
01200     ezxml_free_attr(xml->attr); /* tag attributes */
01201     if((xml->flags & EZXML_TXTM))
01202         free(xml->txt);         /* character content */
01203     if((xml->flags & EZXML_NAMEM))
01204         free(xml->name);        /* tag name */
01205     free(xml);
01206 }

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 157 of file ezxml.c.

00159 {
00160     va_list ap;
00161     ezxml_t r;
00162 
00163     va_start(ap, xml);
00164     r = ezxml_vget(xml, ap);
00165     va_end(ap);
00166     return r;
00167 }

Here is the call graph for this function:

ezxml_t ezxml_idx ( ezxml_t  xml,
int  idx 
)

Definition at line 100 of file ezxml.c.

00102 {
00103     for(; xml && idx; idx--)
00104         xml = xml->next;
00105     return xml;
00106 }

Here is the caller graph for this function:

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

Definition at line 1238 of file ezxml.c.

01241 {
01242     ezxml_t cur, prev, head;
01243 
01244     xml->next = xml->sibling = xml->ordered = NULL;
01245     xml->off = off;
01246     xml->parent = dest;
01247 
01248     /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */
01249     head = dest->child;
01250     if(head)
01251         {                       /* already have sub tags */
01252             if(head->off <= off)
01253                 {               /* not first subtag */
01254                     for(cur = head; cur->ordered && cur->ordered->off <= off;
01255                         cur = cur->ordered);
01256                     xml->ordered = cur->ordered;
01257                     cur->ordered = xml;
01258                 }
01259             else
01260                 {               /* first subtag */
01261                     xml->ordered = head;
01262                     dest->child = xml;
01263                 }
01264 
01265             for(cur = head, prev = NULL; cur && strcmp(cur->name, xml->name); prev = cur, cur = cur->sibling);  /* find tag type */
01266             if(cur && cur->off <= off)
01267                 {               /* not first of type */
01268                     while(cur->next && cur->next->off <= off)
01269                         cur = cur->next;
01270                     xml->next = cur->next;
01271                     cur->next = xml;
01272                 }
01273             else
01274                 {               /* first tag of this type */
01275                     if(prev && cur)
01276                         prev->sibling = cur->sibling;   /* remove old first */
01277                     xml->next = cur;    /* old first tag is now next */
01278                     for(cur = head, prev = NULL; cur && cur->off <= off; prev = cur, cur = cur->sibling);       /* new sibling insert point */
01279                     xml->sibling = cur;
01280                     if(prev)
01281                         prev->sibling = xml;
01282                 }
01283         }
01284     else
01285         dest->child = xml;      /* only sub tag */
01286 
01287     return xml;
01288 }

Here is the caller graph for this function:

ezxml_t ezxml_new ( const char *  name  ) 

Definition at line 1219 of file ezxml.c.

01220 {
01221     static char *ent[] = { "lt;", "&#60;", "gt;", "&#62;", "quot;", "&#34;",
01222         "apos;", "&#39;", "amp;", "&#38;", NULL
01223     };
01224     ezxml_root_t root =
01225         (ezxml_root_t) memset(malloc(sizeof(struct ezxml_root)),
01226                               '\0', sizeof(struct ezxml_root));
01227 
01228     root->xml.name = (char *)name;
01229     root->cur = &root->xml;
01230     strcpy(root->err, root->xml.txt = "");
01231     root->ent = memcpy(malloc(sizeof(ent)), ent, sizeof(ent));
01232     root->attr = root->pi = (char ***)(root->xml.attr = EZXML_NIL);
01233     return &root->xml;
01234 }

Here is the caller graph for this function:

ezxml_t ezxml_parse_fd ( int  fd  ) 

Definition at line 921 of file ezxml.c.

00922 {
00923     ezxml_root_t root;
00924     struct stat st;
00925     size_t l;
00926     void *m;
00927 
00928     if(fd < 0)
00929         return NULL;
00930     fstat(fd, &st);
00931 
00932 #ifndef EZXML_NOMMAP
00933     l = (st.st_size + sysconf(_SC_PAGESIZE) -
00934          1) & ~(sysconf(_SC_PAGESIZE) - 1);
00935     if((m =
00936         mmap(NULL, l, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd,
00937              0)) != MAP_FAILED)
00938         {
00939             madvise(m, l, MADV_SEQUENTIAL);     /* optimize for sequential access */
00940             root = (ezxml_root_t) ezxml_parse_str(m, st.st_size);
00941             madvise(m, root->len = l, MADV_NORMAL);     /* put it back to normal */
00942         }
00943     else
00944         {                       /* mmap failed, read file into memory */
00945 #endif /* EZXML_NOMMAP */
00946             l = read(fd, m = malloc(st.st_size), st.st_size);
00947             root = (ezxml_root_t) ezxml_parse_str(m, l);
00948             /* Ted Campbell, Aug 14, 2007. Added explicit cast. */
00949             root->len = (size_t) (-1);  /* so we know to free s in ezxml_free() */
00950 #ifndef EZXML_NOMMAP
00951         }
00952 #endif /* EZXML_NOMMAP */
00953     return &root->xml;
00954 }

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 958 of file ezxml.c.

00959 {
00960     int fd = open(file, O_RDONLY, 0);
00961     ezxml_t xml = ezxml_parse_fd(fd);
00962 
00963     if(fd >= 0)
00964         close(fd);
00965     return xml;
00966 }

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 891 of file ezxml.c.

00892 {
00893     ezxml_root_t root;
00894     size_t l, len = 0;
00895     char *s;
00896 
00897     /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */
00898     s = malloc(EZXML_BUFSIZE);
00899     if(!s)
00900         return NULL;
00901     do
00902         {
00903             len += (l = fread((s + len), 1, EZXML_BUFSIZE, fp));
00904             if(l == EZXML_BUFSIZE)
00905                 s = realloc(s, len + EZXML_BUFSIZE);
00906         }
00907     while(s && l == EZXML_BUFSIZE);
00908 
00909     if(!s)
00910         return NULL;
00911     root = (ezxml_root_t) ezxml_parse_str(s, len);
00912     /* Ted Campbell, Aug 14, 2007. Added explicit cast. */
00913     root->len = (size_t) (-1);  /* so we know to free s in ezxml_free() */
00914     return &root->xml;
00915 }

Here is the call graph for this function:

ezxml_t ezxml_parse_str ( char *  s,
size_t  len 
)

Definition at line 682 of file ezxml.c.

00684 {
00685     ezxml_root_t root = (ezxml_root_t) ezxml_new(NULL);
00686     char q, e, *d, **attr, **a = NULL;  /* initialize a to avoid compile warning */
00687     int l, i, j;
00688 
00689     root->m = s;
00690     if(!len)
00691         return ezxml_err(root, NULL, "root tag missing");
00692     root->u = ezxml_str2utf8(&s, &len); /* convert utf-16 to utf-8 */
00693     root->e = (root->s = s) + len;      /* record start and end of work area */
00694 
00695     e = s[len - 1];             /* save end char */
00696     s[len - 1] = '\0';          /* turn end char into null terminator */
00697 
00698     while(*s && *s != '<')
00699         s++;                    /* find first tag */
00700     if(!*s)
00701         return ezxml_err(root, s, "root tag missing");
00702 
00703     for(;;)
00704         {
00705             attr = (char **)EZXML_NIL;
00706             d = ++s;
00707 
00708             if(isalpha(*s) || *s == '_' || *s == ':' || *s < '\0')
00709                 {               /* new tag */
00710                     if(!root->cur)
00711                         return ezxml_err(root, d,
00712                                          "markup outside of root element");
00713 
00714                     s += strcspn(s, EZXML_WS "/>");
00715                     while(isspace(*s))
00716                         *(s++) = '\0';  /* null terminate tag name */
00717 
00718                     if(*s && *s != '/' && *s != '>')
00719                         {       /* find tag in default attr list */
00720                             /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */
00721                             a = root->attr[0];
00722                             for(i = 0; a && strcmp(a[0], d); i++)
00723                                 {
00724                                     a = root->attr[i];
00725                                 }
00726                         }
00727 
00728                     for(l = 0; *s && *s != '/' && *s != '>'; l += 2)
00729                         {       /* new attrib */
00730                             attr = (l) ? realloc(attr, (l + 4) * sizeof(char *)) : malloc(4 * sizeof(char *));  /* allocate space */
00731                             attr[l + 3] = (l) ? realloc(attr[l + 1], (l / 2) + 2) : malloc(2);  /* mem for list of maloced vals */
00732                             strcpy(attr[l + 3] + (l / 2), " "); /* value is not malloced */
00733                             attr[l + 2] = NULL; /* null terminate list */
00734                             attr[l + 1] = "";   /* temporary attribute value */
00735                             attr[l] = s;        /* set attribute name */
00736 
00737                             s += strcspn(s, EZXML_WS "=/>");
00738                             if(*s == '=' || isspace(*s))
00739                                 {
00740                                     *(s++) = '\0';      /* null terminate tag attribute name */
00741                                     q = *(s += strspn(s, EZXML_WS "="));
00742                                     if(q == '"' || q == '\'')
00743                                         {       /* attribute value */
00744                                             attr[l + 1] = ++s;
00745                                             while(*s && *s != q)
00746                                                 s++;
00747                                             if(*s)
00748                                                 *(s++) = '\0';  /* null terminate attribute val */
00749                                             else
00750                                                 {
00751                                                     ezxml_free_attr(attr);
00752                                                     return ezxml_err(root, d,
00753                                                                      "missing %c",
00754                                                                      q);
00755                                                 }
00756 
00757                                             for(j = 1; a && a[j]
00758                                                 && strcmp(a[j], attr[l]);
00759                                                 j += 3);
00760                                             attr[l + 1] =
00761                                                 ezxml_decode(attr[l + 1],
00762                                                              root->ent, (a
00763                                                                          &&
00764                                                                          a[j])
00765                                                              ? *a[j +
00766                                                                   2] : ' ');
00767                                             if(attr[l + 1] < d
00768                                                || attr[l + 1] > s)
00769                                                 attr[l + 3][l / 2] = EZXML_TXTM;        /* value malloced */
00770                                         }
00771                                 }
00772                             while(isspace(*s))
00773                                 s++;
00774                         }
00775 
00776                     if(*s == '/')
00777                         {       /* self closing tag */
00778                             *(s++) = '\0';
00779                             if((*s && *s != '>') || (!*s && e != '>'))
00780                                 {
00781                                     if(l)
00782                                         ezxml_free_attr(attr);
00783                                     return ezxml_err(root, d, "missing >");
00784                                 }
00785                             ezxml_open_tag(root, d, attr);
00786                             ezxml_close_tag(root, d, s);
00787                         }
00788                     else if((q = *s) == '>' || (!*s && e == '>'))
00789                         {       /* open tag */
00790                             *s = '\0';  /* temporarily null terminate tag name */
00791                             ezxml_open_tag(root, d, attr);
00792                             *s = q;
00793                         }
00794                     else
00795                         {
00796                             if(l)
00797                                 ezxml_free_attr(attr);
00798                             return ezxml_err(root, d, "missing >");
00799                         }
00800                 }
00801             else if(*s == '/')
00802                 {               /* close tag */
00803                     s += strcspn(d = s + 1, EZXML_WS ">") + 1;
00804                     /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */
00805                     q = *s;
00806                     if(!q && e != '>')
00807                         return ezxml_err(root, d, "missing >");
00808                     *s = '\0';  /* temporarily null terminate tag name */
00809                     if(ezxml_close_tag(root, d, s))
00810                         return &root->xml;
00811                     if(isspace(*s = q))
00812                         s += strspn(s, EZXML_WS);
00813                 }
00814             else if(!strncmp(s, "!--", 3))
00815                 {               /* xml comment */
00816                     s = strstr(s + 3, "--");
00817                     if(!s || (*(s += 2) != '>' && *s) || (!*s && e != '>'))
00818                         return ezxml_err(root, d, "unclosed <!--");
00819                 }
00820             else if(!strncmp(s, "![CDATA[", 8))
00821                 {               /* cdata */
00822                     /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */
00823                     s = strstr(s, "]]>");
00824                     if(s)
00825                         ezxml_char_content(root, d + 8, (s += 2) - d - 10,
00826                                            'c');
00827                     else
00828                         return ezxml_err(root, d, "unclosed <![CDATA[");
00829                 }
00830             else if(!strncmp(s, "!DOCTYPE", 8))
00831                 {               /* dtd */
00832                     for(l = 0; *s && ((!l && *s != '>') || (l && (*s != ']' ||
00833                                                                   *(s +
00834                                                                     strspn(s +
00835                                                                            1,
00836                                                                            EZXML_WS)
00837                                                                     + 1) !=
00838                                                                   '>')));
00839                         l = (*s == '[') ? 1 : l)
00840                         s += strcspn(s + 1, "[]>") + 1;
00841                     if(!*s && e != '>')
00842                         return ezxml_err(root, d, "unclosed <!DOCTYPE");
00843                     d = (l) ? strchr(d, '[') + 1 : d;
00844                     if(l && !ezxml_internal_dtd(root, d, s++ - d))
00845                         return &root->xml;
00846                 }
00847             else if(*s == '?')
00848                 {               /* <?...?> processing instructions */
00849                     do
00850                         {
00851                             s = strchr(s, '?');
00852                         }
00853                     while(s && *(++s) && *s != '>');
00854                     if(!s || (!*s && e != '>'))
00855                         return ezxml_err(root, d, "unclosed <?");
00856                     else
00857                         ezxml_proc_inst(root, d + 1, s - d - 2);
00858                 }
00859             else
00860                 return ezxml_err(root, d, "unexpected <");
00861 
00862             if(!s || !*s)
00863                 break;
00864             *s = '\0';
00865             d = ++s;
00866             if(*s && *s != '<')
00867                 {               /* tag character content */
00868                     while(*s && *s != '<')
00869                         s++;
00870                     if(*s)
00871                         ezxml_char_content(root, d, s - d, '&');
00872                     else
00873                         break;
00874                 }
00875             else if(!*s)
00876                 break;
00877         }
00878 
00879     if(!root->cur)
00880         return &root->xml;
00881     else if(!root->cur->name)
00882         return ezxml_err(root, d, "root tag missing");
00883     else
00884         return ezxml_err(root, d, "unclosed tag <%s>", root->cur->name);
00885 }

Here is the call graph for this function:

Here is the caller graph for this function:

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

Definition at line 172 of file ezxml.c.

00174 {
00175     ezxml_root_t root = (ezxml_root_t) xml;
00176     int i = 0;
00177 
00178     if(!root)
00179         return (const char **)EZXML_NIL;
00180     while(root->xml.parent)
00181         root = (ezxml_root_t) root->xml.parent; /* root tag */
00182     while(root->pi[i] && strcmp(target, root->pi[i][0]))
00183         i++;                    /* find target */
00184     return (const char **)((root->pi[i]) ? root->pi[i] + 1 : EZXML_NIL);
00185 }

ezxml_t ezxml_set_attr ( ezxml_t  xml,
const char *  name,
const char *  value 
)

Definition at line 1327 of file ezxml.c.

01330 {
01331     int l = 0, c;
01332 
01333     if(!xml)
01334         return NULL;
01335     while(xml->attr[l] && strcmp(xml->attr[l], name))
01336         l += 2;
01337     if(!xml->attr[l])
01338         {                       /* not found, add as new attribute */
01339             if(!value)
01340                 return xml;     /* nothing to do */
01341             if(xml->attr == EZXML_NIL)
01342                 {               /* first attribute */
01343                     xml->attr = malloc(4 * sizeof(char *));
01344                     /* Ted Campbell, Aug 14, 2007. Changed to use 'my_strdup' */
01345                     xml->attr[1] = my_strdup("");       /* empty list of malloced names/vals */
01346                 }
01347             else
01348                 xml->attr = realloc(xml->attr, (l + 4) * sizeof(char *));
01349 
01350             xml->attr[l] = (char *)name;        /* set attribute name */
01351             xml->attr[l + 2] = NULL;    /* null terminate attribute list */
01352             xml->attr[l + 3] = realloc(xml->attr[l + 1],
01353                                        (c = strlen(xml->attr[l + 1])) + 2);
01354             strcpy(xml->attr[l + 3] + c, " ");  /* set name/value as not malloced */
01355             if(xml->flags & EZXML_DUP)
01356                 xml->attr[l + 3][c] = (char)(unsigned char)EZXML_NAMEM;
01357         }
01358     else if(xml->flags & EZXML_DUP)
01359         free((char *)name);     /* name was strduped */
01360 
01361     for(c = l; xml->attr[c]; c += 2);   /* find end of attribute list */
01362     if(xml->attr[c + 1][l / 2] & EZXML_TXTM)
01363         free(xml->attr[l + 1]); /*old val */
01364     if(xml->flags & EZXML_DUP)
01365         xml->attr[c + 1][l / 2] |= EZXML_TXTM;
01366     else
01367         xml->attr[c + 1][l / 2] &= ~EZXML_TXTM;
01368 
01369     if(value)
01370         xml->attr[l + 1] = (char *)value;       /* set attribute value */
01371     else
01372         {                       /* remove attribute */
01373             if(xml->attr[c + 1][l / 2] & EZXML_NAMEM)
01374                 free(xml->attr[l]);
01375             /* Ted Campbell, Aug 14, 2007. It seems that the size should be 
01376              * (c + 2) - (l + 2) = (c - l) */
01377             memmove(xml->attr + l, xml->attr + l + 2,
01378                     (c - l) * sizeof(char *));
01379             /* Ted Campbell, Aug 14, 2007. We need to adjust c to point to new
01380              * location it was moved to since its old location is undefined */
01381             c -= 2;             /* We have one less elements */
01382             xml->attr = realloc(xml->attr, (c + 2) * sizeof(char *));
01383             memmove(xml->attr[c + 1] + (l / 2), xml->attr[c + 1] + (l / 2) + 1, (c / 2) - (l / 2));     /* fix list of which name/vals are malloced */
01384         }
01385     xml->flags &= ~EZXML_DUP;   /* clear strdup() flag */
01386     return xml;
01387 }

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 1391 of file ezxml.c.

01393 {
01394     if(xml)
01395         xml->flags |= flag;
01396     return xml;
01397 }

Here is the caller graph for this function:

ezxml_t ezxml_set_txt ( ezxml_t  xml,
const char *  txt 
)

Definition at line 1312 of file ezxml.c.

01314 {
01315     if(!xml)
01316         return NULL;
01317     if(xml->flags & EZXML_TXTM)
01318         free(xml->txt);         /* existing txt was malloced */
01319     xml->flags &= ~EZXML_TXTM;
01320     xml->txt = (char *)txt;
01321     return xml;
01322 }

Here is the caller graph for this function:

char* ezxml_toxml ( ezxml_t  xml  ) 

Definition at line 1092 of file ezxml.c.

01093 {
01094     ezxml_t p = (xml) ? xml->parent : NULL,
01095       o = (xml) ? xml->ordered : NULL;
01096     ezxml_root_t root = (ezxml_root_t) xml;
01097     size_t len = 0, max = EZXML_BUFSIZE;
01098     char *s = strcpy(malloc(max), ""),
01099      *t,
01100      *n;
01101     int i, j, k;
01102 
01103     if(!xml || !xml->name)
01104         return realloc(s, len + 1);
01105     while(root->xml.parent)
01106         root = (ezxml_root_t) root->xml.parent; /* root tag */
01107 
01108     for(i = 0; !p && root->pi[i]; i++)
01109         {                       /* pre-root processing instructions */
01110             for(k = 2; root->pi[i][k - 1]; k++);
01111             for(j = 1; root->pi[i][j]; j++)
01112                 {
01113                     /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */
01114                     n = root->pi[i][j];
01115                     if(root->pi[i][k][j - 1] == '>')
01116                         continue;       /* not pre-root */
01117                     while(len + strlen(t = root->pi[i][0]) + strlen(n) + 7 >
01118                           max)
01119                         s = realloc(s, max += EZXML_BUFSIZE);
01120                     len +=
01121                         sprintf(s + len, "<?%s%s%s?>\n", t, *n ? " " : "", n);
01122                 }
01123         }
01124 
01125     xml->parent = xml->ordered = NULL;
01126     s = ezxml_toxml_r(xml, &s, &len, &max, 0, root->attr);
01127     xml->parent = p;
01128     xml->ordered = o;
01129 
01130     for(i = 0; !p && root->pi[i]; i++)
01131         {                       /* post-root processing instructions */
01132             for(k = 2; root->pi[i][k - 1]; k++);
01133             for(j = 1; root->pi[i][j]; j++)
01134                 {
01135                     /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */
01136                     n = root->pi[i][j];
01137                     if(root->pi[i][k][j - 1] == '<')
01138                         continue;       /* not post-root */
01139                     while(len + strlen(t = root->pi[i][0]) + strlen(n) + 7 >
01140                           max)
01141                         s = realloc(s, max += EZXML_BUFSIZE);
01142                     len +=
01143                         sprintf(s + len, "\n<?%s%s%s?>", t, *n ? " " : "", n);
01144                 }
01145         }
01146     return realloc(s, len + 1);
01147 }

Here is the call graph for this function:


Generated on Tue Jan 5 15:25:29 2010 for VPR5.0 by  doxygen 1.6.1