Beispiel #1
0
static const char *json_value(ACL_JSON *json, const char *data)
{
	SKIP_SPACE(data);
	if (*data == 0)
		return NULL;

	/* 为 '{' 或 '[' 时说明遇到了当前结点的子结点 */
	if (*data == '{') {
		data++;
		json->status = ACL_JSON_S_OBJ;
	} else if (*data == '[') {
		data++;
		json->status = ACL_JSON_S_ARRAY;
	}

	/* 兼容一下有些数据格式为 "xxx: ," 的方式 */
	else if (*data == ',' || *data == ';') {
		data++;
		/* 切换至查询该结点的兄弟结点的过程 */
		json->status = ACL_JSON_S_NEXT;
	}

	/* 说明标签名后面的标签值为字符串或数字 */
	/* 如果标签值前有引号,记录下该引号 */
	else if (IS_QUOTE(*data)) { /* && json->curr_node->quote == 0) { */
		json->curr_node->quote = *data++;
		json->status = ACL_JSON_S_STRING;
	} else
		json->status = ACL_JSON_S_STRING;

	json->curr_node->type = ACL_JSON_T_LEAF;
	return data;
}
Beispiel #2
0
static int	get_file_name_len(const char *str)
{
  int		len;
  const char	*save;

  save = str;
  while (IS_SPACE(*str))
    ++str;
  if (!(*str) || (IS_DELIM(*str)))
    return (return_error(MISS_NAME_DIR, END_CHAR));
  while ((*str) && !(IS_SPACE(*str)) && !(IS_DELIM(*str)))
    {
      if (IS_QUOTE(*str))
	{
	  if ((len = pass_quote(str)) == -1)
	    return (return_error(UNMATCH_QUOTE, *str));
	  str += len;
	}
      else if (*str == B_SLASH)
	{
	  if (!(*(++str)))
	    return (return_error(MISS_SLASH, END_CHAR));
	}
      ++str;
    }
  return (str - save);
}
Beispiel #3
0
static char *xml_meta_attr_value(ACL_XML3_ATTR *attr, char *data)
{
	ACL_XML3 *xml = attr->node->xml;
	int   ch;

	SKIP_SPACE(data);
	if (IS_QUOTE(*data))
		attr->quote = *data++;

	if (*data == 0)
		return data;

	if (attr->value == xml->addr)
		attr->value = data;

	while ((ch = *data) != 0) {
		if (attr->quote && ch == attr->quote) {
			attr->value_size = data - attr->value;
			*data++ = 0;
			break;
		} else if (IS_SPACE(ch)) {
			attr->value_size = data - attr->value;
			*data++ = 0;
			break;
		}

		data++;
	}

	return data;
}
Beispiel #4
0
static char *xml_parse_meta_text(ACL_XML3 *xml, char *data)
{
	int   ch;

	if (xml->curr_node->text == xml->addr)
		SKIP_SPACE(data);

	if (*data == 0)
		return data;

	if (xml->curr_node->text == xml->addr)
		xml->curr_node->text = data;

	while ((ch = *data) != 0) {
		if (xml->curr_node->quote) {
			if (ch == xml->curr_node->quote)
				xml->curr_node->quote = 0;
		} else if (IS_QUOTE(ch)) {
			if (xml->curr_node->quote == 0)
				xml->curr_node->quote = ch;
		} else if (ch == '<') {
			xml->curr_node->nlt++;
		} else if (ch != '>') {
			;
		} else if (xml->curr_node->nlt == 0) {
			char *last;

			xml->curr_node->text_size = data - xml->curr_node->text;
			xml->curr_node->status = ACL_XML3_S_MEND;
			*data++ = 0;

			if ((xml->curr_node->flag & ACL_XML3_F_META_QM) == 0)
				break;

			last = data;
			while (last > xml->curr_node->text) {
				if (*last == '?') {
					xml->curr_node->text_size = last -
						xml->curr_node->text;
					*last = 0;
					break;
				}
				last--;
			}
			if (last == xml->curr_node->text)
				break;

			xml_meta_attr(xml->curr_node);
			break;
		} else {
			xml->curr_node->nlt--;
		}

		data++;
	}

	return data;
}
Beispiel #5
0
static char *xml_parse_meta_comment(ACL_XML3 *xml, char *data)
{
	int   ch;

	if (xml->curr_node->text == xml->addr)
		SKIP_SPACE(data);

	if (*data == 0)
		return data;

	if (xml->curr_node->text == xml->addr)
		xml->curr_node->text = data;

	while ((ch = *data) != 0) {
		if (xml->curr_node->quote) {
			if (ch == xml->curr_node->quote)
				xml->curr_node->quote = 0;
		} else if (IS_QUOTE(ch)) {
			if (xml->curr_node->quote == 0)
				xml->curr_node->quote = ch;
		} else if (ch == '<') {
			xml->curr_node->nlt++;
		} else if (ch == '>') {
			if (xml->curr_node->nlt == 0
				&& xml->curr_node->meta[0] == '-'
				&& xml->curr_node->meta[1] == '-')
			{

				xml->curr_node->text_size = data -
					xml->curr_node->text;
				xml->curr_node->status = ACL_XML3_S_MEND;
				*data++ = 0;
				break;
			}

			xml->curr_node->nlt--;
		} else if (xml->curr_node->nlt > 0) {
			;
		} else if (ch == '-') {
			if (xml->curr_node->meta[0] != '-')
				xml->curr_node->meta[0] = '-';
			else if (xml->curr_node->meta[1] != '-')
				xml->curr_node->meta[1] = '-';
		} else {
			if (xml->curr_node->meta[0] == '-')
				xml->curr_node->meta[0] = 0;
			if (xml->curr_node->meta[1] == '-')
				xml->curr_node->meta[1] = 0;
		}

		data++;
	}

	return data;
}
Beispiel #6
0
static const char *xml_meta_attr_value(ACL_XML_ATTR *attr, const char *data)
{
	int   ch;

	SKIP_SPACE(data);
	if (*data == 0)
		return data;
	if (IS_QUOTE(*data))
		attr->quote = *data++;

	while ((ch = *data) != 0) {
		if (attr->backslash) {
			if (ch == 'b')
				ADDCH(attr->value, '\b');
			else if (ch == 'f')
				ADDCH(attr->value, '\f');
			else if (ch == 'n')
				ADDCH(attr->value, '\n');
			else if (ch == 'r')
				ADDCH(attr->value, '\r');
			else if (ch == 't')
				ADDCH(attr->value, '\t');
			else
				ADDCH(attr->value, ch);
			attr->backslash = 0;
		} else if (ch == '\\') {
			if (attr->part_word) {
				ADDCH(attr->value, ch);
				attr->part_word = 0;
			} else
				attr->backslash = 1;
		} else if (attr->quote) {
			if (ch == attr->quote) {
				data++;
				break;
			}
			ADDCH(attr->value, ch);
		} else if (IS_SPACE(ch)) {
			data++;
			break;
		} else {
			ADDCH(attr->value, ch);
			if ((attr->node->xml->flag & ACL_XML_FLAG_PART_WORD)) {
				if (attr->part_word)
					attr->part_word = 0;
				else if (ch < 0)
					attr->part_word = 1;
			}
		}
		data++;
	}

	ACL_VSTRING_TERMINATE(attr->value);
	return data;
}
Beispiel #7
0
static const char *xml_parse_meta_text(ACL_XML *xml, const char *data)
{
	int   ch;

	if (LEN(xml->curr_node->text) == 0) {
		SKIP_SPACE(data);
	}

	while ((ch = *data) != 0) {
		if (xml->curr_node->quote) {
			if (ch == xml->curr_node->quote) {
				xml->curr_node->quote = 0;
			}
			ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
		} else if (IS_QUOTE(ch)) {
			if (xml->curr_node->quote == 0) {
				xml->curr_node->quote = ch;
			}
			ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
		} else if (ch == '<') {
			xml->curr_node->nlt++;
			ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
		} else if (ch == '>') {
			if (xml->curr_node->nlt == 0) {
				char *last;
				size_t off;

				data++;
				xml->curr_node->status = ACL_XML_S_MEND;
				if ((xml->curr_node->flag & ACL_XML_F_META_QM) == 0)
					break;

				last = acl_vstring_end(xml->curr_node->text) - 1;
				if (last < STR(xml->curr_node->text) || *last != '?')
					break;
				off = ACL_VSTRING_LEN(xml->curr_node->text) - 1;
				if (off == 0)
					break;
				ACL_VSTRING_AT_OFFSET(xml->curr_node->text, off);
				ACL_VSTRING_TERMINATE(xml->curr_node->text);
				xml_meta_attr(xml->curr_node);
				break;
			}
			xml->curr_node->nlt--;
			ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
		} else {
			ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
		}
		data++;
	}

	ACL_VSTRING_TERMINATE(xml->curr_node->text);
	return (data);
}
Beispiel #8
0
static const char *json_pair(ACL_JSON *json, const char *data)
{
	ACL_JSON_NODE *parent = acl_json_node_parent(json->curr_node);

	SKIP_SPACE(data);
	if (*data == 0)
		return NULL;

	acl_assert(parent);

	/* 如果当前字符为父结点的右分隔符,则表示父结点结束 */
	if (*data == parent->right_ch) {
		data++;  /* 去掉父结点的右分隔符 */

		if (parent == json->root) {
			/* 如果根结点分析结束则整个 json 分析完毕 */
			json->finish = 1;
			return NULL;
		}
		/* 弹出父结点 */
		json->curr_node = parent;
		/* 查询父结点的下一个兄弟结点 */
		json->status = ACL_JSON_S_NEXT;
		return data;
	}

	/* 为 '{' 或 '[' 时说明遇到了当前结点的子结点 */
	if (*data == '{') {
		data++;
		json->status = ACL_JSON_S_OBJ;
		return data;
	}
	else if (*data == '[') {
		data++;
		json->status = ACL_JSON_S_ARRAY;
		return data;
	}

	/* 如果标签名前有引号,记录下该引号 */
	if (IS_QUOTE(*data) && json->curr_node->quote == 0)
		json->curr_node->quote = *data++;

	json->curr_node->type = ACL_JSON_T_PAIR;
	json->status = ACL_JSON_S_TAG;

	return data;
}
Beispiel #9
0
static void clear_comments(CONF *conf, char *p)
	{
	for (;;)
		{
		if (IS_FCOMMENT(conf,*p))
			{
			*p='\0';
			return;
			}
		if (!IS_WS(conf,*p))
			{
			break;
			}
		p++;
		}

	for (;;)
		{
		if (IS_COMMENT(conf,*p))
			{
			*p='\0';
			return;
			}
		if (IS_DQUOTE(conf,*p))
			{
			p=scan_dquote(conf, p);
			continue;
			}
		if (IS_QUOTE(conf,*p))
			{
			p=scan_quote(conf, p);
			continue;
			}
		if (IS_ESC(conf,*p))
			{
			p=scan_esc(conf,p);
			continue;
			}
		if (IS_EOF(conf,*p))
			return;
		else
			p++;
		}
	}
Beispiel #10
0
static char *xml_meta_attr_value(ACL_XML2_ATTR *attr, char *data)
{
    ACL_XML2 *xml = attr->node->xml;
    int   ch;

    SKIP_SPACE(data);
    if (IS_QUOTE(*data))
        attr->quote = *data++;

    if (*data == 0)
        return data;

    if (attr->value == xml->addr)
        attr->value = data;

    while ((ch = *data) != 0) {
        if (attr->quote && ch == attr->quote) {
            attr->value_size = data - attr->value;
            *data++ = 0;
            break;
        } else if (IS_SPACE(ch)) {
            attr->value_size = data - attr->value;
            *data++ = 0;
            break;
        }

        data++;
    }

    if ((xml->flag & ACL_XML2_FLAG_XML_DECODE) && attr->value_size > 0
            && xml->len > 0)
    {
        const char *ptr = attr->value;

        attr->value = xml->ptr;
        (void) acl_xml_decode2(ptr, &xml->ptr, &xml->len);
        attr->value_size = xml->ptr - attr->value - 1;
    }

    return data;
}
Beispiel #11
0
/*
** Function that gets the lexical type
** of a requested element (always symbolized
** by two chars in order to fit to || or && etc.
*/
t_lextype	get_lextype(char a, char b, char c)
{
  t_lextype	lextype;

  lextype = WORD;
  if (is_delim(b, c))
    lextype = DELIM;
  else if (is_redirection(b, c))
    lextype = REDIR;
  else if (is_and(b, c))
    lextype = AND;
  else if (IS_PAR(b))
    lextype = PAR;
  else if (IS_QUOTE(b) && a != '\\')
    lextype = QUOTE;
  else if (IS_DQUOTE(b) && a != '\\')
    lextype = DQUOTE;
  else if (IS_BQUOTE(b))
    lextype = BACKQUOTE;
  return (lextype);
}
Beispiel #12
0
static char *xml_meta_attr_value(ACL_XML2_ATTR *attr, char *data)
{
	ACL_XML2 *xml = attr->node->xml;
	int   ch;

	SKIP_SPACE(data);
	if (IS_QUOTE(*data))
		attr->quote = *data++;

	if (*data == 0)
		return data;

	if (attr->value == xml->dummy)
		attr->value = data;

	while ((ch = *data) != 0) {
		if (attr->quote && ch == attr->quote) {
			attr->value_size = data - attr->value;
			*data++ = 0;
			break;
		} else if (IS_SPACE(ch)) {
			attr->value_size = data - attr->value;
			*data++ = 0;
			break;
		}

		data++;
	}

	if ((xml->flag & ACL_XML2_FLAG_XML_DECODE) && attr->value_size > 0) {
		const char *ptr = attr->value;

		attr->value = END(xml);
		(void) acl_xml_decode(ptr, xml->vbuf);
		attr->value_size = END(xml) - attr->value;
		ADD(xml, '\0');  /* skip one byte */
	}

	return data;
}
Beispiel #13
0
static const char *xml_parse_attr_val(ACL_XML2 *xml, const char *data)
{
    int   ch;
    ACL_XML2_ATTR *attr = xml->curr_node->curr_attr;

    if (attr->value == xml->addr && !attr->quote) {
        SKIP_SPACE(data);
        if (IS_QUOTE(*data))
            attr->quote = *data++;
    }

    if (*data == 0)
        return data;

    if (attr->value == xml->addr)
        attr->value = xml->ptr;

    while ((ch = *data) != 0) {
        if (attr->quote) {
            if (ch == attr->quote) {
                if (xml->len < MIN_LEN)
                    return data;
                data++;
                xml->len--;
                attr->value_size = xml->ptr - attr->value;
                *xml->ptr++ = 0;
                xml->curr_node->status = ACL_XML2_S_ATTR;
                xml->curr_node->last_ch = ch;
                break;
            }

            if (xml->len < MIN_LEN)
                return data;
            xml->len--;
            *xml->ptr++ = ch;
            xml->curr_node->last_ch = ch;
        } else if (ch == '>') {
            if (xml->len < MIN_LEN)
                return data;
            data++;
            xml->len--;
            attr->value_size = xml->ptr - attr->value;
            *xml->ptr++ = 0;

            xml_parse_check_self_closed(xml);

            if ((xml->curr_node->flag & ACL_XML2_F_SELF_CL)
                    && xml->curr_node->last_ch == '/')
            {
                if (attr->value_size >= 2)
                    attr->value[attr->value_size - 2] = 0;
                xml->curr_node->status = ACL_XML2_S_RGT;
            } else
                xml->curr_node->status = ACL_XML2_S_LGT;
            break;
        } else if (IS_SPACE(ch)) {
            if (xml->len < MIN_LEN)
                return data;
            data++;
            xml->len--;
            attr->value_size = xml->ptr - attr->value;
            *xml->ptr++ = 0;
            xml->curr_node->status = ACL_XML2_S_ATTR;
            xml->curr_node->last_ch = ch;
            break;
        } else {
            if (xml->len < MIN_LEN)
                return data;
            xml->len--;
            *xml->ptr++ = ch;
            xml->curr_node->last_ch = ch;
        }

        data++;
    }

    /* 说明属性值还未解析完,需要继续解析 */
    if (xml->curr_node->status == ACL_XML2_S_AVAL)
        return data;

    /* 当状态发生改变时,则说明属性值已经完毕 */

    if ((xml->flag & ACL_XML2_FLAG_XML_DECODE) && attr->value_size > 1
            && xml->len > 0)
    {
        const char *val = attr->value;

        attr->value = xml->ptr;
        (void) acl_xml_decode2(val, &xml->ptr, &xml->len);
        attr->value_size = xml->ptr - attr->value - 1;
    }

    /* 将该标签ID号映射至哈希表中,以便于快速查询 */
    if (IS_ID(attr->name) && *attr->value != 0) {
        const char *ptr = attr->value;

        /* 防止重复ID被插入现象 */
        if (acl_htable_find(xml->id_table, ptr) == NULL) {
            acl_htable_enter(xml->id_table, ptr, attr);

            /* 当该属性被加入哈希表后才会赋于节点 id */
            xml->curr_node->id = attr->value;
        }
    }

    /* 必须将该节点的当前属性对象置空,以便于继续解析时
     * 可以创建新的属性对象
     */
    xml->curr_node->curr_attr = NULL;

    return data;
}
Beispiel #14
0
static int str_copy(CONF *conf, char *section, char **pto, char *from)
{
    int q, r, rr = 0, to = 0, len = 0;
    char *s, *e, *rp, *p, *rrp, *np, *cp, v;
    BUF_MEM *buf;

    if ((buf = BUF_MEM_new()) == NULL)
        return 0;

    len = strlen(from) + 1;
    if (!BUF_MEM_grow(buf, len))
        goto err;

    for (;;) {
        if (IS_QUOTE(conf, *from)) {
            q = *from;
            from++;
            while (!IS_EOF(conf, *from) && (*from != q)) {
                if (IS_ESC(conf, *from)) {
                    from++;
                    if (IS_EOF(conf, *from))
                        break;
                }
                buf->data[to++] = *(from++);
            }
            if (*from == q)
                from++;
        } else if (IS_DQUOTE(conf, *from)) {
            q = *from;
            from++;
            while (!IS_EOF(conf, *from)) {
                if (*from == q) {
                    if (*(from + 1) == q) {
                        from++;
                    } else {
                        break;
                    }
                }
                buf->data[to++] = *(from++);
            }
            if (*from == q)
                from++;
        } else if (IS_ESC(conf, *from)) {
            from++;
            v = *(from++);
            if (IS_EOF(conf, v))
                break;
            else if (v == 'r')
                v = '\r';
            else if (v == 'n')
                v = '\n';
            else if (v == 'b')
                v = '\b';
            else if (v == 't')
                v = '\t';
            buf->data[to++] = v;
        } else if (IS_EOF(conf, *from))
            break;
        else if (*from == '$') {
            size_t newsize;

            /* try to expand it */
            rrp = NULL;
            s = &(from[1]);
            if (*s == '{')
                q = '}';
            else if (*s == '(')
                q = ')';
            else
                q = 0;

            if (q)
                s++;
            cp = section;
            e = np = s;
            while (IS_ALNUM(conf, *e))
                e++;
            if ((e[0] == ':') && (e[1] == ':')) {
                cp = np;
                rrp = e;
                rr = *e;
                *rrp = '\0';
                e += 2;
                np = e;
                while (IS_ALNUM(conf, *e))
                    e++;
            }
            r = *e;
            *e = '\0';
            rp = e;
            if (q) {
                if (r != q) {
                    CONFerr(CONF_F_STR_COPY, CONF_R_NO_CLOSE_BRACE);
                    goto err;
                }
                e++;
            }
            /*-
             * So at this point we have
             * np which is the start of the name string which is
             *   '\0' terminated.
             * cp which is the start of the section string which is
             *   '\0' terminated.
             * e is the 'next point after'.
             * r and rr are the chars replaced by the '\0'
             * rp and rrp is where 'r' and 'rr' came from.
             */
            p = _CONF_get_string(conf, cp, np);
            if (rrp != NULL)
                *rrp = rr;
            *rp = r;
            if (p == NULL) {
                CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_HAS_NO_VALUE);
                goto err;
            }
            newsize = strlen(p) + buf->length - (e - from);
            if (newsize > MAX_CONF_VALUE_LENGTH) {
                CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_EXPANSION_TOO_LONG);
                goto err;
            }
            if (!BUF_MEM_grow_clean(buf, newsize)) {
                CONFerr(CONF_F_STR_COPY, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            while (*p)
                buf->data[to++] = *(p++);

            /*
             * Since we change the pointer 'from', we also have to change the
             * perceived length of the string it points at.  /RL
             */
            len -= e - from;
            from = e;

            /*
             * In case there were no braces or parenthesis around the
             * variable reference, we have to put back the character that was
             * replaced with a '\0'.  /RL
             */
            *rp = r;
        } else
            buf->data[to++] = *(from++);
    }
    buf->data[to] = '\0';
    OPENSSL_free(*pto);
    *pto = buf->data;
    OPENSSL_free(buf);
    return 1;
 err:
    BUF_MEM_free(buf);
    return 0;
}
Beispiel #15
0
static const char *xml_parse_meta_text(ACL_XML2 *xml, const char *data)
{
    int   ch;

    if (xml->curr_node->text == xml->addr)
        SKIP_SPACE(data);

    if (*data == 0)
        return data;

    if (xml->curr_node->text == xml->addr)
        xml->curr_node->text = xml->ptr;

    while ((ch = *data) != 0) {
        if (xml->curr_node->quote) {
            if (xml->len < MIN_LEN)
                return data;
            if (ch == xml->curr_node->quote)
                xml->curr_node->quote = 0;
            xml->len--;
            *xml->ptr++ = ch;
        } else if (IS_QUOTE(ch)) {
            if (xml->len < MIN_LEN)
                return data;
            if (xml->curr_node->quote == 0)
                xml->curr_node->quote = ch;
            xml->len--;
            *xml->ptr++ = ch;
        } else if (ch == '<') {
            if (xml->len < MIN_LEN)
                return data;
            xml->curr_node->nlt++;
            xml->len--;
            *xml->ptr++ = ch;
        } else if (ch != '>') {
            if (xml->len < MIN_LEN)
                return data;
            xml->len--;
            *xml->ptr++ = ch;
        } else if (xml->curr_node->nlt == 0) {
            char *last;

            if (xml->len < MIN_LEN)
                return data;

            data++;
            xml->len--;
            xml->curr_node->text_size = xml->ptr -
                                        xml->curr_node->text;
            *xml->ptr++ = 0;
            xml->curr_node->status = ACL_XML2_S_MEND;

            if ((xml->curr_node->flag & ACL_XML2_F_META_QM) == 0)
                break;

            last = xml->ptr - 1;
            while (last > xml->curr_node->text) {
                if (*last == '?') {
                    *last = 0;
                    xml->curr_node->text_size = last -
                                                xml->curr_node->text;
                    break;
                }
                last--;
            }
            if (last == xml->curr_node->text)
                break;

            xml_meta_attr(xml->curr_node);
            break;
        } else {
            if (xml->len < MIN_LEN)
                return data;
            xml->curr_node->nlt--;
            xml->len--;
            *xml->ptr++ = ch;
        }

        data++;
    }

    if (xml->curr_node->status == ACL_XML2_S_MEND
            && (xml->flag & ACL_XML2_FLAG_XML_DECODE)
            && xml->curr_node->text_size > 0 && xml->len > 0)
    {
        const char *txt = xml->curr_node->text;

        xml->curr_node->text = xml->ptr;
        (void) acl_xml_decode2(txt, &xml->ptr, &xml->len);
        xml->curr_node->text_size = xml->ptr
                                    - xml->curr_node->text - 1;
    }

    return data;
}
Beispiel #16
0
static const char *xml_parse_meta_comment(ACL_XML2 *xml, const char *data)
{
    int   ch;

    if (xml->curr_node->text == xml->addr)
        SKIP_SPACE(data);

    if (*data == 0)
        return data;

    if (xml->curr_node->text == xml->addr)
        xml->curr_node->text = xml->ptr;

    while ((ch = *data) != 0) {
        if (xml->curr_node->quote) {
            if (xml->len < MIN_LEN)
                return data;
            if (ch == xml->curr_node->quote)
                xml->curr_node->quote = 0;
            else {
                xml->len--;
                *xml->ptr++ = ch;
            }
        } else if (IS_QUOTE(ch)) {
            if (xml->len < MIN_LEN)
                return data;
            if (xml->curr_node->quote == 0)
                xml->curr_node->quote = ch;
            else {
                xml->len--;
                *xml->ptr++ = ch;
            }
        } else if (ch == '<') {
            if (xml->len < MIN_LEN)
                return data;
            xml->curr_node->nlt++;
            xml->len--;
            *xml->ptr++ = ch;
        } else if (ch == '>') {
            if (xml->curr_node->nlt == 0
                    && xml->curr_node->meta[0] == '-'
                    && xml->curr_node->meta[1] == '-')
            {
                if (xml->len < MIN_LEN)
                    return data;

                data++;
                xml->len--;
                xml->curr_node->text_size = xml->ptr -
                                            xml->curr_node->text;
                *xml->ptr++ = 0;
                xml->curr_node->status = ACL_XML2_S_MEND;
                break;
            }

            xml->curr_node->nlt--;

            if (xml->len < MIN_LEN)
                return data;
            xml->len--;
            *xml->ptr++ = ch;
        } else if (xml->curr_node->nlt > 0) {
            if (xml->len < MIN_LEN)
                return data;
            xml->len--;
            *xml->ptr++ = ch;
        } else if (ch == '-') {
            if (xml->curr_node->meta[0] != '-')
                xml->curr_node->meta[0] = '-';
            else if (xml->curr_node->meta[1] != '-')
                xml->curr_node->meta[1] = '-';
        } else {
            if (xml->curr_node->meta[0] == '-') {
                if (xml->len < MIN_LEN)
                    return data;
                xml->len--;
                *xml->ptr++ = '-';
                xml->curr_node->meta[0] = 0;
            }
            if (xml->curr_node->meta[1] == '-') {
                if (xml->len < MIN_LEN)
                    return data;
                xml->len--;
                *xml->ptr++ = '-';
                xml->curr_node->meta[1] = 0;
            }

            if (xml->len < MIN_LEN)
                return data;
            xml->len--;
            *xml->ptr++ = ch;
        }

        data++;
    }

    if (xml->curr_node->status == ACL_XML2_S_MEND
            && (xml->flag & ACL_XML2_FLAG_XML_DECODE)
            && xml->curr_node->text_size > 0
            && xml->len > 0)
    {
        const char *txt = xml->curr_node->text;

        xml->curr_node->text = xml->ptr;
        (void) acl_xml_decode2(txt, &xml->ptr, &xml->len);
        xml->curr_node->text_size = xml->ptr
                                    - xml->curr_node->text - 1;
    }

    return data;
}
Beispiel #17
0
short int php_tmpl_pre_parse_config(t_template* tmpl) {
zval		*zparam;

char	*nam, *val;
uint	nam_len, val_len;

uchar	quote;
register char	*p;
register char	*start;

	nam = (char*)emalloc(TMPL_MAX_TAG_LEN); nam_len = 0;
	val = (char*)emalloc(TMPL_MAX_TAG_LEN); val_len = 0;
	MAKE_STD_ZVAL(zparam); array_init(zparam);

	sprintf(nam, "<%s", TMPL_CONFIG_TAG_NAME);
	nam_len = strlen(nam);

	if(!(p = strstrl_ex(ZV(tmpl->original), ZL(tmpl->original), nam, nam_len))) {
		TMPL_PRE_PARSE_CONFIG_CLEANUP;
		return SUCCESS;
	}

	start = p;
	p += nam_len;

	while(1) {

		/* skip delimiters and check for end of the tag */
		while(*p && '>' != *p && IS_DELIM(*p)) p++;
		if(!(*p) || '>' == *p) {	/* end of tag */
			if('>' == *p) {			/* hide this tag from result output */
				for(++p; *p;) *(start++) = *(++p);
				*start = 0;
				ZL(tmpl->original) -= (p-start);
			}
			break;
		}

		/* get parameter name */
		for(nam_len=0; *p && nam_len < TMPL_MAX_TAG_LEN && !IS_DELIM(*p) && '=' != *p; p++) nam[nam_len++] = *p;
		if(!(*p)) break; else nam[nam_len] = 0;

		if('=' != *p) {
			php_error(E_ERROR, "Invalid configuration tag parameter in template (line:%d)", php_tmpl_line_num(tmpl, p));
			TMPL_PRE_PARSE_CONFIG_CLEANUP;
			return FAILURE;
		}

		/* check if the value is quoted and get the value */
		p++;
		quote = IS_QUOTE(*p) ? *(p++) : 0;

		for(val_len=0; *p && val_len < TMPL_MAX_TAG_LEN && quote ? quote != *p : !IS_DELIM(*p); p++) val[val_len++] = *p;
		if(!(*p)) break; else val[val_len] = 0;

		if(quote && quote != *p) {
			php_error(E_ERROR, "Invalid parameter value in configuration tag in template (line:%d)", php_tmpl_line_num(tmpl, p));
			TMPL_PRE_PARSE_CONFIG_CLEANUP;
			return FAILURE;
		}
		if(quote) p++;

		add_assoc_stringl(zparam, nam, val, val_len, 1);
	}

	php_tmpl_process_param_array(tmpl, zparam);

	TMPL_PRE_PARSE_CONFIG_CLEANUP;
	return SUCCESS;
}
Beispiel #18
0
static const char *xml_parse_meta_comment(ACL_XML2 *xml, const char *data)
{
	int   ch;

	if (xml->curr_node->text == xml->dummy)
		SKIP_SPACE(data);

	if (*data == 0)
		return data;

	if (xml->curr_node->text == xml->dummy)
		xml->curr_node->text = END(xml);

	while ((ch = *data) != 0) {
		if (xml->curr_node->quote) {
			if (NO_SPACE(xml))
				return data;
			if (ch == xml->curr_node->quote)
				xml->curr_node->quote = 0;
			else
				ADD(xml, ch);
		} else if (IS_QUOTE(ch)) {
			if (NO_SPACE(xml))
				return data;
			if (xml->curr_node->quote == 0)
				xml->curr_node->quote = ch;
			else
				ADD(xml, ch);
		} else if (ch == '<') {
			if (NO_SPACE(xml))
				return data;
			xml->curr_node->nlt++;
			ADD(xml, ch);
		} else if (ch == '>') {
			if (xml->curr_node->nlt == 0
				&& xml->curr_node->meta[0] == '-'
				&& xml->curr_node->meta[1] == '-')
			{
				if (NO_SPACE(xml))
					return data;

				data++;
				xml->curr_node->text_size =
					END(xml) - xml->curr_node->text;
				ADD(xml, '\0');
				xml->curr_node->status = ACL_XML2_S_MEND;
				break;
			}

			xml->curr_node->nlt--;

			if (NO_SPACE(xml))
				return data;
			ADD(xml, ch);
		} else if (xml->curr_node->nlt > 0) {
			if (NO_SPACE(xml))
				return data;
			ADD(xml, ch);
		} else if (ch == '-') {
			if (xml->curr_node->meta[0] != '-')
				xml->curr_node->meta[0] = '-';
			else if (xml->curr_node->meta[1] != '-')
				xml->curr_node->meta[1] = '-';
		} else {
			if (xml->curr_node->meta[0] == '-') {
				if (NO_SPACE(xml))
					return data;
				ADD(xml, '-');
				xml->curr_node->meta[0] = 0;
			}
			if (xml->curr_node->meta[1] == '-') {
				if (NO_SPACE(xml))
					return data;
				ADD(xml, '-');
				xml->curr_node->meta[1] = 0;
			}

			if (NO_SPACE(xml))
				return data;
			ADD(xml, ch);
		}

		data++;
	}

	if (xml->curr_node->status == ACL_XML2_S_MEND
		&& (xml->flag & ACL_XML2_FLAG_XML_DECODE)
		&& xml->curr_node->text_size > 0
		&& !NO_SPACE(xml))
	{
		const char *txt = xml->curr_node->text;

		xml->curr_node->text = END(xml);
		(void) acl_xml_decode(txt, xml->vbuf);
		xml->curr_node->text_size = END(xml) - xml->curr_node->text;
		ADD(xml, '\0');  /* skip one byte */
	}

	return data;
}
Beispiel #19
0
int cfg_get_token(cfg_token_t* token, cfg_parser_t* st, unsigned int flags)
{
	static int look_ahead = EOF;
	int c;
	enum st state;

	state = ST_S;
	
	token->val.s = token->buf;
	token->val.len = 0;

	if (look_ahead != EOF) {
		c = look_ahead;
		look_ahead = EOF;
	} else {
		READ_CHAR;
	}

	while(c != EOF) {
		switch(state) {
		case ST_S:
			if (flags & CFG_EXTENDED_ALPHA) {
				if (IS_WHITESPACE(c)) {
					     /* Do nothing */
				} else if (IS_ALPHA(c) ||
					   IS_ESCAPE(c) ||
					   IS_DELIM(c)) {
					PUSH(c);
					state = ST_A;
				} else if (IS_QUOTE(c)) {
					state = ST_Q;
				} else if (IS_COMMENT(c)) {
					state = ST_C;
				} else if (IS_EOL(c)) {
					PUSH(c);
					RETURN(c);
				} else {
					ERR("%s:%d:%d: Invalid character 0x%x\n", 
					    st->file, st->line, st->col, c);
					return -1;
				}
			} else {
				if (IS_WHITESPACE(c)) {
					     /* Do nothing */
				} else if (IS_ALPHA(c)) {
					PUSH(c);
					state = ST_A;
				} else if (IS_QUOTE(c)) {
					state = ST_Q;
				} else if (IS_COMMENT(c)) {
					state = ST_C;
				} else if (IS_ESCAPE(c)) {
					state = ST_E;
				} else if (IS_DELIM(c) || IS_EOL(c)) {
					PUSH(c);
					RETURN(c);
				} else {
					ERR("%s:%d:%d: Invalid character 0x%x\n", 
					    st->file, st->line, st->col, c);
					return -1;
				}
			}
			break;

		case ST_A:
			if (flags & CFG_EXTENDED_ALPHA) {
				if (IS_ALPHA(c) ||
				    IS_DELIM(c) ||
				    IS_QUOTE(c)) {
					PUSH(c);
				} else if (IS_ESCAPE(c)) {
					state = ST_AE;
				} else if (IS_COMMENT(c) || IS_EOL(c) || IS_WHITESPACE(c)) {
					look_ahead = c;
					RETURN(CFG_TOKEN_ALPHA);
				} else {
					ERR("%s:%d:%d: Invalid character 0x%x\n", 
					    st->file, st->line, st->col, c);
					return -1;
				}
			} else {
				if (IS_ALPHA(c)) {
					PUSH(c);
				} else if (IS_ESCAPE(c)) {
					state = ST_AE;
				} else if (IS_WHITESPACE(c) ||
					   IS_DELIM(c) ||
					   IS_QUOTE(c) ||
					   IS_COMMENT(c) ||
					   IS_EOL(c)) {
					look_ahead = c;
					RETURN(CFG_TOKEN_ALPHA);
				} else {
					ERR("%s:%d:%d: Invalid character 0x%x\n", 
					    st->file, st->line, st->col, c);
					return -1;
				}
			}
			break;

		case ST_AE:
			if (IS_COMMENT(c) ||
			    IS_QUOTE(c) ||
			    IS_ESCAPE(c)) {
				PUSH(c);
			} else if (c == 'r') {
				PUSH('\r');
			} else if (c == 'n') {
				PUSH('\n');
			} else if (c == 't') {
				PUSH('\t');
			} else if (c == ' ') {
				PUSH(' ');
			} else if (IS_EOL(c)) {
				     /* Do nothing */
			} else {
				ERR("%s:%d:%d: Unsupported escape character 0x%x\n", 
				    st->file, st->line, st->col, c);
				return -1;
			}
			state = ST_A;
			break;

		case ST_Q:
			if (IS_QUOTE(c)) {
				RETURN(CFG_TOKEN_STRING);
			} else if (IS_ESCAPE(c)) {
				state = ST_QE;
				break;
			} else {
				PUSH(c);
			}
			break;

		case ST_QE:
			if (IS_ESCAPE(c) ||
			    IS_QUOTE(c)) {
				PUSH(c);
			} else if (c == 'n') {
				PUSH('\n');
			} else if (c == 'r') {
				PUSH('\r');
			} else if (c == 't') {
				PUSH('\t');
			} else if (IS_EOL(c)) {
				     /* Do nothing */
			} else {
				ERR("%s:%d:%d: Unsupported escape character 0x%x\n", 
				    st->file, st->line, st->col, c);
				return -1;
			}
			state = ST_Q;
			break;

		case ST_C:
			if (IS_ESCAPE(c)) {
				state = ST_CE;
			} else if (IS_EOL(c)) {
				state = ST_S;
				continue; /* Do not read a new char, return EOL */
			} else {
				     /* Do nothing */
			}
			break;

		case ST_CE:
			state = ST_C;
			break;

		case ST_E:
			if (IS_COMMENT(c) ||
			    IS_QUOTE(c) ||
			    IS_ESCAPE(c)) {
				PUSH(c);
				RETURN(c);
			} else if (c == 'r') {
				PUSH('\r');
				RETURN('\r');
			} else if (c == 'n') {
				PUSH('\n');
				RETURN('\n');
			} else if (c == 't') {
				PUSH('\t');
				RETURN('\t');
			} else if (c == ' ') {
				PUSH(' ');
				RETURN(' ');
			} else if (IS_EOL(c)) {
				     /* Escped eol means no eol */
				state = ST_S;
			} else {
				ERR("%s:%d:%d: Unsupported escape character 0x%x\n", 
				    st->file, st->line, st->col, c);
				return -1;
			}
			break;
		}

		READ_CHAR;
	};

	switch(state) {
	case ST_S: 
	case ST_C:
	case ST_CE:
		return 1;

	case ST_A:
		RETURN(CFG_TOKEN_ALPHA);

	case ST_Q:
		ERR("%s:%d:%d: Premature end of file, missing closing quote in"
			" string constant\n", st->file, st->line, st->col);
		return -1;

	case ST_QE:
	case ST_E:
	case ST_AE:
		ERR("%s:%d:%d: Premature end of file, missing escaped character\n", 
		    st->file, st->line, st->col);
		return -1;
	}
	BUG("%s:%d:%d: Invalid state %d\n",
		st->file, st->line, st->col, state);
	return -1;
}
Beispiel #20
0
Datei: tok.c Projekt: Limsik/e17
spif_bool_t
spif_tok_eval(spif_tok_t self)
{
    const char *pstr, *delim = NULL;
    spif_str_t tmp;
    char quote;
    size_t len;

    ASSERT_RVAL(!SPIF_TOK_ISNULL(self), FALSE);
    REQUIRE_RVAL(!SPIF_STR_ISNULL(self->src), FALSE);

    pstr = (const char *) SPIF_STR_STR(SPIF_STR(self->src));
    len = spif_str_get_len(SPIF_STR(self->src));

    if (!SPIF_STR_ISNULL(self->sep)) {
        delim = (const char *) SPIF_STR_STR(SPIF_STR(self->sep));
    }

    if (!SPIF_LIST_ISNULL(self->tokens)) {
        SPIF_LIST_DEL(self->tokens);
    }
    self->tokens = SPIF_LIST_NEW(dlinked_list);

    /* Before we do anything, skip leading "whitespace." */
    for (; *pstr && IS_DELIM(*pstr); pstr++);

    /* The outermost for loop is where we traverse the string.  Each new
       word brings us back to the top where we resize our string list. */
    for (quote = 0; *pstr; ) {
        tmp = spif_str_new_from_buff(SPIF_CHARPTR(""), len);
        spif_str_clear(tmp, 0);

        /* This for loop is where we process each character. */
        for (; *pstr && (quote || !IS_DELIM(*pstr));) {
            if (*pstr == self->dquote || *pstr == self->quote) {
                /* It's a quote character, so set or reset the quote variable. */
                if (quote) {
                    if (quote == *pstr) {
                        quote = 0;
                    } else {
                        /* It's a single quote inside double quotes, or vice versa.  Leave it alone. */
                        spif_str_append_char(tmp, *pstr);
                    }
                } else {
                    quote = *pstr;
                }
                pstr++;
            } else {
                /* Handle any backslashes that are escaping delimiters or quotes. */
                if ((*pstr == self->escape) && (IS_DELIM(*(pstr + 1)) || IS_QUOTE(*(pstr + 1)))) {
                    /* Incrementing pstr here moves us past the backslash so that the line
                       below will copy the next character to the new token, no questions asked. */
                    pstr++;
                }
                spif_str_append_char(tmp, *pstr++);
            }
        }

        /* Reallocate the new string to be just the right size. */
        spif_str_trim(tmp);
        len -= spif_str_get_len(tmp);

        /* Add it to the list */
        SPIF_LIST_APPEND(self->tokens, tmp);

        /* Move past any trailing "whitespace." */
        for (; *pstr && IS_DELIM(*pstr); pstr++);
    }
    return TRUE;
}
Beispiel #21
0
spif_charptr_t *
spiftool_split(const spif_charptr_t delim, const spif_charptr_t str)
{
    spif_charptr_t *slist;
    register spif_charptr_t pstr;
    register spif_charptr_t pdest;
    char quote = 0;
    unsigned short cnt = 0;
    unsigned long len;

    REQUIRE_RVAL(str != NULL, (spif_charptr_t *) NULL);

    if (!(slist = (spif_charptr_t *)MALLOC(sizeof(spif_charptr_t)))) {
        libast_print_error("split():  Unable to allocate memory -- %s\n", strerror(errno));
        return ((spif_charptr_t *) NULL);
    }

    /* Before we do anything, skip leading "whitespace." */
    for (pstr = (spif_charptr_t) str; *pstr && IS_DELIM(*pstr); pstr++);

    /* The outermost for loop is where we traverse the string.  Each new
       word brings us back to the top where we resize our string list. */
    for (; *pstr; cnt++) {
        /* First, resize the list to two bigger than our count.  Why two?
           One for the string we're about to do, and one for a trailing NULL. */
        if (!(slist = (spif_charptr_t *)REALLOC(slist, sizeof(spif_charptr_t) * (cnt + 2)))) {
            libast_print_error("split():  Unable to allocate memory -- %s\n", strerror(errno));
            return ((spif_charptr_t *) NULL);
        }

        /* The string we're about to create can't possibly be larger than the remainder
           of the string we have yet to parse, so allocate that much space to start. */
        len = strlen((char *) pstr) + 1;
        if (!(slist[cnt] = (spif_charptr_t)MALLOC(len))) {
            libast_print_error("split():  Unable to allocate memory -- %s.\n", strerror(errno));
            return ((spif_charptr_t *) NULL);
        }
        pdest = slist[cnt];

        /* This for loop is where we process each character. */
        for (; *pstr && (quote || !IS_DELIM(*pstr));) {
            if (*pstr == '\"' || *pstr == '\'') {
                /* It's a quote character, so set or reset the quote variable. */
                if (quote) {
                    if (quote == *pstr) {
                        quote = 0;
                    } else {
                        /* It's a single quote inside double quotes, or vice versa.  Leave it alone. */
                        *pdest++ = *pstr++;
                    }
                } else {
                    quote = *pstr;
                }
                pstr++;
            } else {
                /* Handle any backslashes that are escaping delimiters or quotes. */
                if ((*pstr == '\\') && (IS_DELIM(*(pstr + 1)) || IS_QUOTE(*(pstr + 1)))) {
                    /* Incrementing pstr here moves us past the backslash so that the line
                       below will copy the next character to the new token, no questions asked. */
                    pstr++;
                }
                *pdest++ = *pstr++;
            }
        }
        /* Add the trailing \0 to terminate the new string. */
        *pdest = 0;

        /* Reallocate the new string to be just the right size. */
        len = strlen((char *) slist[cnt]) + 1;
        slist[cnt] = (spif_charptr_t) REALLOC(slist[cnt], len);

        /* Move past any trailing "whitespace." */
        for (; *pstr && IS_DELIM(*pstr); pstr++);
    }
    if (cnt == 0) {
        FREE(slist);
        return NULL;
    } else {
        /* The last element of slist[] should be NULL. */
        slist[cnt] = 0;
        return slist;
    }
}
Beispiel #22
0
static char *xml_parse_attr_val(ACL_XML3 *xml, char *data)
{
	int   ch;
	ACL_XML3_ATTR *attr = xml->curr_node->curr_attr;

	if (attr->value == xml->addr && !attr->quote) {
		SKIP_SPACE(data);
		if (IS_QUOTE(*data))
			attr->quote = *data++;
	}

	if (*data == 0)
		return data;

	if (attr->value == xml->addr)
		attr->value = data;

	while ((ch = *data) != 0) {
		if (attr->quote) {
			if (ch == attr->quote) {
				attr->value_size = data - attr->value;
				xml->curr_node->status = ACL_XML3_S_ATTR;
				xml->curr_node->last_ch = ch;
				*data++ = 0;
				break;
			}

			xml->curr_node->last_ch = ch;
		} else if (ch == '>') {
			if (attr->value_size == 0)
				attr->value_size = data - attr->value;
			*data++ = 0;

			xml_parse_check_self_closed(xml);

			if ((xml->curr_node->flag & ACL_XML3_F_SELF_CL)
				&& xml->curr_node->last_ch == '/')
			{
				if (attr->value_size >= 2)
					attr->value[attr->value_size - 2] = 0;
				xml->curr_node->status = ACL_XML3_S_RGT;
			} else
				xml->curr_node->status = ACL_XML3_S_LGT;
			break;
		} else if (IS_SPACE(ch)) {
			attr->value_size = data - attr->value;
			xml->curr_node->status = ACL_XML3_S_ATTR;
			xml->curr_node->last_ch = ch;
			*data++ = 0;
			break;
		} else
			xml->curr_node->last_ch = ch;

		data++;
	}

	/* 当状态发生改变时,则说明属性值已经完毕 */
	if (xml->curr_node->status != ACL_XML3_S_AVAL) {
		/* 将该标签ID号映射至哈希表中,以便于快速查询 */
		if (IS_ID(attr->name) && *attr->value != 0) {
			char *ptr = attr->value;

			/* 防止重复ID被插入现象 */
			if (acl_htable_find(xml->id_table, ptr) == NULL) {
				acl_htable_enter(xml->id_table, ptr, attr);

				/* 当该属性被加入哈希表后才会赋于节点 id */
				xml->curr_node->id = attr->value;
			}
		}

		/* 必须将该节点的当前属性对象置空,以便于继续解析时
		 * 可以创建新的属性对象
		 */
		xml->curr_node->curr_attr = NULL;
	}

	return data;
}
Beispiel #23
0
static const char *xml_parse_meta_comment(ACL_XML *xml, const char *data)
{
	int   ch;

	if (LEN(xml->curr_node->text) == 0) {
		SKIP_SPACE(data);
	}

	while ((ch = *data) != 0) {
		if (xml->curr_node->quote) {
			if (ch == xml->curr_node->quote) {
				xml->curr_node->quote = 0;
			} else {
				ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
			}
		} else if (IS_QUOTE(ch)) {
			if (xml->curr_node->quote == 0) {
				xml->curr_node->quote = ch;
			} else {
				ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
			}
		} else if (ch == '<') {
			xml->curr_node->nlt++;
			ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
		} else if (ch == '>') {
			if (xml->curr_node->nlt == 0) {
				if (xml->curr_node->meta[0] == '-'
					&& xml->curr_node->meta[1] == '-')
				{
					data++;
					xml->curr_node->status = ACL_XML_S_MEND;
					break;
				}
			}
			xml->curr_node->nlt--;
			ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
		} else if (xml->curr_node->nlt > 0) {
			ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
		} else if (ch == '-') {
			if (xml->curr_node->meta[0] != '-') {
				xml->curr_node->meta[0] = '-';
			} else if (xml->curr_node->meta[1] != '-') {
				xml->curr_node->meta[1] = '-';
			}
		} else {
			if (xml->curr_node->meta[0] == '-') {
				ACL_VSTRING_ADDCH(xml->curr_node->text, '-');
				xml->curr_node->meta[0] = 0;
			}
			if (xml->curr_node->meta[1] == '-') {
				ACL_VSTRING_ADDCH(xml->curr_node->text, '-');
				xml->curr_node->meta[1] = 0;
			}
			ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
		}
		data++;
	}

	ACL_VSTRING_TERMINATE(xml->curr_node->text);
	return (data);
}
Beispiel #24
0
static const char *xml_parse_attr_val(ACL_XML *xml, const char *data)
{
	int   ch;
	ACL_XML_ATTR *attr = xml->curr_node->curr_attr;

	if (LEN(attr->value) == 0 && !attr->quote) {
		SKIP_SPACE(data);
		if (IS_QUOTE(*data)) {
			attr->quote = *data++;
		}
		if (*data == 0) {
			return (NULL);
		}
	}

	while ((ch = *data) != 0) {
		if (attr->backslash) {
			ACL_VSTRING_ADDCH(attr->value, ch);
			xml->curr_node->last_ch = ch;
			attr->backslash = 0;
		} else if (ch == '\\') {
			if (attr->part_word) {
				ACL_VSTRING_ADDCH(attr->value, ch);
				attr->part_word = 0;
			}
			else
				attr->backslash = 1;
		} else if (attr->quote) {
			if (ch == attr->quote) {
				xml->curr_node->status = ACL_XML_S_ATTR;
				xml->curr_node->last_ch = ch;
				data++;
				break;
			}
			ACL_VSTRING_ADDCH(attr->value, ch);
			xml->curr_node->last_ch = ch;
		} else if (ch == '>') {
			xml->curr_node->status = ACL_XML_S_LGT;
			xml_parse_check_self_closed(xml);
			data++;
			break;
		} else if (IS_SPACE(ch)) {
			xml->curr_node->status = ACL_XML_S_ATTR;
			xml->curr_node->last_ch = ch;
			data++;
			break;
		} else {
			ACL_VSTRING_ADDCH(attr->value, ch);
			xml->curr_node->last_ch = ch;

			if ((xml->flag & ACL_XML_FLAG_PART_WORD)) {
				/* 处理半个汉字的情形 */
				if (attr->part_word)
					attr->part_word = 0;
				else if (ch < 0)
					attr->part_word = 1;
			}
		}
		data++;
	}

	ACL_VSTRING_TERMINATE(attr->value);

	if (xml->curr_node->status != ACL_XML_S_AVAL) {
		/* 将该标签ID号映射至哈希表中,以便于快速查询 */
		if (IS_ID(STR(attr->name)) && LEN(attr->value) > 0) {
			const char *ptr = STR(attr->value);

			/* 防止重复ID被插入现象 */
			if (acl_htable_find(xml->id_table, ptr) == NULL) {
				acl_htable_enter(xml->id_table, ptr, attr);

				/* 只有当该属性被加入哈希表后才会赋于结点的 id */
				xml->curr_node->id = attr->value;
			}
		}

		/* 必须将该结点的当前属性对象置空,以便于继续解析时
		 * 可以创建新的属性对象
		 */
		xml->curr_node->curr_attr = NULL;
	}
	return (data);
}
Beispiel #25
0
static const char *xml_parse_meta_text(ACL_XML2 *xml, const char *data)
{
	int   ch;

	if (xml->curr_node->text == xml->dummy)
		SKIP_SPACE(data);

	if (*data == 0)
		return data;

	if (xml->curr_node->text == xml->dummy)
		xml->curr_node->text = END(xml);

	while ((ch = *data) != 0) {
		if (xml->curr_node->quote) {
			if (NO_SPACE(xml))
				return data;
			if (ch == xml->curr_node->quote)
				xml->curr_node->quote = 0;
			ADD(xml, ch);
		} else if (IS_QUOTE(ch)) {
			if (NO_SPACE(xml))
				return data;
			if (xml->curr_node->quote == 0)
				xml->curr_node->quote = ch;
			ADD(xml, ch);
		} else if (ch == '<') {
			if (NO_SPACE(xml))
				return data;
			xml->curr_node->nlt++;
			ADD(xml, ch);
		} else if (ch != '>') {
			if (NO_SPACE(xml))
				return data;
			ADD(xml, ch);
		} else if (xml->curr_node->nlt == 0) {
			char *last;

			if (NO_SPACE(xml))
				return data;

			xml->curr_node->text_size =
				END(xml) - xml->curr_node->text;
			xml->curr_node->status = ACL_XML2_S_MEND;

			ADD(xml, '\0');
			data++;

			if ((xml->curr_node->flag & ACL_XML2_F_META_QM) == 0)
				break;

			last = END(xml) - 1;
			while (last > xml->curr_node->text) {
				if (*last == '?') {
					*last = 0;
					xml->curr_node->text_size = last -
						xml->curr_node->text;
					break;
				}
				last--;
			}
			if (last == xml->curr_node->text)
				break;

			xml_meta_attr(xml->curr_node);
			break;
		} else {
			if (NO_SPACE(xml))
				return data;
			xml->curr_node->nlt--;
			ADD(xml, ch);
		}

		data++;
	}

	if (xml->curr_node->status == ACL_XML2_S_MEND
		&& (xml->flag & ACL_XML2_FLAG_XML_DECODE)
		&& xml->curr_node->text_size > 0 && !NO_SPACE(xml))
	{
		const char *txt = xml->curr_node->text;

		xml->curr_node->text = END(xml);
		(void) acl_xml_decode(txt, xml->vbuf);
		xml->curr_node->text_size = END(xml) - xml->curr_node->text;
		ADD(xml, '\0');  /* skip one byte */
	}

	return data;
}