aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-06-15 20:24:26 +0200
committerdec05eba <dec05eba@protonmail.com>2021-06-15 20:24:26 +0200
commit50b96bb1ad375668519ed44075ec96f2f9ab9477 (patch)
treeb0a9d001b7aa8f5e60c46b655f3bb8208dc84654
parentfdcdf3e62230b8bf14d9ee22bb067040d173ea70 (diff)
Add glob matching for attribute value
-rw-r--r--src/HtmlSearch.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/src/HtmlSearch.c b/src/HtmlSearch.c
index 150437e..d31ab04 100644
--- a/src/HtmlSearch.c
+++ b/src/HtmlSearch.c
@@ -64,6 +64,43 @@ static void strip_newline(const char *str, size_t size, const char **output_str,
rstrip_newline(*output_str, *output_size, output_size);
}
+/* Returns pointer to char that is not |not_char|, even if the first matching character is the null terminator. |not_char| can't be '\0' */
+static const char* find_first_not_char(const char *str, char not_char) {
+ assert(not_char != '\0');
+ while(*str == not_char) { ++str; }
+ return str;
+}
+
+/* Returns 0 on match */
+static int str_glob_match(const char *str, const char *glob) {
+ for(;;) {
+ char glob_c = *glob;
+ if(glob_c == '*') {
+ glob = find_first_not_char(glob + 1, '*');
+ char next_glob_c = *glob;
+ if(next_glob_c == '\0')
+ return 0;
+
+ str = strchr(str, next_glob_c);
+ if(!str)
+ return 1;
+ } else {
+ char str_c = *str;
+ if(str_c != glob_c)
+ return 1;
+
+ if(str_c == '\0')
+ return 0;
+ }
+
+ ++str;
+ ++glob;
+ }
+
+ assert(0); /* shouldn't happen */
+ return 1;
+}
+
static int add_inner_text_recursive(const TidyDoc doc, const TidyNode node, QuickMediaString *str) {
for(TidyNode child = tidyGetChild(node); child; child = tidyGetNext(child)) {
const char *node_name = tidyNodeGetName(child);
@@ -137,7 +174,7 @@ static void find_child_nodes(TidyDoc tdoc, TidyNode node, const QuickMediaNodeSe
const char *attr_value = tidyAttrValue(child_attr);
assert(search_data->param.value);
/* If the param value matches what we want to search for */
- if(attr_value && strcmp(search_data->param.value, attr_value) == 0) {
+ if(attr_value && str_glob_match(attr_value, search_data->param.value) == 0) {
on_match();
continue;
}