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

📄 mxml-file.c

📁 适用于嵌入式系统的XML解析库, 规模比libxml2小得多.
💻 C
📖 第 1 页 / 共 5 页
字号:
	*/	while ((ch = (*getc_cb)(p, &encoding)) != EOF)	{	  if (ch == '>' && bufptr > buffer && bufptr[-1] == '?')	    break;	  else if (mxml_add_char(ch, &bufptr, &buffer, &bufsize))	    goto error;	}       /*        * Error out if we didn't get the whole processing instruction...	*/        if (ch != '>')	{	 /*	  * Print error and return...	  */	  mxml_error("Early EOF in processing instruction node!");	  goto error;	}       /*        * Otherwise add this as an element under the current parent...	*/	*bufptr = '\0';	if ((node = mxmlNewElement(parent, buffer)) == NULL)	{	 /*	  * Print error and return...	  */	  mxml_error("Unable to add processing instruction node to parent <%s>!",	             parent ? parent->value.element.name : "null");	  goto error;	}        if (sax_cb)        {          (*sax_cb)(node, MXML_SAX_DIRECTIVE, sax_data);          if (!mxmlRelease(node))            node = NULL;        }        if (node)	{	  if (!first)            first = node;	  if (!parent)	  {	    parent = node;	    if (cb)	      type = (*cb)(parent);	  }	}      }      else if (buffer[0] == '!')      {       /*        * Gather rest of declaration...	*/	do	{	  if (ch == '>')	    break;	  else	  {            if (ch == '&')	      if ((ch = mxml_get_entity(parent, p, &encoding, getc_cb)) == EOF)		goto error;	    if (mxml_add_char(ch, &bufptr, &buffer, &bufsize))	      goto error;	  }	}        while ((ch = (*getc_cb)(p, &encoding)) != EOF);       /*        * Error out if we didn't get the whole declaration...	*/        if (ch != '>')	{	 /*	  * Print error and return...	  */	  mxml_error("Early EOF in declaration node!");	  goto error;	}       /*        * Otherwise add this as an element under the current parent...	*/	*bufptr = '\0';	if ((node = mxmlNewElement(parent, buffer)) == NULL)	{	 /*	  * Print error and return...	  */	  mxml_error("Unable to add declaration node to parent <%s>!",	             parent ? parent->value.element.name : "null");	  goto error;	}        if (sax_cb)        {          (*sax_cb)(node, MXML_SAX_DIRECTIVE, sax_data);          if (!mxmlRelease(node))            node = NULL;        }        if (node)	{	  if (!first)            first = node;	  if (!parent)	  {	    parent = node;	    if (cb)	      type = (*cb)(parent);	  }	}      }      else if (buffer[0] == '/')      {       /*        * Handle close tag...	*/        if (!parent || strcmp(buffer + 1, parent->value.element.name))	{	 /*	  * Close tag doesn't match tree; print an error for now...	  */	  mxml_error("Mismatched close tag <%s> under parent <%s>!",	             buffer, parent ? parent->value.element.name : "(null)");          goto error;	}       /*        * Keep reading until we see >...	*/        while (ch != '>' && ch != EOF)	  ch = (*getc_cb)(p, &encoding);        node   = parent;        parent = parent->parent;        if (sax_cb)        {          (*sax_cb)(node, MXML_SAX_ELEMENT_CLOSE, sax_data);          mxmlRelease(node);        }       /*	* Ascend into the parent and set the value type as needed...	*/	if (cb && parent)	  type = (*cb)(parent);      }      else      {       /*        * Handle open tag...	*/        if ((node = mxmlNewElement(parent, buffer)) == NULL)	{	 /*	  * Just print error for now...	  */	  mxml_error("Unable to add element node to parent <%s>!",	             parent ? parent->value.element.name : "null");	  goto error;	}        if (mxml_isspace(ch))        {	  if ((ch = mxml_parse_element(node, p, &encoding, getc_cb)) == EOF)	    goto error;        }        else if (ch == '/')	{	  if ((ch = (*getc_cb)(p, &encoding)) != '>')	  {	    mxml_error("Expected > but got '%c' instead for element <%s/>!",	               ch, buffer);            mxmlDelete(node);            goto error;	  }	  ch = '/';	}        if (sax_cb)          (*sax_cb)(node, MXML_SAX_ELEMENT_OPEN, sax_data);        if (!first)	  first = node;	if (ch == EOF)	  break;        if (ch != '/')	{	 /*	  * Descend into this node, setting the value type as needed...	  */	  parent = node;	  if (cb && parent)	    type = (*cb)(parent);	}        else if (sax_cb)        {          (*sax_cb)(node, MXML_SAX_ELEMENT_CLOSE, sax_data);          if (!mxmlRelease(node) && first == node)            first = NULL;        }      }      bufptr  = buffer;    }    else if (ch == '&')    {     /*      * Add character entity to current buffer...      */      if ((ch = mxml_get_entity(parent, p, &encoding, getc_cb)) == EOF)	goto error;      if (mxml_add_char(ch, &bufptr, &buffer, &bufsize))	goto error;    }    else if (type == MXML_OPAQUE || type == MXML_CUSTOM || !mxml_isspace(ch))    {     /*      * Add character to current buffer...      */      if (mxml_add_char(ch, &bufptr, &buffer, &bufsize))	goto error;    }  } /*  * Free the string buffer - we don't need it anymore...  */  free(buffer); /*  * Find the top element and return it...  */  if (parent)  {    node = parent;    while (parent->parent != top && parent->parent)      parent = parent->parent;    if (node != parent)    {      mxml_error("Missing close tag </%s> under parent <%s>!",	         node->value.element.name,		 node->parent ? node->parent->value.element.name : "(null)");      mxmlDelete(first);      return (NULL);    }  }  if (parent)    return (parent);  else    return (first); /*  * Common error return...  */error:  mxmlDelete(first);  free(buffer);  return (NULL);}/* * 'mxml_parse_element()' - Parse an element for any attributes... */static int				/* O  - Terminating character */mxml_parse_element(    mxml_node_t     *node,		/* I  - Element node */    void            *p,			/* I  - Data to read from */    int             *encoding,		/* IO - Encoding */    _mxml_getc_cb_t getc_cb)		/* I  - Data callback */{  int	ch,				/* Current character in file */	quote;				/* Quoting character */  char	*name,				/* Attribute name */	*value,				/* Attribute value */	*ptr;				/* Pointer into name/value */  int	namesize,			/* Size of name string */	valsize;			/* Size of value string */ /*  * Initialize the name and value buffers...  */  if ((name = malloc(64)) == NULL)  {    mxml_error("Unable to allocate memory for name!");    return (EOF);  }  namesize = 64;  if ((value = malloc(64)) == NULL)  {    free(name);    mxml_error("Unable to allocate memory for value!");    return (EOF);  }  valsize = 64; /*  * Loop until we hit a >, /, ?, or EOF...  */  while ((ch = (*getc_cb)(p, encoding)) != EOF)  {#if DEBUG > 1    fprintf(stderr, "parse_element: ch='%c'\n", ch);#endif /* DEBUG > 1 */   /*    * Skip leading whitespace...    */    if (mxml_isspace(ch))      continue;   /*    * Stop at /, ?, or >...    */    if (ch == '/' || ch == '?')    {     /*      * Grab the > character and print an error if it isn't there...      */      quote = (*getc_cb)(p, encoding);      if (quote != '>')      {        mxml_error("Expected '>' after '%c' for element %s, but got '%c'!",	           ch, node->value.element.name, quote);        goto error;      }      break;    }    else if (ch == '<')    {      mxml_error("Bare < in element %s!", node->value.element.name);      goto error;    }    else if (ch == '>')      break;   /*    * Read the attribute name...    */    name[0] = ch;    ptr     = name + 1;    if (ch == '\"' || ch == '\'')    {     /*      * Name is in quotes, so get a quoted string...      */      quote = ch;      while ((ch = (*getc_cb)(p, encoding)) != EOF)      {        if (ch == '&')	  if ((ch = mxml_get_entity(node, p, encoding, getc_cb)) == EOF)	    goto error;	if (mxml_add_char(ch, &ptr, &name, &namesize))	  goto error;	if (ch == quote)          break;      }    }    else    {     /*      * Grab an normal, non-quoted name...      */      while ((ch = (*getc_cb)(p, encoding)) != EOF)	if (mxml_isspace(ch) || ch == '=' || ch == '/' || ch == '>' ||	    ch == '?')          break;	else	{          if (ch == '&')	    if ((ch = mxml_get_entity(node, p, encoding, getc_cb)) == EOF)	      goto error;	  if (mxml_add_char(ch, &ptr, &name, &namesize))	    goto error;	}    }    *ptr = '\0';    if (mxmlElementGetAttr(node, name))      goto error;    while (ch != EOF && mxml_isspace(ch))      ch = (*getc_cb)(p, encoding);    if (ch == '=')    {     /*      * Read the attribute value...      */      while ((ch = (*getc_cb)(p, encoding)) != EOF && mxml_isspace(ch));      if (ch == EOF)      {        mxml_error("Missing value for attribute '%s' in element %s!",	           name, node->value.element.name);        goto error;      }      if (ch == '\'' || ch == '\"')      {       /*        * Read quoted value...	*/        quote = ch;	ptr   = value;        while ((ch = (*getc_cb)(p, encoding)) != EOF)	  if (ch == quote)	    break;	  else	  {	    if (ch == '&')	      if ((ch = mxml_get_entity(node, p, encoding, getc_cb)) == EOF)	        goto error;	      	    if (mxml_add_char(ch, &ptr, &value, &valsize))	      goto error;	  }        *ptr = '\0';      }      else      {       /*        * Read unquoted value...	*/	value[0] = ch;	ptr      = value + 1;	while ((ch = (*getc_cb)(p, encoding)) != EOF)	  if (mxml_isspace(ch) || ch == '=' || ch == '/' || ch == '>')            break;	  else	  {	    if (ch == '&')	      if ((ch = mxml_get_entity(node, p, encoding, getc_cb)) == EOF)	        goto error;	      	    if (mxml_add_char(ch, &ptr, &value, &valsize))	      goto error;	  }        *ptr = '\0';      }     /*      * Set the attribute with the given string value...      */      mxmlElementSetAttr(node, name, value);    }    else    {      mxml_error("Missing value for attribute '%s' in element %s!",	         name, node->value.element.name);      goto error;    }   /*    * Check the end character...    */    if (ch == '/' || ch == '?')    {     /*      * Grab the > character and print an error if it isn't there...      */      quote = (*getc_cb)(p, encoding);      if (quote != '>')      {        mxml_error("Expected '>' after '%c' for element %s, but got '%c'!",	           ch, node->value.element.name, quote);        ch = EOF;      }      break;    }    else if (ch == '>')      break;  } /*  * Free the name and value buffers and return...  */  free(name);  free(value);  return (ch); /*  * Common error return point...  */error:  free(name);  free(value);  return (EOF);}/* * 'mxml_string_getc()' - Get a character from a string. */static int				/* O  - Character or EOF */mxml_string_getc(void *p,		/* I  - Pointer to file */                 int  *encoding)	/* IO - Encoding */{  int		ch;			/* Character */  const char	**s;			/* Pointer to string pointer */  s = (const char **)p;

⌨️ 快捷键说明

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