SRC/ezxml.c File Reference

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include "ezxml.h"
#include "util.h"
Include dependency graph for ezxml.c:

Go to the source code of this file.

Data Structures

struct  ezxml_root

Defines

#define EZXML_WS   "\t\r\n "
#define EZXML_ERRL   128

Typedefs

typedef struct ezxml_rootezxml_root_t

Functions

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_vget (ezxml_t xml, va_list ap)
ezxml_t ezxml_get (ezxml_t xml,...)
const char ** ezxml_pi (ezxml_t xml, const char *target)
ezxml_t ezxml_err (ezxml_root_t root, char *s, const char *err,...)
char * ezxml_decode (char *s, char **ent, char t)
void ezxml_open_tag (ezxml_root_t root, char *name, char **attr)
void ezxml_char_content (ezxml_root_t root, char *s, size_t len, char t)
ezxml_t ezxml_close_tag (ezxml_root_t root, char *name, char *s)
int ezxml_ent_ok (char *name, char *s, char **ent)
void ezxml_proc_inst (ezxml_root_t root, char *s, size_t len)
short ezxml_internal_dtd (ezxml_root_t root, char *s, size_t len)
char * ezxml_str2utf8 (char **s, size_t *len)
void ezxml_free_attr (char **attr)
ezxml_t ezxml_parse_str (char *s, size_t len)
ezxml_t ezxml_parse_fp (FILE *fp)
ezxml_t ezxml_parse_fd (int fd)
ezxml_t ezxml_parse_file (const char *file)
char * ezxml_ampencode (const char *s, size_t len, char **dst, size_t *dlen, size_t *max, short a)
char * ezxml_toxml_r (ezxml_t xml, char **s, size_t *len, size_t *max, size_t start, char ***attr)
char * ezxml_toxml (ezxml_t xml)
void ezxml_free (ezxml_t xml)
const char * ezxml_error (ezxml_t xml)
ezxml_t ezxml_new (const char *name)
ezxml_t ezxml_insert (ezxml_t xml, ezxml_t dest, size_t off)
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)

Variables

char * EZXML_NIL [] = { NULL }

Define Documentation

#define EZXML_ERRL   128

Definition at line 65 of file ezxml.c.

#define EZXML_WS   "\t\r\n "

Definition at line 64 of file ezxml.c.


Typedef Documentation

typedef struct ezxml_root* ezxml_root_t

Definition at line 67 of file ezxml.c.


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:

char* ezxml_ampencode ( const char *  s,
size_t  len,
char **  dst,
size_t *  dlen,
size_t *  max,
short  a 
)

Definition at line 971 of file ezxml.c.

00977 {
00978     const char *e;
00979 
00980     for(e = s + len; s != e; s++)
00981         {
00982             while(*dlen + 10 > *max)
00983                 *dst = realloc(*dst, *max += EZXML_BUFSIZE);
00984 
00985             switch (*s)
00986                 {
00987                 case '\0':
00988                     return *dst;
00989                 case '&':
00990                     *dlen += sprintf(*dst + *dlen, "&amp;");
00991                     break;
00992                 case '<':
00993                     *dlen += sprintf(*dst + *dlen, "&lt;");
00994                     break;
00995                 case '>':
00996                     *dlen += sprintf(*dst + *dlen, "&gt;");
00997                     break;
00998                 case '"':
00999                     *dlen += sprintf(*dst + *dlen, (a) ? "&quot;" : "\"");
01000                     break;
01001                 case '\n':
01002                     *dlen += sprintf(*dst + *dlen, (a) ? "&#xA;" : "\n");
01003                     break;
01004                 case '\t':
01005                     *dlen += sprintf(*dst + *dlen, (a) ? "&#x9;" : "\t");
01006                     break;
01007                 case '\r':
01008                     *dlen += sprintf(*dst + *dlen, "&#xD;");
01009                     break;
01010                 default:
01011                     (*dst)[(*dlen)++] = *s;
01012                 }
01013         }
01014     return *dst;
01015 }

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:

void ezxml_char_content ( ezxml_root_t  root,
char *  s,
size_t  len,
char  t 
)

Definition at line 332 of file ezxml.c.

00336 {
00337     ezxml_t xml = root->cur;
00338     char *m = s;
00339     size_t l;
00340 
00341     if(!xml || !xml->name || !len)
00342         return;                 /* sanity check */
00343 
00344     s[len] = '\0';              /* null terminate text (calling functions anticipate this) */
00345     len = strlen(s = ezxml_decode(s, root->ent, t)) + 1;
00346 
00347     if(!*(xml->txt))
00348         xml->txt = s;           /* initial character content */
00349     else
00350         {                       /* allocate our own memory and make a copy */
00351             xml->txt = (xml->flags & EZXML_TXTM)        /* allocate some space */
00352                 ? realloc(xml->txt, (l = strlen(xml->txt)) + len)
00353                 : strcpy(malloc((l = strlen(xml->txt)) + len), xml->txt);
00354             strcpy(xml->txt + l, s);    /* add new char content */
00355             if(s != m)
00356                 free(s);        /* free s if it was malloced by ezxml_decode() */
00357         }
00358 
00359     if(xml->txt != m)
00360         ezxml_set_flag(xml, EZXML_TXTM);
00361 }

Here is the call graph for this function:

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_close_tag ( ezxml_root_t  root,
char *  name,
char *  s 
)

Definition at line 365 of file ezxml.c.

00368 {
00369     if(!root->cur || !root->cur->name || strcmp(name, root->cur->name))
00370         return ezxml_err(root, s, "unexpected closing tag </%s>", name);
00371 
00372     root->cur = root->cur->parent;
00373     return NULL;
00374 }

Here is the call graph for this function:

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 }

char* ezxml_decode ( char *  s,
char **  ent,
char  t 
)

Definition at line 217 of file ezxml.c.

00220 {
00221     char *e, *r = s, *m = s;
00222     long b, c, d, l;
00223 
00224     for(; *s; s++)
00225         {                       /* normalize line endings */
00226             while(*s == '\r')
00227                 {
00228                     *(s++) = '\n';
00229                     if(*s == '\n')
00230                         memmove(s, (s + 1), strlen(s));
00231                 }
00232         }
00233 
00234     for(s = r;;)
00235         {
00236             while(*s && *s != '&' && (*s != '%' || t != '%') && !isspace(*s))
00237                 s++;
00238 
00239             if(!*s)
00240                 break;
00241             else if(t != 'c' && !strncmp(s, "&#", 2))
00242                 {               /* character reference */
00243                     if(s[2] == 'x')
00244                         c = strtol(s + 3, &e, 16);      /* base 16 */
00245                     else
00246                         c = strtol(s + 2, &e, 10);      /* base 10 */
00247                     if(!c || *e != ';')
00248                         {
00249                             s++;
00250                             continue;
00251                         }
00252                     /* not a character ref */
00253                     if(c < 0x80)
00254                         *(s++) = c;     /* US-ASCII subset */
00255                     else
00256                         {       /* multi-byte UTF-8 sequence */
00257                             for(b = 0, d = c; d; d /= 2)
00258                                 b++;    /* number of bits in c */
00259                             b = (b - 2) / 5;    /* number of bytes in payload */
00260                             *(s++) = (0xFF << (7 - b)) | (c >> (6 * b));        /* head */
00261                             while(b)
00262                                 *(s++) = 0x80 | ((c >> (6 * --b)) & 0x3F);      /* payload */
00263                         }
00264 
00265                     memmove(s, strchr(s, ';') + 1, strlen(strchr(s, ';')));
00266                 }
00267             else if((*s == '&' && (t == '&' || t == ' ' || t == '*'))
00268                     || (*s == '%' && t == '%'))
00269                 {               /* entity reference */
00270                     for(b = 0; ent[b] && strncmp(s + 1, ent[b], strlen(ent[b])); b += 2);       /* find entity in entity list */
00271 
00272                     if(ent[b++])
00273                         {       /* found a match */
00274                             if((c = strlen(ent[b])) - 1 > (e =
00275                                                            strchr(s,
00276                                                                   ';')) - s)
00277                                 {
00278                                     l = (d = (s - r)) + c + strlen(e);  /* new length */
00279                                     r = (r == m) ? strcpy(malloc(l),
00280                                                           r) : realloc(r, l);
00281                                     e = strchr((s = r + d), ';');       /* fix up pointers */
00282                                 }
00283 
00284                             memmove(s + c, e + 1, strlen(e));   /* shift rest of string */
00285                             strncpy(s, ent[b], c);      /* copy in replacement text */
00286                         }
00287                     else
00288                         s++;    /* not a known entity */
00289                 }
00290             else if((t == ' ' || t == '*') && isspace(*s))
00291                 *(s++) = ' ';
00292             else
00293                 s++;            /* no decoding needed */
00294         }
00295 
00296     if(t == '*')
00297         {                       /* normalize spaces for non-cdata attributes */
00298             for(s = r; *s; s++)
00299                 {
00300                     /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */
00301                     l = strspn(s, " ");
00302                     if(l)
00303                         memmove(s, s + l, strlen(s + l) + 1);
00304                     while(*s && *s != ' ')
00305                         s++;
00306                 }
00307             if(--s >= r && *s == ' ')
00308                 *s = '\0';      /* trim any trailing space */
00309         }
00310     return r;
00311 }

Here is the caller graph for this function:

int ezxml_ent_ok ( char *  name,
char *  s,
char **  ent 
)

Definition at line 379 of file ezxml.c.

00382 {
00383     int i;
00384 
00385     for(;; s++)
00386         {
00387             while(*s && *s != '&')
00388                 s++;            /* find next entity reference */
00389             if(!*s)
00390                 return 1;
00391             if(!strncmp(s + 1, name, strlen(name)))
00392                 return 0;       /* circular ref. */
00393             for(i = 0; ent[i] && strncmp(ent[i], s + 1, strlen(ent[i]));
00394                 i += 2);
00395             if(ent[i] && !ezxml_ent_ok(name, ent[i + 1], ent))
00396                 return 0;
00397         }
00398 }

Here is the caller graph for this function:

ezxml_t ezxml_err ( ezxml_root_t  root,
char *  s,
const char *  err,
  ... 
)

Definition at line 189 of file ezxml.c.

00193 {
00194     va_list ap;
00195     int line = 1;
00196     char *t, fmt[EZXML_ERRL];
00197 
00198     for(t = root->s; t < s; t++)
00199         if(*t == '\n')
00200             line++;
00201     snprintf(fmt, EZXML_ERRL, "[error near line %d]: %s", line, err);
00202 
00203     va_start(ap, err);
00204     vsnprintf(root->err, EZXML_ERRL, fmt, ap);
00205     va_end(ap);
00206 
00207     return &root->xml;
00208 }

Here is the caller graph for this function:

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:

void ezxml_free_attr ( char **  attr  ) 

Definition at line 659 of file ezxml.c.

00660 {
00661     int i = 0;
00662     char *m;
00663 
00664     if(!attr || attr == EZXML_NIL)
00665         return;                 /* nothing to free */
00666     while(attr[i])
00667         i += 2;                 /* find end of attribute list */
00668     m = attr[i + 1];            /* list of which names and values are malloced */
00669     for(i = 0; m[i]; i++)
00670         {
00671             if(m[i] & EZXML_NAMEM)
00672                 free(attr[i * 2]);
00673             if(m[i] & EZXML_TXTM)
00674                 free(attr[(i * 2) + 1]);
00675         }
00676     free(m);
00677     free(attr);
00678 }

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:

short ezxml_internal_dtd ( ezxml_root_t  root,
char *  s,
size_t  len 
)

Definition at line 452 of file ezxml.c.

00455 {
00456     char q, *c, *t, *n = NULL, *v, **ent, **pe;
00457     int i, j;
00458 
00459     pe = memcpy(malloc(sizeof(EZXML_NIL)), EZXML_NIL, sizeof(EZXML_NIL));
00460 
00461     for(s[len] = '\0'; s;)
00462         {
00463             while(*s && *s != '<' && *s != '%')
00464                 s++;            /* find next declaration */
00465 
00466             if(!*s)
00467                 break;
00468             else if(!strncmp(s, "<!ENTITY", 8))
00469                 {               /* parse entity definitions */
00470                     c = s += strspn(s + 8, EZXML_WS) + 8;       /* skip white space separator */
00471                     n = s + strspn(s, EZXML_WS "%");    /* find name */
00472                     *(s = n + strcspn(n, EZXML_WS)) = ';';      /* append ; to name */
00473 
00474                     v = s + strspn(s + 1, EZXML_WS) + 1;        /* find value */
00475                     if((q = *(v++)) != '"' && q != '\'')
00476                         {       /* skip externals */
00477                             s = strchr(s, '>');
00478                             continue;
00479                         }
00480 
00481                     for(i = 0, ent = (*c == '%') ? pe : root->ent; ent[i];
00482                         i++);
00483                     ent = realloc(ent, (i + 3) * sizeof(char *));       /* space for next ent */
00484                     if(*c == '%')
00485                         pe = ent;
00486                     else
00487                         root->ent = ent;
00488 
00489                     *(++s) = '\0';      /* null terminate name */
00490                     /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */
00491                     s = strchr(v, q);
00492                     if(s)
00493                         *(s++) = '\0';  /* null terminate value */
00494                     ent[i + 1] = ezxml_decode(v, pe, '%');      /* set value */
00495                     ent[i + 2] = NULL;  /* null terminate entity list */
00496                     if(!ezxml_ent_ok(n, ent[i + 1], ent))
00497                         {       /* circular reference */
00498                             if(ent[i + 1] != v)
00499                                 free(ent[i + 1]);
00500                             ezxml_err(root, v,
00501                                       "circular entity declaration &%s", n);
00502                             break;
00503                         }
00504                     else
00505                         ent[i] = n;     /* set entity name */
00506                 }
00507             else if(!strncmp(s, "<!ATTLIST", 9))
00508                 {               /* parse default attributes */
00509                     t = s + strspn(s + 9, EZXML_WS) + 9;        /* skip whitespace separator */
00510                     if(!*t)
00511                         {
00512                             ezxml_err(root, t, "unclosed <!ATTLIST");
00513                             break;
00514                         }
00515                     if(*(s = t + strcspn(t, EZXML_WS ">")) == '>')
00516                         continue;
00517                     else
00518                         *s = '\0';      /* null terminate tag name */
00519                     for(i = 0; root->attr[i] && strcmp(n, root->attr[i][0]);
00520                         i++);
00521 
00522                     while(*(n = ++s + strspn(s, EZXML_WS)) && *n != '>')
00523                         {
00524                             if(*(s = n + strcspn(n, EZXML_WS)))
00525                                 *s = '\0';      /* attr name */
00526                             else
00527                                 {
00528                                     ezxml_err(root, t, "malformed <!ATTLIST");
00529                                     break;
00530                                 }
00531 
00532                             s += strspn(s + 1, EZXML_WS) + 1;   /* find next token */
00533                             c = (strncmp(s, "CDATA", 5)) ? "*" : " ";   /* is it cdata? */
00534                             if(!strncmp(s, "NOTATION", 8))
00535                                 s += strspn(s + 8, EZXML_WS) + 8;
00536                             s = (*s == '(') ? strchr(s, ')') : s + strcspn(s,
00537                                                                            EZXML_WS);
00538                             if(!s)
00539                                 {
00540                                     ezxml_err(root, t, "malformed <!ATTLIST");
00541                                     break;
00542                                 }
00543 
00544                             s += strspn(s, EZXML_WS ")");       /* skip white space separator */
00545                             if(!strncmp(s, "#FIXED", 6))
00546                                 s += strspn(s + 6, EZXML_WS) + 6;
00547                             if(*s == '#')
00548                                 {       /* no default value */
00549                                     s += strcspn(s, EZXML_WS ">") - 1;
00550                                     if(*c == ' ')
00551                                         continue;       /* cdata is default, nothing to do */
00552                                     v = NULL;
00553                                 }
00554                             else
00555                                 {
00556                                     /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */
00557                                     s = strchr(v = s + 1, *s);
00558                                     if((*s == '"' || *s == '\'') &&     /* default value */
00559                                        s)
00560                                         *s = '\0';
00561                                     else
00562                                         {
00563                                             ezxml_err(root, t,
00564                                                       "malformed <!ATTLIST");
00565                                             break;
00566                                         }
00567                                 }
00568 
00569                             if(!root->attr[i])
00570                                 {       /* new tag name */
00571                                     root->attr =
00572                                         (!i) ? malloc(2 *
00573                                                       sizeof(char **)) :
00574                                         realloc(root->attr,
00575                                                 (i + 2) * sizeof(char **));
00576                                     root->attr[i] =
00577                                         malloc(2 * sizeof(char *));
00578                                     root->attr[i][0] = t;       /* set tag name */
00579                                     root->attr[i][1] =
00580                                         (char *)(root->attr[i + 1] = NULL);
00581                                 }
00582 
00583                             for(j = 1; root->attr[i][j]; j += 3);       /* find end of list */
00584                             root->attr[i] = realloc(root->attr[i],
00585                                                     (j + 4) * sizeof(char *));
00586 
00587                             root->attr[i][j + 3] = NULL;        /* null terminate list */
00588                             root->attr[i][j + 2] = c;   /* is it cdata? */
00589                             root->attr[i][j + 1] =
00590                                 (v) ? ezxml_decode(v, root->ent, *c) : NULL;
00591                             root->attr[i][j] = n;       /* attribute name  */
00592                         }
00593                 }
00594             else if(!strncmp(s, "<!--", 4))
00595                 s = strstr(s + 4, "-->");       /* comments */
00596             else if(!strncmp(s, "<?", 2))
00597                 {               /* processing instructions */
00598                     /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */
00599                     s = strstr(c = s + 2, "?>");
00600                     if(s)
00601                         ezxml_proc_inst(root, c, s++ - c);
00602                 }
00603             else if(*s == '<')
00604                 s = strchr(s, '>');     /* skip other declarations */
00605             else if(*(s++) == '%' && !root->standalone)
00606                 break;
00607         }
00608 
00609     free(pe);
00610     return !*root->err;
00611 }

Here is the call graph for this function:

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:

void ezxml_open_tag ( ezxml_root_t  root,
char *  name,
char **  attr 
)

Definition at line 315 of file ezxml.c.

00318 {
00319     ezxml_t xml = root->cur;
00320 
00321     if(xml->name)
00322         xml = ezxml_add_child(xml, name, strlen(xml->txt));
00323     else
00324         xml->name = name;       /* first open tag */
00325 
00326     xml->attr = attr;
00327     root->cur = xml;            /* update tag insertion point */
00328 }

Here is the call graph for this function:

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 }

void ezxml_proc_inst ( ezxml_root_t  root,
char *  s,
size_t  len 
)

Definition at line 402 of file ezxml.c.

00405 {
00406     int i = 0, j = 1;
00407     char *target = s;
00408 
00409     s[len] = '\0';              /* null terminate instruction */
00410     if(*(s += strcspn(s, EZXML_WS)))
00411         {
00412             *s = '\0';          /* null terminate target */
00413             s += strspn(s + 1, EZXML_WS) + 1;   /* skip whitespace after target */
00414         }
00415 
00416     if(!strcmp(target, "xml"))
00417         {                       /* <?xml ... ?> */
00418             /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */
00419             s = strstr(s, "standalone");
00420             if(s && !strncmp(s + strspn(s + 10,
00421                                         EZXML_WS "='\"") + 10, "yes", 3))
00422                 root->standalone = 1;
00423             return;
00424         }
00425 
00426     if(!root->pi[0])
00427         *(root->pi = malloc(sizeof(char **))) = NULL;   /*first pi */
00428 
00429     while(root->pi[i] && strcmp(target, root->pi[i][0]))
00430         i++;                    /* find target */
00431     if(!root->pi[i])
00432         {                       /* new target */
00433             root->pi = realloc(root->pi, sizeof(char **) * (i + 2));
00434             root->pi[i] = malloc(sizeof(char *) * 3);
00435             root->pi[i][0] = target;
00436             root->pi[i][1] = (char *)(root->pi[i + 1] = NULL);  /* terminate pi list */
00437             /* Ted Campbell, Aug 14, 2007. Changed to use 'my_strdup' */
00438             root->pi[i][2] = my_strdup("");     /* empty document position list */
00439         }
00440 
00441     while(root->pi[i][j])
00442         j++;                    /* find end of instruction list for this target */
00443     root->pi[i] = realloc(root->pi[i], sizeof(char *) * (j + 3));
00444     root->pi[i][j + 2] = realloc(root->pi[i][j + 1], j + 1);
00445     strcpy(root->pi[i][j + 2] + j - 1, (root->xml.name) ? ">" : "<");
00446     root->pi[i][j + 1] = NULL;  /* null terminate pi list for this target */
00447     root->pi[i][j] = s;         /* set instruction */
00448 }

Here is the call graph for this function:

Here is the caller graph for this function:

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_str2utf8 ( char **  s,
size_t *  len 
)

Definition at line 616 of file ezxml.c.

00618 {
00619     char *u;
00620     size_t l = 0, sl, max = *len;
00621     long c, d;
00622     int b, be = (**s == '\xFE') ? 1 : (**s == '\xFF') ? 0 : -1;
00623 
00624     if(be == -1)
00625         return NULL;            /* not UTF-16 */
00626 
00627     u = malloc(max);
00628     for(sl = 2; sl < *len - 1; sl += 2)
00629         {
00630             c = (be) ? (((*s)[sl] & 0xFF) << 8) | ((*s)[sl + 1] & 0xFF) /*UTF-16BE */
00631                 : (((*s)[sl + 1] & 0xFF) << 8) | ((*s)[sl] & 0xFF);     /*UTF-16LE */
00632             if(c >= 0xD800 && c <= 0xDFFF && (sl += 2) < *len - 1)
00633                 {               /* high-half */
00634                     d = (be) ? (((*s)[sl] & 0xFF) << 8) | ((*s)[sl + 1] &
00635                                                            0xFF)
00636                         : (((*s)[sl + 1] & 0xFF) << 8) | ((*s)[sl] & 0xFF);
00637                     c = (((c & 0x3FF) << 10) | (d & 0x3FF)) + 0x10000;
00638                 }
00639 
00640             while(l + 6 > max)
00641                 u = realloc(u, max += EZXML_BUFSIZE);
00642             if(c < 0x80)
00643                 u[l++] = c;     /* US-ASCII subset */
00644             else
00645                 {               /* multi-byte UTF-8 sequence */
00646                     for(b = 0, d = c; d; d /= 2)
00647                         b++;    /* bits in c */
00648                     b = (b - 2) / 5;    /* bytes in payload */
00649                     u[l++] = (0xFF << (7 - b)) | (c >> (6 * b));        /* head */
00650                     while(b)
00651                         u[l++] = 0x80 | ((c >> (6 * --b)) & 0x3F);      /* payload */
00652                 }
00653         }
00654     return *s = realloc(u, *len = l);
00655 }

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:

char* ezxml_toxml_r ( ezxml_t  xml,
char **  s,
size_t *  len,
size_t *  max,
size_t  start,
char ***  attr 
)

Definition at line 1021 of file ezxml.c.

01027 {
01028     int i, j;
01029     char *txt = (xml->parent) ? xml->parent->txt : "";
01030     size_t off = 0;
01031 
01032     /* parent character content up to this tag */
01033     *s = ezxml_ampencode(txt + start, xml->off - start, s, len, max, 0);
01034 
01035     while(*len + strlen(xml->name) + 4 > *max)  /* reallocate s */
01036         *s = realloc(*s, *max += EZXML_BUFSIZE);
01037 
01038     *len += sprintf(*s + *len, "<%s", xml->name);       /* open tag */
01039     for(i = 0; xml->attr[i]; i += 2)
01040         {                       /* tag attributes */
01041             if(ezxml_attr(xml, xml->attr[i]) != xml->attr[i + 1])
01042                 continue;
01043             while(*len + strlen(xml->attr[i]) + 7 > *max)       /* reallocate s */
01044                 *s = realloc(*s, *max += EZXML_BUFSIZE);
01045 
01046             *len += sprintf(*s + *len, " %s=\"", xml->attr[i]);
01047             /* Ted Campbell, Aug 14, 2007. Added explicit cast to size_t. */
01048             ezxml_ampencode(xml->attr[i + 1], (size_t) (-1), s, len, max, 1);
01049             *len += sprintf(*s + *len, "\"");
01050         }
01051 
01052     for(i = 0; attr[i] && strcmp(attr[i][0], xml->name); i++);
01053     for(j = 1; attr[i] && attr[i][j]; j += 3)
01054         {                       /* default attributes */
01055             if(!attr[i][j + 1]
01056                || ezxml_attr(xml, attr[i][j]) != attr[i][j + 1])
01057                 continue;       /* skip duplicates and non-values */
01058             while(*len + strlen(attr[i][j]) + 7 > *max) /* reallocate s */
01059                 *s = realloc(*s, *max += EZXML_BUFSIZE);
01060 
01061             *len += sprintf(*s + *len, " %s=\"", attr[i][j]);
01062             /* Ted Campbell, Aug 14, 2007. Added explicit cast to size_t. */
01063             ezxml_ampencode(attr[i][j + 1], (size_t) (-1), s, len, max, 1);
01064             *len += sprintf(*s + *len, "\"");
01065         }
01066     *len += sprintf(*s + *len, ">");
01067 
01068     /* Ted Campbell, Aug 14, 2007. Added explicit cast to size_t. */
01069     *s = (xml->child) ? ezxml_toxml_r(xml->child, s, len, max, 0, attr) /*child */
01070         : ezxml_ampencode(xml->txt, (size_t) (-1), s, len, max, 0);     /*data */
01071 
01072     while(*len + strlen(xml->name) + 4 > *max)  /* reallocate s */
01073         *s = realloc(*s, *max += EZXML_BUFSIZE);
01074 
01075     *len += sprintf(*s + *len, "</%s>", xml->name);     /* close tag */
01076 
01077     while(txt[off] && off < xml->off)
01078         off++;                  /* make sure off is within bounds */
01079     /* Ted Campbell, Aug 14, 2007. Added explicit cast to size_t. */
01080     return (xml->ordered) ? ezxml_toxml_r(xml->ordered, s, len, max, off,
01081                                           attr) : ezxml_ampencode(txt +
01082                                                                   off,
01083                                                                   (size_t)
01084                                                                   (-1), s,
01085                                                                   len, max,
01086                                                                   0);
01087 }

Here is the call graph for this function:

Here is the caller graph for this function:

ezxml_t ezxml_vget ( ezxml_t  xml,
va_list  ap 
)

Definition at line 135 of file ezxml.c.

00137 {
00138     char *name = va_arg(ap, char *);
00139     int idx = -1;
00140 
00141     if(name && *name)
00142         {
00143             idx = va_arg(ap, int);
00144 
00145             xml = ezxml_child(xml, name);
00146         }
00147     return (idx < 0) ? xml : ezxml_vget(ezxml_idx(xml, idx), ap);
00148 }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

char* EZXML_NIL[] = { NULL }

Definition at line 84 of file ezxml.c.


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