texinfo-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[5724] regexp_search


From: Gavin D. Smith
Subject: [5724] regexp_search
Date: Sun, 27 Jul 2014 12:52:13 +0000

Revision: 5724
          http://svn.sv.gnu.org/viewvc/?view=rev&root=texinfo&revision=5724
Author:   gavin
Date:     2014-07-27 12:52:12 +0000 (Sun, 27 Jul 2014)
Log Message:
-----------
regexp_search

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/info/Makefile.am
    trunk/info/search.c

Added Paths:
-----------
    trunk/info/t/infodir/search.info
    trunk/info/t/search-skip-screen.sh

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog     2014-07-27 10:32:33 UTC (rev 5723)
+++ trunk/ChangeLog     2014-07-27 12:52:12 UTC (rev 5724)
@@ -3,6 +3,12 @@
        * info/session.c (info_search_in_node): Merged into callers in
        info_target_search_node and make_footnotes_node.
 
+       * info/search.c (regexp_search): Store previous start and end of
+       search.  Recalculate matches if new search range is outside these.
+       When looking for matches, check that they are within the search range.
+       * info/t/search-skip-screen.sh: New test.
+       * info/t/infodir/search.info: New file.
+
 2014-07-26  Gavin Smith  <address@hidden>
 
        * info/session.c (info_search_1): Unused 'key' argument removed.

Modified: trunk/info/Makefile.am
===================================================================
--- trunk/info/Makefile.am      2014-07-27 10:32:33 UTC (rev 5723)
+++ trunk/info/Makefile.am      2014-07-27 12:52:12 UTC (rev 5724)
@@ -118,6 +118,7 @@
        t/menu-sequence.sh \
        t/relative-reference.sh \
        t/resize-in-completions.sh \
+       t/search-skip-screen.sh \
        t/quoted-label-as-target.sh \
        t/quoted-target.sh \
        t/quoted-label-and-target.sh \

Modified: trunk/info/search.c
===================================================================
--- trunk/info/search.c 2014-07-27 10:32:33 UTC (rev 5723)
+++ trunk/info/search.c 2014-07-27 12:52:12 UTC (rev 5724)
@@ -96,21 +96,28 @@
 regexp_search (char *regexp, SEARCH_BINDING *binding, 
               long *poff, SEARCH_BINDING *pend)
 {
+  static regex_t preg; /* Compiled pattern buffer for regexp. */
+
+  /* Store the last regular expression to avoid recompiling. */
   static char *previous_regexp = NULL;
+  static int was_insensitive = 0;
+
+  regoff_t start = 0, end;
+
+  /* Remember the last buffer the search was over.  We can optimize by reusing
+     the results from last time. */
   static char *previous_content = NULL;
-  static int was_insensitive = 0;
-  static regex_t preg;
-  static regmatch_t *matches;
+  static long previous_start = 0, previous_end = 0;
+
+  static regmatch_t *matches; /* List of matches. */
   static size_t match_alloc = 0;
   static size_t match_count = 0;
-  regoff_t pos;
-  regoff_t start = 0, end;
 
+  /* Check if we need to compile a new regexp. */
   if (previous_regexp == NULL
-      || ((binding->flags & S_FoldCase) != was_insensitive)
-      || (strcmp (previous_regexp, regexp) != 0))
+      || (binding->flags & S_FoldCase) != was_insensitive
+      || strcmp (previous_regexp, regexp) != 0)
     {
-      /* need to compile a new regexp */
       int result;
       char *unescaped_regexp;
       char *p, *q;
@@ -182,41 +189,48 @@
       end = binding->start;
     }
   
-  if (previous_content != binding->buffer)
+  /* Check if we need to calculate new results. */
+  if (binding->buffer != previous_content
+      || start < previous_start
+      || end > previous_end)
     {
-      /* new buffer to search in, let's scan it */
       char saved_char;
+      regoff_t offset = start;
 
+      /* Save for next time. */
       previous_content = binding->buffer;
+      previous_start = start;
+      previous_end = end;
+
       saved_char = previous_content[end];
       previous_content[end] = '\0';
 
-      for (match_count = 0; start < end; )
+      for (match_count = 0; offset < end; )
         {
           int result = 0;
           if (match_count == match_alloc)
             {
-              /* match list full. Initially allocate 256 entries, then double
-                 every time we fill it */
+              /* The match list is full.  Initially allocate 256 entries,
+                 then double every time we fill it. */
              if (match_alloc == 0)
                match_alloc = 256;
              matches = x2nrealloc (matches, &match_alloc, sizeof matches[0]);
             }
 
-          result = regexec (&preg, &previous_content[start],
+          result = regexec (&preg, &previous_content[offset],
                             1, &matches[match_count], 0);
           if (result == 0)
             {
               if (matches[match_count].rm_eo == 0)
                 {
                   /* ignore empty matches */
-                  start++;
+                  offset++;
                 }
               else
                 {
-                  matches[match_count].rm_so += start;
-                  matches[match_count].rm_eo += start;
-                  start = matches[match_count++].rm_eo;
+                  matches[match_count].rm_so += offset;
+                  matches[match_count].rm_eo += offset;
+                  offset = matches[match_count++].rm_eo;
                 }
             }
           else
@@ -225,14 +239,16 @@
       previous_content[end] = saved_char;
     }
 
-  pos = binding->start;
-  if (pos > binding->end)
+  if (binding->start > binding->end)
     {
       /* searching backward */
       int i;
       for (i = match_count - 1; i >= 0; i--)
         {
-          if (matches[i].rm_so <= pos)
+          if (matches[i].rm_so < start)
+            break; /* No matches found in search area. */
+
+          if (matches[i].rm_so < end)
            {
              if (pend)
                {
@@ -252,7 +268,10 @@
       int i;
       for (i = 0; i < match_count; i++)
         {
-          if (matches[i].rm_so >= pos)
+          if (matches[i].rm_so >= end)
+            break; /* No matches found in search area. */
+
+          if (matches[i].rm_so >= start)
             {
              if (pend)
                {

Added: trunk/info/t/infodir/search.info
===================================================================
(Binary files differ)


Property changes on: trunk/info/t/infodir/search.info
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/info/t/search-skip-screen.sh
===================================================================
--- trunk/info/t/search-skip-screen.sh                          (rev 0)
+++ trunk/info/t/search-skip-screen.sh  2014-07-27 12:52:12 UTC (rev 5724)
@@ -0,0 +1,33 @@
+#!/bin/sh
+# Copyright (C) 2014 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
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+srcdir=${srcdir:-.}
+. $srcdir/t/Init-test.inc
+. $t/Init-inter.inc
+
+run_ginfo -v search-skip-screen=Off -f search
+
+# Go back to previous match when search-skip-screen=On
+printf 'smatch\r}{Dq' >$PTY_TYPE
+
+. $t/Timeout-test.inc
+
+# Check we went back to the right node.
+grep '^File: search\.info, Node: Top' $GINFO_OUTPUT
+RETVAL=$?
+
+. $t/Cleanup.inc
+


Property changes on: trunk/info/t/search-skip-screen.sh
___________________________________________________________________
Added: svn:executable
   + *




reply via email to

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