[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[7696] Access list of search matches through accessor functions only
From: |
gavinsmith0123 |
Subject: |
[7696] Access list of search matches through accessor functions only |
Date: |
Tue, 21 Mar 2017 10:00:55 -0400 (EDT) |
Revision: 7696
http://svn.sv.gnu.org/viewvc/?view=rev&root=texinfo&revision=7696
Author: gavin
Date: 2017-03-21 10:00:55 -0400 (Tue, 21 Mar 2017)
Log Message:
-----------
Access list of search matches through accessor functions only
Modified Paths:
--------------
trunk/ChangeLog
trunk/info/display.c
trunk/info/search.c
trunk/info/search.h
trunk/info/session.c
trunk/info/window.c
trunk/info/window.h
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2017-03-19 20:48:41 UTC (rev 7695)
+++ trunk/ChangeLog 2017-03-21 14:00:55 UTC (rev 7696)
@@ -1,3 +1,32 @@
+2017-03-21 Gavin Smith <address@hidden>
+
+ Access list of search matches through accessor functions only.
+
+ * info/window.h (MATCH_STATE): New struct type.
+ (WINDOW): Use it for new field 'matches', replacing previous
+ 'matches' and 'match_count' fields.
+
+ * info/search.c (match_by_index, free_matches, matches_ready)
+ (at_end_of_matches):
+ New functions.
+ * info/session.c (info_search_in_node_internal, put_node_in_window)
+ (info_search_internal, info_clear_search, incremental_search),
+ * info/window.c (window_set_node_of_window, tree_search_check_node),
+ * info/display.c (display_process_line): Use them.
+
+ * info/session.c, info/search.c (match_in_match_list): Move
+ function to search.c, and take MATCH_STATE argument.
+ * info/search.c (regexp_search): Return result via a pointer to
+ a MATCH_STATE.
+
+ * info/display.c, info/search.c (decide_if_in_match): Move to
+ search.c.
+ * info/display.c (matches): Variable is of type MATCH_STATE *.
+
+ This opens the way to not calculating an entire list of matches
+ in one go, which may take a long time if there are too many (thus
+ leading to the need for the 'min-search-length' variable).
+
2017-03-19 Gavin Smith <address@hidden>
* doc/texinfo.texi (HTML Customization Variable) <WORDS_IN_PAGE>:
Modified: trunk/info/display.c
===================================================================
--- trunk/info/display.c 2017-03-19 20:48:41 UTC (rev 7695)
+++ trunk/info/display.c 2017-03-21 14:00:55 UTC (rev 7696)
@@ -2,7 +2,7 @@
$Id$
Copyright 1993, 1997, 2003, 2004, 2006, 2007, 2008, 2012, 2013,
- 2014, 2015 Free Software Foundation, Inc.
+ 2014, 2015, 2016, 2017 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -225,35 +225,11 @@
}
-/* Given an array MATCHES with regions, and an offset *MATCH_INDEX, decide
- if we are inside a region at offset OFF. The matches are assumed not
+/* Similar to decide_if_in_match, but used for reference highlighting.
+ Given an array REFERENCES with regions, starting at *REF_INDEX decide
+ if we are inside a region at offset OFF. The regions are assumed not
to overlap and to be in order. */
static void
-decide_if_in_match (long off, int *in_match, regmatch_t *matches,
- size_t match_count, size_t *match_index)
-{
- size_t i = *match_index;
- int m = *in_match;
-
- for (; i < match_count; i++)
- {
- if (matches[i].rm_so > off)
- break;
-
- m = 1;
-
- if (matches[i].rm_eo > off)
- break;
-
- m = 0;
- }
-
- *match_index = i;
- *in_match = m;
-}
-
-/* Similar to decide_if_in_match, but used for reference highlighting. */
-static void
decide_if_in_reference (long off, int *in_ref, REFERENCE **references,
int *ref_index)
{
@@ -324,7 +300,7 @@
/* Set in display_update_node_text if matches or references are to be
distinguished with terminal appearance modes. */
-static regmatch_t *matches;
+static MATCH_STATE *matches;
static REFERENCE **refs;
static size_t match_index;
static int ref_index;
@@ -381,12 +357,12 @@
break;
cur_ptr = mbi_cur_ptr (iter);
- if (matches && match_index != win->match_count)
+ if (matches_ready (matches)
+ && !at_end_of_matches (matches, match_index))
{
int was_in_match = in_match;
decide_if_in_match (cur_ptr - win->node->contents,
- &in_match, matches, win->match_count,
- &match_index);
+ &in_match, matches, &match_index);
if (!was_in_match && in_match && writing_out == DEFAULT)
writing_out = COLLECT;
@@ -524,7 +500,7 @@
matches = 0;
refs = 0;
if (match_rendition.mask)
- matches = win->matches;
+ matches = &win->matches;
if (ref_rendition.mask || hl_ref_rendition.mask)
refs = win->node->references;
Modified: trunk/info/search.c
===================================================================
--- trunk/info/search.c 2017-03-19 20:48:41 UTC (rev 7695)
+++ trunk/info/search.c 2017-03-21 14:00:55 UTC (rev 7696)
@@ -136,7 +136,7 @@
enum search_result
regexp_search (char *regexp, int is_literal, int is_insensitive,
char *buffer, size_t buflen,
- regmatch_t **matches_out, size_t *match_count_out)
+ MATCH_STATE *match_state)
{
regmatch_t *matches = 0; /* List of found matches. */
size_t match_alloc = 0;
@@ -201,8 +201,8 @@
buffer[buflen] = saved_char;
regfree (&preg);
- *matches_out = matches;
- *match_count_out = match_count;
+ match_state->matches = matches;
+ match_state->match_count = match_count;
if (match_count == 0)
return search_not_found;
@@ -400,6 +400,127 @@
/* **************************************************************** */
/* */
+/* Accessing matches */
+/* */
+/* **************************************************************** */
+/* Search forwards or backwards for entries in MATCHES that start within
+ the search area. The search is forwards if START_IN is greater than
+ END_IN. Return offset of match in *MATCH_INDEX. */
+enum search_result
+match_in_match_list (MATCH_STATE *match_state,
+ long start_in, long end_in, int *match_index)
+{
+ regmatch_t *matches = match_state->matches;
+ size_t match_count = match_state->match_count;
+
+ regoff_t start, end;
+ if (start_in < end_in)
+ {
+ start = start_in;
+ end = end_in;
+ }
+ else
+ {
+ /* Include the byte with offset 'start_in' in our range, but not
+ the byte with offset 'end_in'. */
+ start = end_in - 1;
+ end = start_in + 1;
+ }
+
+ if (start_in > end_in)
+ {
+ /* searching backward */
+ int i;
+ for (i = match_count - 1; i >= 0; i--)
+ {
+ if (matches[i].rm_so < start)
+ break; /* No matches found in search area. */
+
+ if (matches[i].rm_so < end)
+ {
+ *match_index = i;
+ return search_success;
+ }
+ }
+ }
+ else
+ {
+ /* searching forward */
+ int i;
+ for (i = 0; i < match_count; i++)
+ {
+ if (matches[i].rm_so >= end)
+ break; /* No matches found in search area. */
+
+ if (matches[i].rm_so >= start)
+ {
+ *match_index = i;
+ return search_success;
+ }
+ }
+ }
+
+ /* not found */
+ return search_not_found;
+}
+
+regmatch_t
+match_by_index (MATCH_STATE *state, int index)
+{
+ return state->matches[index];
+}
+
+void
+free_matches (MATCH_STATE *state)
+{
+ free (state->matches);
+ state->matches = 0;
+ state->match_count = 0;
+}
+
+int
+matches_ready (MATCH_STATE *state)
+{
+ return state->matches ? 1 : 0;
+}
+
+/* Starting at index *MATCH_INDEX, decide if we are inside a match
+ in MATCHES at offset OFF. The matches are assumed not to overlap
+ and to be in order. */
+void
+decide_if_in_match (long off, int *in_match,
+ MATCH_STATE *matches, size_t *match_index)
+{
+ size_t i = *match_index;
+ int m = *in_match;
+
+ for (; i < matches->match_count; i++)
+ {
+ if (matches->matches[i].rm_so > off)
+ break;
+
+ m = 1;
+
+ if (matches->matches[i].rm_eo > off)
+ break;
+
+ m = 0;
+ }
+
+ *match_index = i;
+ *in_match = m;
+}
+
+int
+at_end_of_matches (MATCH_STATE *state, int index)
+{
+ return (state->match_count == index) ? 1 : 0;
+}
+
+
+
+/* **************************************************************** */
+/* */
/* Small String Searches */
/* */
/* **************************************************************** */
Modified: trunk/info/search.h
===================================================================
--- trunk/info/search.h 2017-03-19 20:48:41 UTC (rev 7695)
+++ trunk/info/search.h 2017-03-21 14:00:55 UTC (rev 7696)
@@ -62,7 +62,7 @@
enum search_result regexp_search (char *regexp,
int is_literal, int is_insensitive,
char *buffer, size_t buflen,
- regmatch_t **matches_out, size_t *match_count_out);
+ MATCH_STATE *match_state);
int looking_at (char *string, SEARCH_BINDING *binding);
int looking_at_line (char *string, char *pointer);
@@ -84,4 +84,14 @@
long find_file_section (SEARCH_BINDING *binding, char *label);
long find_node_in_binding (char *nodename, SEARCH_BINDING *binding);
+regmatch_t match_by_index (MATCH_STATE *state, int index);
+enum search_result match_in_match_list (MATCH_STATE *state,
+ long start_in, long end_in, int *match_index);
+
+void free_matches (MATCH_STATE *state);
+int matches_ready (MATCH_STATE *state);
+int at_end_of_matches (MATCH_STATE *state, int index);
+void decide_if_in_match (long off, int *in_match, MATCH_STATE *matches,
+ size_t *match_index);
+
#endif /* not INFO_SEARCH_H */
Modified: trunk/info/session.c
===================================================================
--- trunk/info/session.c 2017-03-19 20:48:41 UTC (rev 7695)
+++ trunk/info/session.c 2017-03-21 14:00:55 UTC (rev 7696)
@@ -2,7 +2,7 @@
$Id$
Copyright 1993, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2007, 2008, 2009, 2011, 2012, 2013, 2014, 2015
+ 2004, 2007, 2008, 2009, 2011, 2012, 2013, 2014, 2015, 2016, 2017
Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
@@ -890,7 +890,7 @@
win->node = node;
win->pagetop = 0;
win->point = 0;
- free (win->matches); win->matches = 0;
+ free_matches (&win->matches);
free (win->line_starts); win->line_starts = 0;
free (win->log_line_no); win->log_line_no = 0;
win->flags |= W_UpdateWindow;
@@ -3914,64 +3914,6 @@
: _("Using literal strings for searches."));
}
-/* Search forwards or backwards for entries in MATCHES that start within
- the search area. The search is forwards if START_IN is greater than
- END_IN. Return offset of match in *MATCH_INDEX. */
-static enum search_result
-match_in_match_list (regmatch_t *matches, size_t match_count,
- long start_in, long end_in, int *match_index)
-{
- regoff_t start, end;
- if (start_in < end_in)
- {
- start = start_in;
- end = end_in;
- }
- else
- {
- /* Include the byte with offset 'start_in' in our range, but not
- the byte with offset 'end_in'. */
- start = end_in - 1;
- end = start_in + 1;
- }
-
- if (start_in > end_in)
- {
- /* searching backward */
- int i;
- for (i = match_count - 1; i >= 0; i--)
- {
- if (matches[i].rm_so < start)
- break; /* No matches found in search area. */
-
- if (matches[i].rm_so < end)
- {
- *match_index = i;
- return search_success;
- }
- }
- }
- else
- {
- /* searching forward */
- int i;
- for (i = 0; i < match_count; i++)
- {
- if (matches[i].rm_so >= end)
- break; /* No matches found in search area. */
-
- if (matches[i].rm_so >= start)
- {
- *match_index = i;
- return search_success;
- }
- }
- }
-
- /* not found */
- return search_not_found;
-}
-
/* Search for STRING in NODE starting at START. The DIR argument says which
direction to search in. If it is positive, search forward, else backwards.
@@ -3990,30 +3932,27 @@
enum search_result result = search_not_found;
long start1, end1;
- regmatch_t *matches;
- size_t match_count;
int match_index;
long new_point;
+
+ MATCH_STATE matches;
/* Check if we need to calculate new results. */
- if (!window->matches
+ if (!matches_ready (&window->matches)
|| strcmp (window->search_string, string)
|| window->search_is_case_sensitive != case_sensitive)
{
- free (window->matches);
- window->matches = 0;
+ free_matches (&window->matches);
free (window->search_string);
window->search_string = xstrdup (string);
window->search_is_case_sensitive = case_sensitive;
result = regexp_search (string, !match_regexp, !case_sensitive,
- node->contents, node->nodelen,
- &matches, &match_count);
+ node->contents, node->nodelen, &matches);
}
else
{
matches = window->matches;
- match_count = window->match_count;
result = search_success;
}
@@ -4027,7 +3966,7 @@
enum search_result subresult;
NODE *full_node;
- free (matches);
+ free_matches (&matches);
full_node = info_get_node (node->fullpath, node->nodename);
subresult = info_search_in_node_internal (window, full_node,
string, start,
@@ -4052,28 +3991,23 @@
end1 = node->body_start;
}
- result = match_in_match_list (matches, match_count,
- start1, end1, &match_index);
+ result = match_in_match_list (&matches, start1, end1, &match_index);
if (result != search_success)
return result;
- *poff = matches[match_index].rm_so;
+ *poff = match_by_index (&matches, match_index).rm_so;
window->flags |= W_UpdateWindow;
if (window->node != node)
info_set_node_of_window (window, node);
- if (window->matches != matches)
- {
- free (window->matches);
- window->matches = matches;
- window->match_count = match_count;
- }
+ if (!matches_ready (&window->matches))
+ window->matches = matches;
if (isearch_is_active && dir > 0)
- new_point = matches[match_index].rm_eo;
+ new_point = match_by_index (&matches, match_index).rm_eo;
else
- new_point = matches[match_index].rm_so;
+ new_point = match_by_index (&matches, match_index).rm_so;
window->point = new_point;
@@ -4201,8 +4135,7 @@
}
/* Get a new node to search in. */
- free (window->matches);
- window->matches = 0;
+ free_matches (&window->matches);
node = info_node_of_tag_fast (file_buffer, &tag);
if (!node)
@@ -4414,7 +4347,7 @@
}
/* Otherwise, try each menu entry in turn. */
- if (window->matches)
+ if (matches_ready (&window->matches))
window->point++; /* Find this match again if/when we come back. */
goto check_menus;
@@ -4789,8 +4722,7 @@
DECLARE_INFO_COMMAND (info_clear_search,
_("Clear displayed search matches"))
{
- free (window->matches);
- window->matches = 0;
+ free_matches (&window->matches);
window->flags |= W_UpdateWindow;
}
@@ -5134,8 +5066,7 @@
if (isearch_string_index == 0)
{
/* Don't search for an empty string. Clear the search. */
- free (window->matches);
- window->matches = 0;
+ free_matches (&window->matches);
display_update_one_window (window);
continue;
}
Modified: trunk/info/window.c
===================================================================
--- trunk/info/window.c 2017-03-19 20:48:41 UTC (rev 7695)
+++ trunk/info/window.c 2017-03-21 14:00:55 UTC (rev 7696)
@@ -575,10 +575,8 @@
calculate_line_starts (window);
window_compute_line_map (window);
- /* Clear displayed search matches if any. TODO: do search again in new
- node? */
- free (window->matches);
- window->matches = 0;
+ /* Clear displayed search matches if any. */
+ free_matches (&window->matches);
window->flags |= W_UpdateWindow;
if (node)
Modified: trunk/info/window.h
===================================================================
--- trunk/info/window.h 2017-03-19 20:48:41 UTC (rev 7695)
+++ trunk/info/window.h 2017-03-21 14:00:55 UTC (rev 7696)
@@ -1,7 +1,7 @@
/* window.h -- Structure and flags used in manipulating Info windows.
$Id$
- Copyright 1993, 1997, 2004, 2007, 2011 2013, 2014, 2015, 2016
+ Copyright 1993, 1997, 2004, 2007, 2011 2013, 2014, 2015, 2016, 2017
Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
@@ -63,6 +63,12 @@
WINDOW_STATE_DECL; /* What gets saved. */
} WINDOW_STATE;
+typedef struct match_struct
+{
+ regmatch_t *matches;
+ size_t match_count;
+} MATCH_STATE;
+
/* Structure which defines a window. Windows are doubly linked, next
and prev. The list of windows is kept on WINDOWS. The structure member
window->height is the total height of the window. The position location
@@ -92,8 +98,7 @@
/* Used for highlighting search matches. */
char *search_string;
int search_is_case_sensitive;
- regmatch_t *matches;
- size_t match_count;
+ MATCH_STATE matches;
/* History of nodes visited in this window. */
WINDOW_STATE **hist; /* Nodes visited in this window, including current. */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [7696] Access list of search matches through accessor functions only,
gavinsmith0123 <=