⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ezxml.c

📁 VPR布局布线源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    for(e = s + len; s != e; s++)	{	    while(*dlen + 10 > *max)		*dst = realloc(*dst, *max += EZXML_BUFSIZE);	    switch (*s)		{		case '\0':		    return *dst;		case '&':		    *dlen += sprintf(*dst + *dlen, "&amp;");		    break;		case '<':		    *dlen += sprintf(*dst + *dlen, "&lt;");		    break;		case '>':		    *dlen += sprintf(*dst + *dlen, "&gt;");		    break;		case '"':		    *dlen += sprintf(*dst + *dlen, (a) ? "&quot;" : "\"");		    break;		case '\n':		    *dlen += sprintf(*dst + *dlen, (a) ? "&#xA;" : "\n");		    break;		case '\t':		    *dlen += sprintf(*dst + *dlen, (a) ? "&#x9;" : "\t");		    break;		case '\r':		    *dlen += sprintf(*dst + *dlen, "&#xD;");		    break;		default:		    (*dst)[(*dlen)++] = *s;		}	}    return *dst;}/* Recursively converts each tag to xml appending it to *s. Reallocates *s if *//* its length excedes max. start is the location of the previous tag in the *//* parent tag's character content. Returns *s. */char *ezxml_toxml_r(ezxml_t xml,	      char **s,	      size_t * len,	      size_t * max,	      size_t start,	      char ***attr){    int i, j;    char *txt = (xml->parent) ? xml->parent->txt : "";    size_t off = 0;    /* parent character content up to this tag */    *s = ezxml_ampencode(txt + start, xml->off - start, s, len, max, 0);    while(*len + strlen(xml->name) + 4 > *max)	/* reallocate s */	*s = realloc(*s, *max += EZXML_BUFSIZE);    *len += sprintf(*s + *len, "<%s", xml->name);	/* open tag */    for(i = 0; xml->attr[i]; i += 2)	{			/* tag attributes */	    if(ezxml_attr(xml, xml->attr[i]) != xml->attr[i + 1])		continue;	    while(*len + strlen(xml->attr[i]) + 7 > *max)	/* reallocate s */		*s = realloc(*s, *max += EZXML_BUFSIZE);	    *len += sprintf(*s + *len, " %s=\"", xml->attr[i]);	    /* Ted Campbell, Aug 14, 2007. Added explicit cast to size_t. */	    ezxml_ampencode(xml->attr[i + 1], (size_t) (-1), s, len, max, 1);	    *len += sprintf(*s + *len, "\"");	}    for(i = 0; attr[i] && strcmp(attr[i][0], xml->name); i++);    for(j = 1; attr[i] && attr[i][j]; j += 3)	{			/* default attributes */	    if(!attr[i][j + 1]	       || ezxml_attr(xml, attr[i][j]) != attr[i][j + 1])		continue;	/* skip duplicates and non-values */	    while(*len + strlen(attr[i][j]) + 7 > *max)	/* reallocate s */		*s = realloc(*s, *max += EZXML_BUFSIZE);	    *len += sprintf(*s + *len, " %s=\"", attr[i][j]);	    /* Ted Campbell, Aug 14, 2007. Added explicit cast to size_t. */	    ezxml_ampencode(attr[i][j + 1], (size_t) (-1), s, len, max, 1);	    *len += sprintf(*s + *len, "\"");	}    *len += sprintf(*s + *len, ">");    /* Ted Campbell, Aug 14, 2007. Added explicit cast to size_t. */    *s = (xml->child) ? ezxml_toxml_r(xml->child, s, len, max, 0, attr)	/*child */	: ezxml_ampencode(xml->txt, (size_t) (-1), s, len, max, 0);	/*data */    while(*len + strlen(xml->name) + 4 > *max)	/* reallocate s */	*s = realloc(*s, *max += EZXML_BUFSIZE);    *len += sprintf(*s + *len, "</%s>", xml->name);	/* close tag */    while(txt[off] && off < xml->off)	off++;			/* make sure off is within bounds */    /* Ted Campbell, Aug 14, 2007. Added explicit cast to size_t. */    return (xml->ordered) ? ezxml_toxml_r(xml->ordered, s, len, max, off,					  attr) : ezxml_ampencode(txt +								  off,								  (size_t)								  (-1), s,								  len, max,								  0);}/* Converts an ezxml structure back to xml. Returns a string of xml data that *//* must be freed. */char *ezxml_toxml(ezxml_t xml){    ezxml_t p = (xml) ? xml->parent : NULL,      o = (xml) ? xml->ordered : NULL;    ezxml_root_t root = (ezxml_root_t) xml;    size_t len = 0, max = EZXML_BUFSIZE;    char *s = strcpy(malloc(max), ""),     *t,     *n;    int i, j, k;    if(!xml || !xml->name)	return realloc(s, len + 1);    while(root->xml.parent)	root = (ezxml_root_t) root->xml.parent;	/* root tag */    for(i = 0; !p && root->pi[i]; i++)	{			/* pre-root processing instructions */	    for(k = 2; root->pi[i][k - 1]; k++);	    for(j = 1; root->pi[i][j]; j++)		{		    /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */		    n = root->pi[i][j];		    if(root->pi[i][k][j - 1] == '>')			continue;	/* not pre-root */		    while(len + strlen(t = root->pi[i][0]) + strlen(n) + 7 >			  max)			s = realloc(s, max += EZXML_BUFSIZE);		    len +=			sprintf(s + len, "<?%s%s%s?>\n", t, *n ? " " : "", n);		}	}    xml->parent = xml->ordered = NULL;    s = ezxml_toxml_r(xml, &s, &len, &max, 0, root->attr);    xml->parent = p;    xml->ordered = o;    for(i = 0; !p && root->pi[i]; i++)	{			/* post-root processing instructions */	    for(k = 2; root->pi[i][k - 1]; k++);	    for(j = 1; root->pi[i][j]; j++)		{		    /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */		    n = root->pi[i][j];		    if(root->pi[i][k][j - 1] == '<')			continue;	/* not post-root */		    while(len + strlen(t = root->pi[i][0]) + strlen(n) + 7 >			  max)			s = realloc(s, max += EZXML_BUFSIZE);		    len +=			sprintf(s + len, "\n<?%s%s%s?>", t, *n ? " " : "", n);		}	}    return realloc(s, len + 1);}/* free the memory allocated for the ezxml structure */voidezxml_free(ezxml_t xml){    ezxml_root_t root = (ezxml_root_t) xml;    int i, j;    char **a, *s;    if(!xml)	return;    ezxml_free(xml->child);    ezxml_free(xml->ordered);    if(!xml->parent)	{			/* free root tag allocations */	    for(i = 10; root->ent[i]; i += 2)	/* 0 - 9 are default entites (<>&"') */		if((s = root->ent[i + 1]) < root->s || s > root->e)		    free(s);	    free(root->ent);	/* free list of general entities */	    for(i = 0; root->attr[i]; i++)		{		    /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */		    a = root->attr[i];		    for(j = 1; a[j++]; j += 2)	/* free malloced attribute values */			if(a[j] && (a[j] < root->s || a[j] > root->e))			    free(a[j]);		    free(a);		}	    if(root->attr[0])		free(root->attr);	/* free default attribute list */	    for(i = 0; root->pi[i]; i++)		{		    for(j = 1; root->pi[i][j]; j++);		    free(root->pi[i][j + 1]);		    free(root->pi[i]);		}	    if(root->pi[0])		free(root->pi);	/* free processing instructions */	    if(root->len == -1)		free(root->m);	/* malloced xml data */#ifndef EZXML_NOMMAP	    else if(root->len)		munmap(root->m, root->len);	/* mem mapped xml data */#endif /* EZXML_NOMMAP */	    if(root->u)		free(root->u);	/* utf8 conversion */	}    ezxml_free_attr(xml->attr);	/* tag attributes */    if((xml->flags & EZXML_TXTM))	free(xml->txt);		/* character content */    if((xml->flags & EZXML_NAMEM))	free(xml->name);	/* tag name */    free(xml);}/* return parser error message or empty string if none */const char *ezxml_error(ezxml_t xml){    while(xml && xml->parent)	xml = xml->parent;	/* find root tag */    return (xml) ? ((ezxml_root_t) xml)->err : "";}/* returns a new empty ezxml structure with the given root tag name */ezxml_tezxml_new(const char *name){    static char *ent[] = { "lt;", "&#60;", "gt;", "&#62;", "quot;", "&#34;",	"apos;", "&#39;", "amp;", "&#38;", NULL    };    ezxml_root_t root =	(ezxml_root_t) memset(malloc(sizeof(struct ezxml_root)),			      '\0', sizeof(struct ezxml_root));    root->xml.name = (char *)name;    root->cur = &root->xml;    strcpy(root->err, root->xml.txt = "");    root->ent = memcpy(malloc(sizeof(ent)), ent, sizeof(ent));    root->attr = root->pi = (char ***)(root->xml.attr = EZXML_NIL);    return &root->xml;}/* inserts an existing tag into an ezxml structure */ezxml_tezxml_insert(ezxml_t xml,	     ezxml_t dest,	     size_t off){    ezxml_t cur, prev, head;    xml->next = xml->sibling = xml->ordered = NULL;    xml->off = off;    xml->parent = dest;    /* Jason Luu, Aug 29, 2007. Removed assignment in conditional statement */    head = dest->child;    if(head)	{			/* already have sub tags */	    if(head->off <= off)		{		/* not first subtag */		    for(cur = head; cur->ordered && cur->ordered->off <= off;			cur = cur->ordered);		    xml->ordered = cur->ordered;		    cur->ordered = xml;		}	    else		{		/* first subtag */		    xml->ordered = head;		    dest->child = xml;		}	    for(cur = head, prev = NULL; cur && strcmp(cur->name, xml->name); prev = cur, cur = cur->sibling);	/* find tag type */	    if(cur && cur->off <= off)		{		/* not first of type */		    while(cur->next && cur->next->off <= off)			cur = cur->next;		    xml->next = cur->next;		    cur->next = xml;		}	    else		{		/* first tag of this type */		    if(prev && cur)			prev->sibling = cur->sibling;	/* remove old first */		    xml->next = cur;	/* old first tag is now next */		    for(cur = head, prev = NULL; cur && cur->off <= off; prev = cur, cur = cur->sibling);	/* new sibling insert point */		    xml->sibling = cur;		    if(prev)			prev->sibling = xml;		}	}    else	dest->child = xml;	/* only sub tag */    return xml;}/* Adds a child tag. off is the offset of the child tag relative to the start *//* of the parent tag's character content. Returns the child tag. */ezxml_tezxml_add_child(ezxml_t xml,		const char *name,		size_t off){    ezxml_t child;    if(!xml)	return NULL;    child = (ezxml_t) memset(malloc(sizeof(struct ezxml)), '\0',			     sizeof(struct ezxml));    child->name = (char *)name;    child->attr = EZXML_NIL;    child->txt = "";    return ezxml_insert(child, xml, off);}/* sets the character content for the given tag and returns the tag */ezxml_tezxml_set_txt(ezxml_t xml,	      const char *txt){    if(!xml)	return NULL;    if(xml->flags & EZXML_TXTM)	free(xml->txt);		/* existing txt was malloced */    xml->flags &= ~EZXML_TXTM;    xml->txt = (char *)txt;    return xml;}/* Sets the given tag attribute or adds a new attribute if not found. A value *//* of NULL will remove the specified attribute. Returns the tag given. */ezxml_tezxml_set_attr(ezxml_t xml,	       const char *name,	       const char *value){    int l = 0, c;    if(!xml)	return NULL;    while(xml->attr[l] && strcmp(xml->attr[l], name))	l += 2;    if(!xml->attr[l])	{			/* not found, add as new attribute */	    if(!value)		return xml;	/* nothing to do */	    if(xml->attr == EZXML_NIL)		{		/* first attribute */		    xml->attr = malloc(4 * sizeof(char *));		    /* Ted Campbell, Aug 14, 2007. Changed to use 'my_strdup' */		    xml->attr[1] = my_strdup("");	/* empty list of malloced names/vals */		}	    else		xml->attr = realloc(xml->attr, (l + 4) * sizeof(char *));	    xml->attr[l] = (char *)name;	/* set attribute name */	    xml->attr[l + 2] = NULL;	/* null terminate attribute list */	    xml->attr[l + 3] = realloc(xml->attr[l + 1],				       (c = strlen(xml->attr[l + 1])) + 2);	    strcpy(xml->attr[l + 3] + c, " ");	/* set name/value as not malloced */	    if(xml->flags & EZXML_DUP)		xml->attr[l + 3][c] = (char)(unsigned char)EZXML_NAMEM;	}    else if(xml->flags & EZXML_DUP)	free((char *)name);	/* name was strduped */    for(c = l; xml->attr[c]; c += 2);	/* find end of attribute list */    if(xml->attr[c + 1][l / 2] & EZXML_TXTM)	free(xml->attr[l + 1]);	/*old val */    if(xml->flags & EZXML_DUP)	xml->attr[c + 1][l / 2] |= EZXML_TXTM;    else	xml->attr[c + 1][l / 2] &= ~EZXML_TXTM;    if(value)	xml->attr[l + 1] = (char *)value;	/* set attribute value */    else	{			/* remove attribute */	    if(xml->attr[c + 1][l / 2] & EZXML_NAMEM)		free(xml->attr[l]);	    /* Ted Campbell, Aug 14, 2007. It seems that the size should be 	     * (c + 2) - (l + 2) = (c - l) */	    memmove(xml->attr + l, xml->attr + l + 2,		    (c - l) * sizeof(char *));	    /* Ted Campbell, Aug 14, 2007. We need to adjust c to point to new	     * location it was moved to since its old location is undefined */	    c -= 2;		/* We have one less elements */	    xml->attr = realloc(xml->attr, (c + 2) * sizeof(char *));	    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 */	}    xml->flags &= ~EZXML_DUP;	/* clear strdup() flag */    return xml;}/* sets a flag for the given tag and returns the tag */ezxml_tezxml_set_flag(ezxml_t xml,	       short flag){    if(xml)	xml->flags |= flag;    return xml;}/* removes a tag along with its subtags without freeing its memory */ezxml_tezxml_cut(ezxml_t xml){    ezxml_t cur;    if(!xml)	return NULL;		/* nothing to do */    if(xml->next)	xml->next->sibling = xml->sibling;	/* patch sibling list */    if(xml->parent)	{			/* not root tag */	    cur = xml->parent->child;	/* find head of subtag list */	    if(cur == xml)		xml->parent->child = xml->ordered;	/* first subtag */	    else		{		/* not first subtag */		    while(cur->ordered != xml)			cur = cur->ordered;		    cur->ordered = cur->ordered->ordered;	/* patch ordered list */		    cur = xml->parent->child;	/* go back to head of subtag list */		    if(strcmp(cur->name, xml->name))			{	/* not in first sibling list */			    while(strcmp(cur->sibling->name, xml->name))				cur = cur->sibling;			    if(cur->sibling == xml)				{	/* first of a sibling list */				    cur->sibling = (xml->next) ? xml->next					: cur->sibling->sibling;				}			    else				cur = cur->sibling;	/* not first of a sibling list */			}		    while(cur->next && cur->next != xml)			cur = cur->next;		    if(cur->next)			cur->next = cur->next->next;	/* patch next list */		}	}    xml->ordered = xml->sibling = xml->next = NULL;    return xml;}#ifdef EZXML_TEST		/* test harness */intmain(int argc,     char **argv){    ezxml_t xml;    char *s;    int i;    if(argc != 2)	return fprintf(stderr, "usage: %s xmlfile\n", argv[0]);    xml = ezxml_parse_file(argv[1]);    printf("%s\n", (s = ezxml_toxml(xml)));    free(s);    i = fprintf(stderr, "%s", ezxml_error(xml));    ezxml_free(xml);    return (i) ? 1 : 0;}#endif /* EZXML_TEST */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -