1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-12-04 14:46:47 -05:00

Cache manager: Add 'Search contents' button

Add a 'Search contents' button to the cache manager that searches
through the cache items' data rather than their metadata.

Add match_cache_entry_contents.

Add push_cache_hierbox_search_button and
push_cache_hierbox_search_contents_button, which call
push_hierbox_search_button after setting box->ops to either
cache_entry_listbox_ops or cache_entry_listbox_ops_match_contents,
respectively, which define the appropriate match callback for the
hierbox search code.

Add strlcasestr, used in the new match_cache_entry_contents routine.
This commit is contained in:
Miciah Dashiel Butler Masters 2009-06-03 19:09:20 +00:00
parent 0ad5b642b4
commit 2b1aedf6d1
4 changed files with 95 additions and 13 deletions

3
NEWS
View File

@ -62,6 +62,9 @@ Miscellaneous:
* Report if the Lua function edit_bookmark_dialog receives the wrong * Report if the Lua function edit_bookmark_dialog receives the wrong
number or types of arguments instead of silently failing. number or types of arguments instead of silently failing.
* enhancement: Add ``Invalidate'' button to the cache manager. * enhancement: Add ``Invalidate'' button to the cache manager.
* enhancement: Add ``Search contents'' button to the cache manager with
which one can search through the cache items' data rather than their
metadata.
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
The following changes should be removed from NEWS before ELinks 0.13.0 The following changes should be removed from NEWS before ELinks 0.13.0

80
src/cache/dialogs.c vendored
View File

@ -200,6 +200,43 @@ match_cache_entry(struct listbox_item *item, struct terminal *term,
return LISTBOX_MATCH_NO; return LISTBOX_MATCH_NO;
} }
static enum listbox_match
match_cache_entry_contents(struct listbox_item *item, struct terminal *term,
unsigned char *text)
{
struct cache_entry *cached = item->udata;
struct fragment *fragment = get_cache_fragment(cached);
if (fragment && strlcasestr(fragment->data, fragment->length, text, -1))
return LISTBOX_MATCH_OK;
return LISTBOX_MATCH_NO;
}
const static struct listbox_ops cache_entry_listbox_ops;
static widget_handler_status_T
push_cache_hierbox_search_button(struct dialog_data *dlg_data, struct widget_data *button)
{
struct listbox_data *box = get_dlg_listbox_data(dlg_data);
box->ops = &cache_entry_listbox_ops;
return push_hierbox_search_button(dlg_data, button);
}
const static struct listbox_ops cache_entry_listbox_ops_match_contents;
static widget_handler_status_T
push_cache_hierbox_search_contents_button(struct dialog_data *dlg_data, struct widget_data *button)
{
struct listbox_data *box = get_dlg_listbox_data(dlg_data);
box->ops = &cache_entry_listbox_ops_match_contents;
return push_hierbox_search_button(dlg_data, button);
}
static struct listbox_ops_messages cache_messages = { static struct listbox_ops_messages cache_messages = {
/* cant_delete_item */ /* cant_delete_item */
N_("Sorry, but cache entry \"%s\" cannot be deleted."), N_("Sorry, but cache entry \"%s\" cannot be deleted."),
@ -227,21 +264,37 @@ static struct listbox_ops_messages cache_messages = {
NULL, NULL,
}; };
static const struct listbox_ops cache_entry_listbox_ops = { #define ops(matchfn) \
lock_cache_entry, lock_cache_entry, \
unlock_cache_entry, unlock_cache_entry, \
is_cache_entry_used, is_cache_entry_used, \
get_cache_entry_text, get_cache_entry_text, \
get_cache_entry_info, get_cache_entry_info, \
get_cache_entry_uri, get_cache_entry_uri, \
get_cache_entry_root, get_cache_entry_root, \
match_cache_entry, matchfn, \
can_delete_cache_entry, can_delete_cache_entry, \
delete_cache_entry_item, delete_cache_entry_item, \
NULL, NULL, \
&cache_messages, &cache_messages,
/* Each hierbox window is represented by an instance of struct hierbox,
* which has a corresponding instance of struct listbox_data. That
* instance of struct listbox_data will point one of the following two
* struct listbox_ops instances depending on which type of search the
* user is performing in that hierbox. The two struct listbox_ops
* instances differ only in the match callback. */
const static struct listbox_ops cache_entry_listbox_ops_match_contents = {
ops(match_cache_entry_contents)
}; };
const static struct listbox_ops cache_entry_listbox_ops = {
ops(match_cache_entry)
};
#undef ops
static widget_handler_status_T static widget_handler_status_T
push_invalidate_button(struct dialog_data *dlg_data, struct widget_data *button) push_invalidate_button(struct dialog_data *dlg_data, struct widget_data *button)
{ {
@ -266,7 +319,8 @@ static const struct hierbox_browser_button cache_buttons[] = {
{ N_("~Info"), push_hierbox_info_button, 1 }, { N_("~Info"), push_hierbox_info_button, 1 },
{ N_("~Goto"), push_hierbox_goto_button, 1 }, { N_("~Goto"), push_hierbox_goto_button, 1 },
{ N_("~Delete"), push_hierbox_delete_button, 1 }, { N_("~Delete"), push_hierbox_delete_button, 1 },
{ N_("~Search"), push_hierbox_search_button, 1 }, { N_("~Search"), push_cache_hierbox_search_button, 1 },
{ N_("Search c~ontents"), push_cache_hierbox_search_contents_button, 1 },
{ N_("In~validate"), push_invalidate_button, 1 }, { N_("In~validate"), push_invalidate_button, 1 },
}; };

View File

@ -245,6 +245,27 @@ elinks_strlcasecmp(const unsigned char *s1, size_t n1,
} }
} }
/* strlcasestr - adapted from c_strcasestr */
char *
elinks_strlcasestr(const char *haystack, const int haystackl,
const char *needle, const int needlel)
{
size_t haystack_length = haystackl == -1 ? strlen(haystack) : haystackl;
size_t needle_length = needlel == -1 ? strlen(needle) : needlel;
int i;
if (haystack_length < needle_length)
return NULL;
for (i = haystack_length - needle_length + 1; i; i--) {
if (!c_strncasecmp(haystack, needle, needle_length))
return (char *) haystack;
haystack++;
}
return NULL;
}
int int
c_strcasecmp(const char *s1, const char *s2) c_strcasecmp(const char *s1, const char *s2)
{ {

View File

@ -106,6 +106,10 @@ int elinks_strlcasecmp(const unsigned char *s1, size_t n1,
const unsigned char *s2, size_t n2, const unsigned char *s2, size_t n2,
const int locale_indep); const int locale_indep);
#define strlcasestr(a,b,c,d) (errfile = __FILE__, errline = __LINE__, elinks_strlcasestr(a,b,c,d))
char *elinks_strlcasestr(const char *haystack, const int haystackl,
const char *needle, const int needlel);
/* strcasecmp and strncasecmp which work as if they are /* strcasecmp and strncasecmp which work as if they are
* in the C locale */ * in the C locale */
int c_strcasecmp(const char *s1, const char *s2); int c_strcasecmp(const char *s1, const char *s2);