#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <fcntl.h>
Go to the source code of this file.
Data Structures | |
struct | ezxml |
Defines | |
#define | EZXML_BUFSIZE 1024 |
#define | EZXML_NAMEM 0x80 |
#define | EZXML_TXTM 0x40 |
#define | EZXML_DUP 0x20 |
#define | ezxml_next(xml) ((xml) ? xml->next : NULL) |
#define | ezxml_name(xml) ((xml) ? xml->name : NULL) |
#define | ezxml_txt(xml) ((xml) ? xml->txt : "") |
#define | ezxml_new_d(name) ezxml_set_flag(ezxml_new(strdup(name)), EZXML_NAMEM) |
#define | ezxml_add_child_d(xml, name, off) ezxml_set_flag(ezxml_add_child(xml, strdup(name), off), EZXML_NAMEM) |
#define | ezxml_set_txt_d(xml, txt) ezxml_set_flag(ezxml_set_txt(xml, strdup(txt)), EZXML_TXTM) |
#define | ezxml_set_attr_d(xml, name, value) ezxml_set_attr(ezxml_set_flag(xml, EZXML_DUP), strdup(name), strdup(value)) |
#define | ezxml_move(xml, dest, off) ezxml_insert(ezxml_cut(xml), dest, off) |
#define | ezxml_remove(xml) ezxml_free(ezxml_cut(xml)) |
Typedefs | |
typedef struct ezxml * | ezxml_t |
Functions | |
ezxml_t | ezxml_parse_str (char *s, size_t len) |
ezxml_t | ezxml_parse_fd (int fd) |
ezxml_t | ezxml_parse_file (const char *file) |
ezxml_t | ezxml_parse_fp (FILE *fp) |
ezxml_t | ezxml_child (ezxml_t xml, const char *name) |
ezxml_t | ezxml_idx (ezxml_t xml, int idx) |
const char * | ezxml_attr (ezxml_t xml, const char *attr) |
ezxml_t | ezxml_get (ezxml_t xml,...) |
char * | ezxml_toxml (ezxml_t xml) |
const char ** | ezxml_pi (ezxml_t xml, const char *target) |
void | ezxml_free (ezxml_t xml) |
const char * | ezxml_error (ezxml_t xml) |
ezxml_t | ezxml_new (const char *name) |
ezxml_t | ezxml_add_child (ezxml_t xml, const char *name, size_t off) |
ezxml_t | ezxml_set_txt (ezxml_t xml, const char *txt) |
ezxml_t | ezxml_set_attr (ezxml_t xml, const char *name, const char *value) |
ezxml_t | ezxml_set_flag (ezxml_t xml, short flag) |
ezxml_t | ezxml_cut (ezxml_t xml) |
ezxml_t | ezxml_insert (ezxml_t xml, ezxml_t dest, size_t off) |
#define ezxml_add_child_d | ( | xml, | |||
name, | |||||
off | ) | ezxml_set_flag(ezxml_add_child(xml, strdup(name), off), EZXML_NAMEM) |
#define ezxml_move | ( | xml, | |||
dest, | |||||
off | ) | ezxml_insert(ezxml_cut(xml), dest, off) |
#define ezxml_new_d | ( | name | ) | ezxml_set_flag(ezxml_new(strdup(name)), EZXML_NAMEM) |
#define ezxml_set_attr_d | ( | xml, | |||
name, | |||||
value | ) | ezxml_set_attr(ezxml_set_flag(xml, EZXML_DUP), strdup(name), strdup(value)) |
#define ezxml_set_txt_d | ( | xml, | |||
txt | ) | ezxml_set_flag(ezxml_set_txt(xml, strdup(txt)), EZXML_TXTM) |
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 }
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 }
Definition at line 1401 of file ezxml.c.
01402 { 01403 ezxml_t cur; 01404 01405 if(!xml) 01406 return NULL; /* nothing to do */ 01407 if(xml->next) 01408 xml->next->sibling = xml->sibling; /* patch sibling list */ 01409 01410 if(xml->parent) 01411 { /* not root tag */ 01412 cur = xml->parent->child; /* find head of subtag list */ 01413 if(cur == xml) 01414 xml->parent->child = xml->ordered; /* first subtag */ 01415 else 01416 { /* not first subtag */ 01417 while(cur->ordered != xml) 01418 cur = cur->ordered; 01419 cur->ordered = cur->ordered->ordered; /* patch ordered list */ 01420 01421 cur = xml->parent->child; /* go back to head of subtag list */ 01422 if(strcmp(cur->name, xml->name)) 01423 { /* not in first sibling list */ 01424 while(strcmp(cur->sibling->name, xml->name)) 01425 cur = cur->sibling; 01426 if(cur->sibling == xml) 01427 { /* first of a sibling list */ 01428 cur->sibling = (xml->next) ? xml->next 01429 : cur->sibling->sibling; 01430 } 01431 else 01432 cur = cur->sibling; /* not first of a sibling list */ 01433 } 01434 01435 while(cur->next && cur->next != xml) 01436 cur = cur->next; 01437 if(cur->next) 01438 cur->next = cur->next->next; /* patch next list */ 01439 } 01440 } 01441 xml->ordered = xml->sibling = xml->next = NULL; 01442 return xml; 01443 }
const char* ezxml_error | ( | ezxml_t | xml | ) |
Definition at line 1210 of file ezxml.c.
01211 { 01212 while(xml && xml->parent) 01213 xml = xml->parent; /* find root tag */ 01214 return (xml) ? ((ezxml_root_t) xml)->err : ""; 01215 }
void ezxml_free | ( | ezxml_t | xml | ) |
Definition at line 1151 of file ezxml.c.
01152 { 01153 ezxml_root_t root = (ezxml_root_t) xml; 01154 int i, j; 01155 char **a, *s; 01156 01157 if(!xml) 01158 return; 01159 ezxml_free(xml->child); 01160 ezxml_free(xml->ordered); 01161 01162 if(!xml->parent) 01163 { /* free root tag allocations */ 01164 for(i = 10; root->ent[i]; i += 2) /* 0 - 9 are default entites (<>&"') */ 01165 if((s = root->ent[i + 1]) < root->s || s > root->e) 01166 free(s); 01167 free(root->ent); /* free list of general entities */ 01168 01169 for(i = 0; root->attr[i]; i++) 01170 { 01171 /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */ 01172 a = root->attr[i]; 01173 for(j = 1; a[j++]; j += 2) /* free malloced attribute values */ 01174 if(a[j] && (a[j] < root->s || a[j] > root->e)) 01175 free(a[j]); 01176 free(a); 01177 } 01178 if(root->attr[0]) 01179 free(root->attr); /* free default attribute list */ 01180 01181 for(i = 0; root->pi[i]; i++) 01182 { 01183 for(j = 1; root->pi[i][j]; j++); 01184 free(root->pi[i][j + 1]); 01185 free(root->pi[i]); 01186 } 01187 if(root->pi[0]) 01188 free(root->pi); /* free processing instructions */ 01189 01190 if(root->len == -1) 01191 free(root->m); /* malloced xml data */ 01192 #ifndef EZXML_NOMMAP 01193 else if(root->len) 01194 munmap(root->m, root->len); /* mem mapped xml data */ 01195 #endif /* EZXML_NOMMAP */ 01196 if(root->u) 01197 free(root->u); /* utf8 conversion */ 01198 } 01199 01200 ezxml_free_attr(xml->attr); /* tag attributes */ 01201 if((xml->flags & EZXML_TXTM)) 01202 free(xml->txt); /* character content */ 01203 if((xml->flags & EZXML_NAMEM)) 01204 free(xml->name); /* tag name */ 01205 free(xml); 01206 }
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 }
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 }
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 }
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_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 }