#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"
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_root * | ezxml_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 } |
typedef struct ezxml_root* ezxml_root_t |
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 }
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, "&"); 00991 break; 00992 case '<': 00993 *dlen += sprintf(*dst + *dlen, "<"); 00994 break; 00995 case '>': 00996 *dlen += sprintf(*dst + *dlen, ">"); 00997 break; 00998 case '"': 00999 *dlen += sprintf(*dst + *dlen, (a) ? """ : "\""); 01000 break; 01001 case '\n': 01002 *dlen += sprintf(*dst + *dlen, (a) ? "
" : "\n"); 01003 break; 01004 case '\t': 01005 *dlen += sprintf(*dst + *dlen, (a) ? "	" : "\t"); 01006 break; 01007 case '\r': 01008 *dlen += sprintf(*dst + *dlen, "
"); 01009 break; 01010 default: 01011 (*dst)[(*dlen)++] = *s; 01012 } 01013 } 01014 return *dst; 01015 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
ezxml_t ezxml_new | ( | const char * | name | ) |
Definition at line 1219 of file ezxml.c.
01220 { 01221 static char *ent[] = { "lt;", "<", "gt;", ">", "quot;", """, 01222 "apos;", "'", "amp;", "&", 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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }