diff options
author | dec05eba <dec05eba@protonmail.com> | 2021-06-15 20:24:26 +0200 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2021-06-15 20:24:26 +0200 |
commit | 50b96bb1ad375668519ed44075ec96f2f9ab9477 (patch) | |
tree | b0a9d001b7aa8f5e60c46b655f3bb8208dc84654 /src | |
parent | fdcdf3e62230b8bf14d9ee22bb067040d173ea70 (diff) |
Add glob matching for attribute value
Diffstat (limited to 'src')
-rw-r--r-- | src/HtmlSearch.c | 39 |
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; } |