Exemplo n.º 1
0
static char * _tinycxml_parse(char *xml,XMLNode *parent, char *buffer){
	char *c = NULL;
	char *n = NULL;
	char *p = NULL;
	XMLNode *node = NULL;
	
	if(xml == NULL) return NULL;
	if(*xml == 0)   return xml;
	c = strstr(xml,"<");
	if(c == NULL)   return NULL;
	c++;
	if(*c == '/' )  return c;

	p = buffer;
	for(;*c && *c != '>' && *c != ' '; c++){
		*(p++) = *c;
	}
	*p = 0;

	node = xmlnode_new(buffer);
	
	xmlnode_add(&parent->children,node);
	
	XMLNode *attrib;
	if(*c == ' '){ // Attributes
		p = buffer;
		n = c;
		c = strstr(c,">");
		for(n++;n<c;n++){
			if(*n == '='){
				*p = 0;
				attrib = xmlnode_new(buffer);
				xmlnode_add(&node->attributes,attrib);
				p = buffer;
				// n+=2 // Get past the opening " char
				for(n+=2;n<c && *n!='"';n++){
					*(p++) = *n;
				}
				*p = 0;
				attrib->content = strdup(buffer);
				p = buffer;
			}else if (*n != ' '){
				*(p++) = *n;	
			}
		}
		// Self closing tag?
		if( *(c-1) == '/' ) return c;
	}
	c++;

	/* There is a lot of XML out there that invalidates
	 * XML spec by using '<' and friends inside a CDATA tag.
	 * Although according to the spec we should just error
	 * out, I prefer to mitigate errors in well known conditions. */

	/* Raw copy in the CDATA tag */
	/* Assume CDATA is the only content */
	if(strncmp(c,"<![CDATA[",9) == 0){
		n = strstr(c,"]]>");
		n += 3;
		node->content = g_strndup(c, n-c);
		n = strstr(n,">");
		return (n) ?  n+1 : NULL;
	}

	while(1){
		n = _tinycxml_parse(c,node,buffer);
		if (n == NULL ) break;
		if(*n == '/' ) {
			memcpy(buffer,c,n-c-1);
			buffer[n-c-1] = 0;
			if(!strisspace(buffer)){
				node->content = strdup(buffer);
			}
			n = strstr(n,">");
			return (n) ?  n+1 : NULL;
		}
		if(*n == 0) break;
		c = n;
	}
	return NULL;
}
Exemplo n.º 2
0
Arquivo: main.c Projeto: Dioxylin/shs
char *get_next_token(char *line, size_t line_size, int *start_from)
{
	enum parse_state state = NORMAL;
	int i = *start_from;
	static char word[BUFSIZE] = {'\0'};
	int word_i = 0;

	/* No further tokens */
	if (*start_from >= line_size) return NULL;

	if (strisspace(line))
		return NULL;

	while (isspace(line[i]))
		++i;

	/* Comment */
	if (line[i] == '#') {
		return NULL;
	}

	if (line[i] == '$' && line[i+1] == '\'') {
		state = SINGLE_QUOTE;
		word[word_i++] = line[i++];
		word[word_i++] = line[i++];
	}
	else if (line[i] == '\'') {
		state = SINGLE_QUOTE;
		word[word_i++] = line[i++];
	}

	if (state == SINGLE_QUOTE) {
		for (; i < line_size; ++i) {
			/* single quote makes entire value have single quote */
			if (line[i] == '\'' && line[i+1] == '\'') {
				word[word_i++] = '\'';
				word[word_i] = '\'';
				++i; /* this will increment a second time during loopover to skip the second quote */
			}
			else if (line[i] == '\''){ /* terminate single-quoted string */
				word[word_i++] = line[i];
				word[word_i] = '\0';
				break;
			}
			else {
				word[word_i] = line[i];
			}
			++word_i;
		}
		if (i >= line_size) {
			eprintf("Input ended unexpectedly\n");
			return NULL;
		}
		++i; /* Increment one last time to get to possible whitespace */

		if (!isspace(line[i])) {
			eprintf("Input after quote is not whitespace.\n");
			return NULL;
		}
	}
	else if (state == NORMAL) {
		for (; i < line_size; ++i) {
			if (isspace(line[i])) {
				word[word_i] = '\0';
				break;
			}
			else {
				word[word_i] = line[i];
				++word_i;
			}
		}
	}

	/* Skip whitespace */
	while (isspace(line[i]))
		++i;

	*start_from = i;

	return word;
}