Пример #1
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;
}
Пример #2
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);
}
Пример #3
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;
}
Пример #4
0
long
eval_mnemonic(GEN str, const char *tmplate)
{
  pari_sp av=avma;
  ulong retval = 0;
  const char *etmplate = NULL;
  const char *arg;

  if (typ(str)==t_INT) return itos(str);
  if (typ(str)!=t_STR) pari_err_TYPE("eval_mnemonic",str);

  arg=GSTR(str);
  etmplate = strchr(tmplate, '\n');
  if (!etmplate)
    etmplate = tmplate + strlen(tmplate);

  while (1)
  {
    long numarg;
    const char *e, *id;
    const char *negated;                /* action found with 'no'-ID */
    int negate;                 /* Arg has 'no' prefix removed */
    ulong l, action = 0, first = 1, singleton = 0;
    char *buf, *inibuf;
    static char b[80];

    while (isspace((int)*arg)) arg++;
    if (!*arg)
      break;
    e = arg;
    while (IS_ID(*e)) e++;
    /* Now the ID is whatever is between arg and e. */
    l = e - arg;
    if (l >= sizeof(b))
      pari_err(e_MISC,"id too long in a stringified flag");
    if (!l)                             /* Garbage after whitespace? */
      pari_err(e_MISC,"a stringified flag does not start with an id");
    strncpy(b, arg, l);
    b[l] = 0;
    arg = e;
    e = inibuf = buf = b;
    while (('0' <= *e) && (*e <= '9'))
      e++;
    if (*e == 0)
      pari_err(e_MISC,"numeric id in a stringified flag");
    negate = 0;
    negated = NULL;
find:
    id = tmplate;
    while ((id = strstr(id, buf)) && id < etmplate)
    {
      if (IS_ID(id[l])) {       /* We do not allow abbreviations yet */
        id += l;                /* False positive */
        continue;
      }
      if ((id >= tmplate + 2) && (IS_ID(id[-1])))
      {
        const char *s = id;

        if ( !negate && s >= tmplate+3
            && ((id[-1] == '_') || (id[-1] == '-')) )
          s--;
        /* Check whether we are preceeded by "no" */
        if ( negate             /* buf initially started with "no" */
            || (s < tmplate+2) || (s[-1] != 'o') || (s[-2] != 'n')
            || (s >= tmplate+3 && IS_ID(s[-3]))) {
          id += l;              /* False positive */
          continue;
        }
        /* Found noID in the template! */
        id += l;
        negated = id;
        continue;               /* Try to find without 'no'. */
      }
      /* Found as is */
      id += l;
      break;
    }
    if ( !id && !negated && !negate
        && (l > 2) && buf[0] == 'n' && buf[1] == 'o' ) {
      /* Try to find the flag without the prefix "no". */
      buf += 2; l -= 2;
      if ((buf[0] == '_') || (buf[0] == '-')) { buf++; l--; }
      negate = 1;
      if (buf[0])
        goto find;
    }
    if (!id && negated) /* Negated and AS_IS forms, prefer AS_IS */
    {
      id = negated;     /* Otherwise, use negated form */
      negate = 1;
    }
    if (!id)
      pari_err(e_MISC,"Unrecognized id '%s' in a stringified flag", inibuf);
    if (singleton && !first)
      pari_err(e_MISC,"Singleton id non-single in a stringified flag");
    if (id[0] == '=') {
      if (negate)
        pari_err(e_MISC,"Cannot negate id=value in a stringified flag");
      if (!first)
        pari_err(e_MISC,"Assign action should be first in a stringified flag");
      action = A_ACTION_ASSIGN;
      id++;
      if (id[0] == '=') {
        singleton = 1;
        id++;
      }
    } else if (id[0] == '^') {
      if (id[1] != '~')
        pari_err(e_MISC, "Unrecognized action in a template");
      id += 2;
      if (negate)
        action = A_ACTION_SET;
      else
        action = A_ACTION_UNSET;
    } else if (id[0] == '|') {
      id++;
      if (negate)
        action = A_ACTION_UNSET;
      else
        action = A_ACTION_SET;
    }

    e = id;

    while ((*e >= '0' && *e <= '9')) e++;
    while (isspace((int)*e))
      e++;
    if (*e && (*e != ';') && (*e != ','))
      pari_err(e_MISC, "Non-numeric argument of an action in a template");
    numarg = atol(id);          /* Now it is safe to get it... */
    switch (action) {
    case A_ACTION_SET:
      retval |= numarg;
      break;
    case A_ACTION_UNSET:
      retval &= ~numarg;
      break;
    case A_ACTION_ASSIGN:
      retval = numarg;
      break;
    default:
      pari_err(e_MISC,"error in parse_option_string");
    }
    first = 0;
    while (isspace((int)*arg))
      arg++;
    if (*arg && !(ispunct((int)*arg) && *arg != '-'))
      pari_err(e_MISC,"Junk after an id in a stringified flag");
    /* Skip punctuation */
    if (*arg)
      arg++;
  }
  avma=av;
  return retval;
}