texinfo-commits
[Top][All Lists]
Advanced

[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. */ 
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]