2007-02-03 05:05:30 -08:00
|
|
|
/* vim: set sw=4 ts=4 sts=4 et: */
|
2009-04-20 16:20:40 -07:00
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/mman.h>
|
|
|
|
|
|
|
|
#include <Ecore_File.h>
|
|
|
|
|
2007-02-03 05:05:30 -08:00
|
|
|
#include "Efreet.h"
|
|
|
|
#include "efreet_private.h"
|
2009-04-20 16:20:40 -07:00
|
|
|
#include "efreet_xml.h"
|
2007-02-03 05:05:30 -08:00
|
|
|
|
2008-10-26 13:05:34 -07:00
|
|
|
#if 0
|
2007-02-03 05:05:30 -08:00
|
|
|
static void efreet_xml_dump(Efreet_Xml *xml, int level);
|
2008-10-26 13:05:34 -07:00
|
|
|
#endif
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
static Efreet_Xml *efreet_xml_parse(char **data, int *size);
|
|
|
|
static int efreet_xml_tag_parse(char **data, int *size, const char **tag);
|
2007-09-06 09:15:10 -07:00
|
|
|
static void efreet_xml_attributes_parse(char **data, int *size,
|
2007-02-03 05:05:30 -08:00
|
|
|
Efreet_Xml_Attribute ***attributes);
|
2010-03-30 05:21:44 -07:00
|
|
|
static void efreet_xml_text_parse(char **data, int *size, const char **text);
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
static int efreet_xml_tag_empty(char **data, int *size);
|
|
|
|
static int efreet_xml_tag_close(char **data, int *size, const char *tag);
|
|
|
|
|
|
|
|
static void efreet_xml_cb_attribute_free(void *data);
|
|
|
|
static void efreet_xml_comment_skip(char **data, int *size);
|
|
|
|
|
|
|
|
static int error = 0;
|
|
|
|
|
2009-09-21 09:36:29 -07:00
|
|
|
/* define macros and variable for using the eina logging system */
|
|
|
|
|
|
|
|
#ifdef EFREET_MODULE_LOG_DOM
|
|
|
|
#undef EFREET_MODULE_LOG_DOM
|
|
|
|
#endif
|
|
|
|
#define EFREET_MODULE_LOG_DOM _efreet_xml_log_dom
|
|
|
|
|
2009-10-22 17:01:15 -07:00
|
|
|
static int _efreet_xml_init_count = 0;
|
2009-09-21 09:36:29 -07:00
|
|
|
static int _efreet_xml_log_dom = -1;
|
|
|
|
|
2007-02-03 05:05:30 -08:00
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
* @return Returns > 0 on success or 0 on failure
|
|
|
|
* @brief Initialize the XML parser subsystem
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
efreet_xml_init(void)
|
|
|
|
{
|
2010-02-04 01:12:35 -08:00
|
|
|
_efreet_xml_init_count++;
|
|
|
|
if (_efreet_xml_init_count > 1) return _efreet_xml_init_count;
|
|
|
|
_efreet_xml_log_dom = eina_log_domain_register("Efreet_xml", EFREET_DEFAULT_LOG_COLOR);
|
|
|
|
if (_efreet_xml_log_dom < 0)
|
|
|
|
{
|
2009-10-22 17:01:15 -07:00
|
|
|
_efreet_xml_init_count--;
|
2010-02-04 01:12:35 -08:00
|
|
|
ERROR("Efreet: Could not create a log domain for Efreet_xml.");
|
|
|
|
return _efreet_xml_init_count;
|
|
|
|
}
|
|
|
|
return _efreet_xml_init_count;
|
2007-02-03 05:05:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
* @returns the number of initializations left for this system
|
|
|
|
* @brief Attempts to shut down the subsystem if nothing else is using it
|
|
|
|
*/
|
2009-10-09 23:19:13 -07:00
|
|
|
void
|
2007-02-03 05:05:30 -08:00
|
|
|
efreet_xml_shutdown(void)
|
|
|
|
{
|
2010-02-04 01:12:35 -08:00
|
|
|
_efreet_xml_init_count--;
|
|
|
|
if (_efreet_xml_init_count > 0) return;
|
|
|
|
eina_log_domain_unregister(_efreet_xml_log_dom);
|
2007-02-03 05:05:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
* @param file: The file to parse
|
|
|
|
* @return Returns an Efreet_Xml structure for the given file @a file or
|
|
|
|
* NULL on failure
|
|
|
|
* @brief Parses the given file into an Efreet_Xml structure.
|
|
|
|
*/
|
|
|
|
Efreet_Xml *
|
|
|
|
efreet_xml_new(const char *file)
|
|
|
|
{
|
|
|
|
Efreet_Xml *xml = NULL;
|
|
|
|
int size, fd = -1;
|
2010-02-14 13:22:06 -08:00
|
|
|
char *data = MAP_FAILED;
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
if (!file) return NULL;
|
2010-04-18 13:04:09 -07:00
|
|
|
if (!ecore_file_exists(file)) return NULL;
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
size = ecore_file_size(file);
|
2009-04-20 16:20:40 -07:00
|
|
|
if (size <= 0) goto efreet_error;
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
fd = open(file, O_RDONLY);
|
2009-04-20 16:20:40 -07:00
|
|
|
if (fd == -1) goto efreet_error;
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
data = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
|
2010-02-14 13:22:06 -08:00
|
|
|
if (data == MAP_FAILED) goto efreet_error;
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
error = 0;
|
|
|
|
xml = efreet_xml_parse(&data, &size);
|
2009-04-20 16:20:40 -07:00
|
|
|
if (error) goto efreet_error;
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
munmap(data, size);
|
|
|
|
close(fd);
|
|
|
|
return xml;
|
|
|
|
|
2009-04-20 16:20:40 -07:00
|
|
|
efreet_error:
|
2009-09-21 09:36:29 -07:00
|
|
|
ERR("could not parse xml file");
|
2010-02-14 13:22:06 -08:00
|
|
|
if (data != MAP_FAILED) munmap(data, size);
|
2007-02-03 05:05:30 -08:00
|
|
|
if (fd != -1) close(fd);
|
|
|
|
if (xml) efreet_xml_del(xml);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
* @param xml: The Efree_Xml to free
|
|
|
|
* @return Returns no value
|
|
|
|
* @brief Frees up the given Efreet_Xml structure
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
efreet_xml_del(Efreet_Xml *xml)
|
|
|
|
{
|
2009-03-26 10:54:50 -07:00
|
|
|
IF_FREE_LIST(xml->children, efreet_xml_cb_attribute_free);
|
2007-02-03 05:05:30 -08:00
|
|
|
|
2008-10-15 07:48:03 -07:00
|
|
|
if (xml->tag) eina_stringshare_del(xml->tag);
|
2007-02-03 05:05:30 -08:00
|
|
|
if (xml->attributes)
|
|
|
|
{
|
|
|
|
Efreet_Xml_Attribute **curr;
|
|
|
|
|
|
|
|
curr = xml->attributes;
|
|
|
|
while (*curr)
|
|
|
|
{
|
2008-10-15 07:48:03 -07:00
|
|
|
eina_stringshare_del((*curr)->key);
|
|
|
|
eina_stringshare_del((*curr)->value);
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
FREE(*curr);
|
|
|
|
curr++;
|
|
|
|
}
|
|
|
|
FREE(xml->attributes);
|
|
|
|
}
|
2010-03-30 05:21:44 -07:00
|
|
|
IF_RELEASE(xml->text);
|
2007-02-03 05:05:30 -08:00
|
|
|
FREE(xml);
|
|
|
|
}
|
2007-09-06 09:15:10 -07:00
|
|
|
|
2007-02-03 05:05:30 -08:00
|
|
|
/**
|
|
|
|
* @param xml: The xml struct to work with
|
|
|
|
* @param key: The attribute key to look for
|
|
|
|
* @return Returns the value for the given key, or NULL if none found
|
|
|
|
* @brief Retrieves the value for the given attribute key
|
|
|
|
*/
|
|
|
|
const char *
|
|
|
|
efreet_xml_attribute_get(Efreet_Xml *xml, const char *key)
|
|
|
|
{
|
|
|
|
Efreet_Xml_Attribute **curr;
|
|
|
|
|
|
|
|
if (!xml || !key || !xml->attributes) return NULL;
|
|
|
|
|
|
|
|
for (curr = xml->attributes; *curr; curr++)
|
|
|
|
{
|
|
|
|
if (!strcmp((*curr)->key, key))
|
|
|
|
return (*curr)->value;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
efreet_xml_cb_attribute_free(void *data)
|
|
|
|
{
|
|
|
|
efreet_xml_del(data);
|
|
|
|
}
|
|
|
|
|
2008-10-26 13:05:34 -07:00
|
|
|
#if 0
|
2007-02-03 05:05:30 -08:00
|
|
|
static void
|
|
|
|
efreet_xml_dump(Efreet_Xml *xml, int level)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2007-09-06 09:15:10 -07:00
|
|
|
for (i = 0; i < level; i++)
|
2007-02-03 05:05:30 -08:00
|
|
|
printf("\t");
|
|
|
|
printf("<%s", xml->tag);
|
|
|
|
if (xml->attributes)
|
|
|
|
{
|
|
|
|
Efreet_Xml_Attribute **curr;
|
|
|
|
for (curr = xml->attributes; *curr; curr++)
|
|
|
|
printf(" %s=\"%s\"", (*curr)->key, (*curr)->value);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (xml->children)
|
|
|
|
{
|
|
|
|
Efreet_Xml *child;
|
2009-03-26 10:54:50 -07:00
|
|
|
Eina_List *l;
|
2007-02-03 05:05:30 -08:00
|
|
|
|
2009-09-21 09:36:29 -07:00
|
|
|
printf(">");
|
2007-02-03 05:05:30 -08:00
|
|
|
|
2009-03-26 10:54:50 -07:00
|
|
|
EINA_LIST_FOREACH(xml->children, l, child)
|
2007-02-03 05:05:30 -08:00
|
|
|
efreet_xml_dump(child, level + 1);
|
|
|
|
|
2007-09-06 09:15:10 -07:00
|
|
|
for (i = 0; i < level; i++)
|
2007-02-03 05:05:30 -08:00
|
|
|
printf("\t");
|
2009-09-21 09:36:29 -07:00
|
|
|
printf("</%s>", xml->tag);
|
2007-02-03 05:05:30 -08:00
|
|
|
}
|
|
|
|
else if (xml->text)
|
|
|
|
printf(">%s</%s>\n", xml->text, xml->tag);
|
|
|
|
else
|
|
|
|
printf("/>\n");
|
|
|
|
}
|
2008-10-26 13:05:34 -07:00
|
|
|
#endif
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
static Efreet_Xml *
|
|
|
|
efreet_xml_parse(char **data, int *size)
|
|
|
|
{
|
|
|
|
Efreet_Xml *xml, *sub_xml;
|
|
|
|
const char *tag = NULL;
|
|
|
|
|
|
|
|
/* parse this tag */
|
|
|
|
if (!efreet_xml_tag_parse(data, size, &(tag))) return NULL;
|
|
|
|
xml = NEW(Efreet_Xml, 1);
|
|
|
|
if (!xml)
|
|
|
|
{
|
2008-10-15 07:48:03 -07:00
|
|
|
eina_stringshare_del(tag);
|
2007-02-03 05:05:30 -08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2009-03-26 10:54:50 -07:00
|
|
|
xml->children = NULL;
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
xml->tag = tag;
|
|
|
|
efreet_xml_attributes_parse(data, size, &(xml->attributes));
|
|
|
|
|
|
|
|
/* Check wether element is empty */
|
|
|
|
if (efreet_xml_tag_empty(data, size)) return xml;
|
|
|
|
efreet_xml_text_parse(data, size, &(xml->text));
|
|
|
|
|
|
|
|
/* Check wether element is closed */
|
|
|
|
if (efreet_xml_tag_close(data, size, xml->tag)) return xml;
|
|
|
|
|
|
|
|
while ((sub_xml = efreet_xml_parse(data, size)))
|
2009-03-26 10:54:50 -07:00
|
|
|
xml->children = eina_list_append(xml->children, sub_xml);
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
efreet_xml_tag_close(data, size, xml->tag);
|
|
|
|
|
|
|
|
return xml;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
efreet_xml_tag_parse(char **data, int *size, const char **tag)
|
|
|
|
{
|
|
|
|
const char *start = NULL, *end = NULL;
|
|
|
|
char buf[256];
|
|
|
|
int buf_size;
|
|
|
|
|
|
|
|
/* Search for tag */
|
|
|
|
while (*size > 1)
|
|
|
|
{
|
|
|
|
/* Check for tag start */
|
|
|
|
if (**data == '<')
|
|
|
|
{
|
|
|
|
/* Check for end tag */
|
|
|
|
if (*(*data + 1) == '/') return 0;
|
|
|
|
|
|
|
|
/* skip comments */
|
2007-09-06 09:15:10 -07:00
|
|
|
if (*size > 3 && *(*data + 1) == '!' && *(*data + 2) == '-' && *(*data + 3) == '-')
|
2007-02-03 05:05:30 -08:00
|
|
|
{
|
|
|
|
(*data) += 3;
|
|
|
|
(*size) -= 3;
|
|
|
|
efreet_xml_comment_skip(data, size);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check for xml directives (and ignore them) */
|
|
|
|
else if ((*(*data + 1) != '!') && (*(*data + 1) != '?'))
|
|
|
|
{
|
|
|
|
(*size)--;
|
|
|
|
(*data)++;
|
|
|
|
start = *data;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
(*size)--;
|
|
|
|
(*data)++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!start)
|
|
|
|
{
|
2009-09-21 09:36:29 -07:00
|
|
|
ERR("missing start tag");
|
2007-02-03 05:05:30 -08:00
|
|
|
error = 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (*size > 0)
|
|
|
|
{
|
|
|
|
if (!isalpha(**data))
|
|
|
|
{
|
|
|
|
end = *data;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
(*size)--;
|
|
|
|
(*data)++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!end)
|
|
|
|
{
|
2009-09-21 09:36:29 -07:00
|
|
|
ERR("no end of tag");
|
2007-02-03 05:05:30 -08:00
|
|
|
error = 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
buf_size = end - start + 1;
|
|
|
|
if (buf_size <= 1)
|
|
|
|
{
|
2009-09-21 09:36:29 -07:00
|
|
|
ERR("no tag name");
|
2007-02-03 05:05:30 -08:00
|
|
|
error = 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (buf_size > 256) buf_size = 256;
|
|
|
|
memcpy(buf, start, buf_size - 1);
|
2007-04-04 05:00:40 -07:00
|
|
|
buf[buf_size - 1] = '\0';
|
2008-10-15 07:48:03 -07:00
|
|
|
*tag = eina_stringshare_add(buf);
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
efreet_xml_attributes_parse(char **data, int *size,
|
|
|
|
Efreet_Xml_Attribute ***attributes)
|
|
|
|
{
|
|
|
|
Efreet_Xml_Attribute attr[10];
|
|
|
|
int i, count = 0;
|
|
|
|
|
|
|
|
while (*size > 0)
|
|
|
|
{
|
|
|
|
if (**data == '>')
|
|
|
|
{
|
|
|
|
(*size)++;
|
|
|
|
(*data)--;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if ((count < 10) && (isalpha(**data)))
|
|
|
|
{
|
|
|
|
/* beginning of key */
|
|
|
|
const char *start = NULL, *end = NULL;
|
|
|
|
char buf[256];
|
|
|
|
int buf_size;
|
|
|
|
|
|
|
|
attr[count].key = NULL;
|
|
|
|
attr[count].value = NULL;
|
|
|
|
|
|
|
|
start = *data;
|
|
|
|
while ((*size > 0) && ((isalpha(**data)) || (**data == '_')))
|
|
|
|
{
|
|
|
|
(*size)--;
|
|
|
|
(*data)++;
|
|
|
|
}
|
|
|
|
|
|
|
|
end = *data;
|
|
|
|
buf_size = end - start + 1;
|
|
|
|
if (buf_size <= 1)
|
|
|
|
{
|
2010-02-04 01:12:35 -08:00
|
|
|
ERR("zero length key");
|
2009-04-20 16:20:40 -07:00
|
|
|
goto efreet_error;
|
2007-02-03 05:05:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (buf_size > 256) buf_size = 256;
|
|
|
|
memcpy(buf, start, buf_size - 1);
|
2007-04-04 05:00:40 -07:00
|
|
|
buf[buf_size - 1] = '\0';
|
2008-10-15 07:48:03 -07:00
|
|
|
attr[count].key = eina_stringshare_add(buf);
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
/* search for '=', key/value seperator */
|
|
|
|
start = NULL;
|
|
|
|
while (*size > 0)
|
|
|
|
{
|
|
|
|
if (**data == '=')
|
|
|
|
{
|
|
|
|
start = *data;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
(*size)--;
|
|
|
|
(*data)++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!start)
|
|
|
|
{
|
2010-02-04 01:12:35 -08:00
|
|
|
ERR("missing value for attribute!");
|
2009-04-20 16:20:40 -07:00
|
|
|
goto efreet_error;
|
2007-02-03 05:05:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* search for '"', beginning of value */
|
|
|
|
start = NULL;
|
|
|
|
while (*size > 0)
|
|
|
|
{
|
|
|
|
if (**data == '"')
|
|
|
|
{
|
|
|
|
start = *data;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
(*size)--;
|
|
|
|
(*data)++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!start)
|
|
|
|
{
|
2009-09-21 09:36:29 -07:00
|
|
|
ERR("erroneous value for attribute!");
|
2009-04-20 16:20:40 -07:00
|
|
|
goto efreet_error;
|
2007-02-03 05:05:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* skip '"' */
|
|
|
|
start++;
|
|
|
|
(*size)--;
|
|
|
|
(*data)++;
|
|
|
|
|
|
|
|
/* search for '"', end of value */
|
|
|
|
end = NULL;
|
|
|
|
while (*size > 0)
|
|
|
|
{
|
|
|
|
if (**data == '"')
|
|
|
|
{
|
|
|
|
end = *data;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
(*size)--;
|
|
|
|
(*data)++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!end)
|
|
|
|
{
|
2009-09-21 09:36:29 -07:00
|
|
|
ERR("erroneous value for attribute!");
|
2009-04-20 16:20:40 -07:00
|
|
|
goto efreet_error;
|
2007-02-03 05:05:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
buf_size = end - start + 1;
|
|
|
|
if (buf_size <= 1)
|
|
|
|
{
|
2010-02-04 01:12:35 -08:00
|
|
|
ERR("zero length value");
|
2009-04-20 16:20:40 -07:00
|
|
|
goto efreet_error;
|
2007-02-03 05:05:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (buf_size > 256) buf_size = 256;
|
|
|
|
memcpy(buf, start, buf_size - 1);
|
2007-04-04 05:00:40 -07:00
|
|
|
buf[buf_size - 1] = '\0';
|
2008-10-15 07:48:03 -07:00
|
|
|
attr[count].value = eina_stringshare_add(buf);
|
2007-02-03 05:05:30 -08:00
|
|
|
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
(*size)--;
|
|
|
|
(*data)++;
|
|
|
|
}
|
|
|
|
|
|
|
|
*attributes = NEW(Efreet_Xml_Attribute *, count + 1);
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
(*attributes)[i] = malloc(sizeof(Efreet_Xml_Attribute));
|
|
|
|
(*attributes)[i]->key = attr[i].key;
|
|
|
|
(*attributes)[i]->value = attr[i].value;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
|
2009-04-20 16:20:40 -07:00
|
|
|
efreet_error:
|
2007-02-03 05:05:30 -08:00
|
|
|
while (count >= 0)
|
|
|
|
{
|
2008-10-15 07:48:03 -07:00
|
|
|
if (attr[count].key) eina_stringshare_del(attr[count].key);
|
|
|
|
if (attr[count].value) eina_stringshare_del(attr[count].value);
|
2007-02-03 05:05:30 -08:00
|
|
|
count--;
|
|
|
|
}
|
|
|
|
error = 1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2010-03-30 05:21:44 -07:00
|
|
|
efreet_xml_text_parse(char **data, int *size, const char **text)
|
2007-02-03 05:05:30 -08:00
|
|
|
{
|
|
|
|
const char *start = NULL, *end = NULL;
|
|
|
|
int buf_size;
|
|
|
|
|
|
|
|
/* skip leading whitespace */
|
|
|
|
while (*size > 0)
|
|
|
|
{
|
|
|
|
if (!isspace(**data))
|
|
|
|
{
|
|
|
|
start = *data;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
(*size)--;
|
|
|
|
(*data)++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!start) return;
|
|
|
|
|
|
|
|
/* find next tag */
|
|
|
|
while (*size > 0)
|
|
|
|
{
|
|
|
|
if (**data == '<')
|
|
|
|
{
|
|
|
|
end = *data;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
(*size)--;
|
|
|
|
(*data)++;
|
|
|
|
}
|
|
|
|
if (!end) return;
|
|
|
|
|
|
|
|
/* skip trailing whitespace */
|
|
|
|
while (isspace(*(end - 1))) end--;
|
|
|
|
|
|
|
|
/* copy text */
|
|
|
|
buf_size = end - start + 1;
|
|
|
|
if (buf_size <= 1) return;
|
|
|
|
|
2010-03-30 05:21:44 -07:00
|
|
|
*text = eina_stringshare_add_length(start, buf_size - 1);
|
2007-02-03 05:05:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
efreet_xml_tag_empty(char **data, int *size)
|
|
|
|
{
|
|
|
|
while (*size > 1)
|
|
|
|
{
|
|
|
|
if (**data == '/')
|
|
|
|
{
|
|
|
|
(*size)--;
|
|
|
|
(*data)++;
|
|
|
|
if (**data == '>')
|
|
|
|
{
|
|
|
|
(*size)--;
|
|
|
|
(*data)++;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (**data == '>')
|
|
|
|
{
|
|
|
|
(*size)--;
|
|
|
|
(*data)++;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
(*size)--;
|
|
|
|
(*data)++;
|
|
|
|
}
|
2009-09-21 09:36:29 -07:00
|
|
|
ERR("missing end of tag");
|
2007-02-03 05:05:30 -08:00
|
|
|
error = 1;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
efreet_xml_tag_close(char **data, int *size, const char *tag)
|
|
|
|
{
|
|
|
|
while (*size > 1)
|
|
|
|
{
|
|
|
|
if (**data == '<')
|
|
|
|
{
|
|
|
|
if (*(*data + 1) == '/')
|
|
|
|
{
|
|
|
|
(*size) -= 2;
|
|
|
|
(*data) += 2;
|
|
|
|
if ((int)strlen(tag) > *size)
|
|
|
|
{
|
2010-02-04 01:12:35 -08:00
|
|
|
ERR("wrong end tag");
|
2007-02-03 05:05:30 -08:00
|
|
|
error = 1;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char *tmp;
|
|
|
|
tmp = *data;
|
|
|
|
while ((*tag) && (*tmp == *tag))
|
|
|
|
{
|
|
|
|
tmp++;
|
|
|
|
tag++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*tag)
|
|
|
|
{
|
2009-09-21 09:36:29 -07:00
|
|
|
ERR("wrong end tag");
|
2007-02-03 05:05:30 -08:00
|
|
|
error = 1;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else return 0;
|
|
|
|
}
|
|
|
|
(*size)--;
|
|
|
|
(*data)++;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-09-06 09:15:10 -07:00
|
|
|
static void
|
2007-02-03 05:05:30 -08:00
|
|
|
efreet_xml_comment_skip(char **data, int *size)
|
|
|
|
{
|
|
|
|
while (*size > 2)
|
|
|
|
{
|
|
|
|
if (**data == '-' && *(*data + 1) == '-' && *(*data + 2) == '>')
|
|
|
|
{
|
|
|
|
(*data) += 3;
|
|
|
|
(*size) -= 3;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
(*data)++;
|
|
|
|
(*size)--;
|
|
|
|
}
|
|
|
|
}
|