1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-09-29 03:17:53 -04:00

match_attribute_value(): Actually do the matching

This is still untested like the last patch.
This commit is contained in:
Jonas Fonseca 2005-12-25 04:38:30 +01:00 committed by Jonas Fonseca
parent fc35d9ee33
commit 40ae683bfb
2 changed files with 87 additions and 19 deletions

View File

@ -612,42 +612,104 @@ get_child_dom_select_node(struct dom_select_node *selector,
static int static int
match_attribute_value(struct dom_select_node *selector, struct dom_node *node) match_attribute_value(struct dom_select_node *selector, struct dom_node *node)
{ {
struct dom_string str;
struct dom_string *selvalue = &selector->node.data.attribute.value; struct dom_string *selvalue = &selector->node.data.attribute.value;
struct dom_string *value = &node->data.attribute.value; struct dom_string *value = &node->data.attribute.value;
unsigned char separator;
int do_compare;
assert(selvalue->length);
/* The attribute selector value should atleast be contained in the /* The attribute selector value should atleast be contained in the
* attribute value. */ * attribute value. */
if (value->length < selvalue->length) if (value->length < selvalue->length)
return 0; return 0;
/* FIXME: Combine the 3 following to use an offset to specify where in /* The following three matching methods requires the selector value to
* value, selvalue should match. */ * match a substring at a well-defined offset. */
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_EXACT) if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_EXACT)) {
&& dom_string_casecmp(value, selvalue)) return !dom_string_casecmp(value, selvalue);
}
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_BEGIN)) {
set_dom_string(&str, value->string, selvalue->length);
return !dom_string_casecmp(&str, selvalue);
}
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_END)) {
size_t offset = value->length - selvalue->length;
set_dom_string(&str, value->string + offset, selvalue->length);
return !dom_string_casecmp(&str, selvalue);
}
/* The 3 following matching methods requires the selector value to be a
* substring of the value enclosed in a specific separator (with the
* begining and ending of the attribute value both being valid
* separators). */
set_dom_string(&str, value->string, value->length);
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_HYPHEN_LIST)) {
separator = '-';
} else if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_CONTAINS)) {
separator = '\0';
} if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_SPACE_LIST)) {
separator = ' ';
} else {
INTERNAL("No attribute selector matching method defined");
return 0; return 0;
}
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_BEGIN)) do_compare = 1;
return 0;
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_END)) do {
return 0; if (do_compare
&& !dom_string_ncasecmp(&str, selvalue, selvalue->length)) {
/* "Contains" matches no matter what comes after. */
if (str.length == selvalue->length)
return 1;
/* FIXME: Combine the 3 following to simply strstr()-search the value switch (separator) {
* and based on a char group check if it is separated either by case '\0':
* begining, end or the values in the char group: '-' for /* "Contains" matches no matter what comes after. */
* DOM_SELECT_ATTRIBUTE_HYPHEN_LIST, etc. */ return 1;
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_SPACE_LIST)) case '-':
return 0; if (str.string[str.length] == separator)
return 1;
break;
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_HYPHEN_LIST)) default:
return 0; if (isspace(str.string[str.length]))
return 1;
}
}
if (has_attribute_match(selector, DOM_SELECT_ATTRIBUTE_CONTAINS)) switch (separator) {
return 0; case '\0':
do_compare = 1;
break;
return 1; case '-':
do_compare = (str.string[0] == '-');
break;
default:
do_compare = isspace(str.string[0]);
}
str.length--, str.string++;
} while (str.length >= selvalue->length);
return 0;
} }
/* Match the attribute of an element @node against attribute selector nodes /* Match the attribute of an element @node against attribute selector nodes

View File

@ -27,6 +27,12 @@ dom_string_casecmp(struct dom_string *string1, struct dom_string *string2)
return string_diff ? string_diff : string1->length - string2->length; return string_diff ? string_diff : string1->length - string2->length;
} }
static inline int
dom_string_ncasecmp(struct dom_string *string1, struct dom_string *string2, size_t length)
{
return strncasecmp(string1->string, string2->string, length);
}
#define is_dom_string_set(str) ((str)->string && (str)->length) #define is_dom_string_set(str) ((str)->string && (str)->length)
#define done_dom_string(str) mem_free((str)->string); #define done_dom_string(str) mem_free((str)->string);