aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-07-03 17:11:39 +0200
committerdec05eba <dec05eba@protonmail.com>2021-07-03 17:11:39 +0200
commit8f41cc827b3c4096da4cd770175f43a085231bbf (patch)
tree51651ff5c8c9734742dc16e2e4897193936c9488
parentbbc88f60df2f22eaa4678f6d7f581229f7905679 (diff)
Case insensitive tag and attribute key match
-rw-r--r--README.md3
-rw-r--r--src/HtmlSearch.c24
2 files changed, 21 insertions, 6 deletions
diff --git a/README.md b/README.md
index 0516066..b7f6ea6 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,5 @@
Html search using non-standard xpath, written in C. See tests/main.c
# Note
-This library does not decode html sequences in text and attribute values \ No newline at end of file
+This library does not decode html sequences in text and attribute values.
+Tag and attribute key matching is case-insensitive. \ No newline at end of file
diff --git a/src/HtmlSearch.c b/src/HtmlSearch.c
index 267ec6a..bc58881 100644
--- a/src/HtmlSearch.c
+++ b/src/HtmlSearch.c
@@ -118,16 +118,30 @@ static int str_glob_match(const QuickMediaStringView str, const QuickMediaString
return 1;
}
-static int string_views_equal(const QuickMediaStringView str1, const QuickMediaStringView str2) {
- if(str2.size == str1.size && memcmp(str2.data, str1.data, str1.size) == 0)
- return 0;
+static char to_upper(char c) {
+ if(c >= 'a' && c <= 'z')
+ return c - 32;
else
+ return c;
+}
+
+static int string_views_equal_case_insensitive(const QuickMediaStringView str1, const QuickMediaStringView str2) {
+ if(str2.size != str1.size)
return 1;
+
+ for(size_t i = 0; i < str1.size; ++i) {
+ char c1 = str1.data[i];
+ char c2 = str2.data[i];
+ if(to_upper(c1) != to_upper(c2))
+ return 1;
+ }
+
+ return 0;
}
static QuickMediaHtmlAttribute* get_attribute_by_name(QuickMediaHtmlNode *node, QuickMediaStringView name) {
for(QuickMediaHtmlAttribute *attr = node->first_attribute; attr; attr = attr->next) {
- if(string_views_equal(attr->key, name) == 0)
+ if(string_views_equal_case_insensitive(attr->key, name) == 0)
return attr;
}
return NULL;
@@ -144,7 +158,7 @@ static int find_child_nodes(QuickMediaHtmlChildNode *node, const QuickMediaNodeS
continue;
/* Match without node name or node name matches */
- if(search_data->name.size == 0 || string_views_equal(child->node.name, search_data->name) == 0) {
+ if(search_data->name.size == 0 || string_views_equal_case_insensitive(child->node.name, search_data->name) == 0) {
#define on_match() do { \
if(search_data->child) { \
if(find_child_nodes(child->node.first_child, search_data->child, result_callback, userdata) != 0) \