bug-texinfo
[Top][All Lists]
Advanced

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

Re: info-4.13 rings too many bells upon invalid search regexp


From: Sergey Poznyakoff
Subject: Re: info-4.13 rings too many bells upon invalid search regexp
Date: Fri, 23 Jan 2009 11:48:13 +0200

Hi,

> I just did "info libc", then "s opendir (".
> It used to work (texinfo-4.12), but now I get
> 
>     regexp error: Unmatched ( or \(
> 
> which is no problem.  I can adapt, of course.

You may switch back to literal searches using the `R' command.
We can also implement a variable in ~/.info which will control the
default search type. What do you think?

> However, I also got so many "BELL" (flash-screen)
> alerts that my window flashed for so long that I
> thought it was stuck in an infinite loop or printing
> garbage, so I interrupted it quickly.  But I was
> too impatient.  If I let it run its course, it stops
> after about 5 seconds of screen flashing.

Thanks for reporting. I have fixed this in the repository. The fix is
included.

Regards,
Sergey

Index: info/dir.c
===================================================================
RCS file: /cvsroot/texinfo/texinfo/info/dir.c,v
retrieving revision 1.8
diff -p -u -r1.8 dir.c
--- info/dir.c  11 Jun 2008 09:55:41 -0000      1.8
+++ info/dir.c  23 Jan 2009 09:12:13 -0000
@@ -180,11 +180,9 @@ add_menu_to_file_buffer (char *contents,
   fb_binding.flags = S_FoldCase | S_SkipDest;
 
   /* Move to the start of the menus in CONTENTS and FB. */
-  contents_offset = search_forward (INFO_MENU_LABEL, &contents_binding);
-  fb_offset = search_forward (INFO_MENU_LABEL, &fb_binding);
-
-  /* If there is no menu in CONTENTS, quit now. */
-  if (contents_offset == -1)
+  if (search_forward (INFO_MENU_LABEL, &contents_binding, &contents_offset)
+      != search_success)
+    /* If there is no menu in CONTENTS, quit now. */
     return;
 
   /* There is a menu in CONTENTS, and contents_offset points to the first
@@ -193,7 +191,8 @@ add_menu_to_file_buffer (char *contents,
   contents_offset += skip_whitespace_and_newlines (contents + contents_offset);
 
   /* If there is no menu in FB, make one. */
-  if (fb_offset == -1)
+  if (search_forward (INFO_MENU_LABEL, &fb_binding, &fb_offset)
+      != search_success)
     {
       /* Find the start of the second node in this file buffer.  If there
          is only one node, we will be adding the contents to the end of
@@ -224,8 +223,8 @@ add_menu_to_file_buffer (char *contents,
       fb_binding.buffer = fb->contents;
       fb_binding.start = 0;
       fb_binding.end = fb->filesize;
-      fb_offset = search_forward (INFO_MENU_LABEL, &fb_binding);
-      if (fb_offset == -1)
+      if (search_forward (INFO_MENU_LABEL, &fb_binding, &fb_offset)
+         != search_success)
         abort ();
     }
 
Index: info/info-utils.c
===================================================================
RCS file: /cvsroot/texinfo/texinfo/info/info-utils.c,v
retrieving revision 1.13
diff -p -u -r1.13 info-utils.c
--- info/info-utils.c   5 Oct 2008 14:56:12 -0000       1.13
+++ info/info-utils.c   23 Jan 2009 09:12:13 -0000
@@ -201,9 +201,8 @@ info_menu_of_node (NODE *node)
   tmp_search.flags = S_FoldCase;
 
   /* Find the start of the menu. */
-  position = search_forward (INFO_MENU_LABEL, &tmp_search);
-
-  if (position == -1)
+  if (search_forward (INFO_MENU_LABEL, &tmp_search, &position)
+      != search_success)
     return NULL;
 
   /* We have the start of the menu now.  Glean menu items from the rest
@@ -272,7 +271,7 @@ info_references_internal (char *label, S
 
   searching_for_menu_items = (mbscasecmp (label, INFO_MENU_ENTRY_LABEL) == 0);
 
-  while ((position = search_forward (label, &tmp_search)) != -1)
+  while (search_forward (label, &tmp_search, &position) == search_success)
     {
       int offset, start;
       char *refdef;
Index: info/man.c
===================================================================
RCS file: /cvsroot/texinfo/texinfo/info/man.c,v
retrieving revision 1.14
diff -p -u -r1.14 man.c
--- info/man.c  28 Jun 2008 08:09:32 -0000      1.14
+++ info/man.c  23 Jan 2009 09:12:14 -0000
@@ -499,8 +499,8 @@ find_reference_section (NODE *node)
 
   for (i = 0; reference_section_starters[i] != NULL; i++)
     {
-      position = search_forward (reference_section_starters[i], &frs_binding);
-      if (position != -1)
+      if (search_forward (reference_section_starters[i], &frs_binding,
+                         &position) == search_success)
         break;
     }
 
@@ -544,7 +544,7 @@ xrefs_of_manpage (NODE *node)
      within parenthesis. */
   reference_section->flags = 0;
 
-  while ((position = search_forward ("(", reference_section)) != -1)
+  while (search_forward ("(", reference_section, &position) == search_success)
     {
       register int start, end;
 
Index: info/nodes.c
===================================================================
RCS file: /cvsroot/texinfo/texinfo/info/nodes.c,v
retrieving revision 1.12
diff -p -u -r1.12 nodes.c
--- info/nodes.c        5 Oct 2008 14:56:12 -0000       1.12
+++ info/nodes.c        23 Jan 2009 09:12:14 -0000
@@ -409,11 +409,10 @@ build_tags_and_nodes (FILE_BUFFER *file_
     binding.end = 0;
   binding.flags = S_FoldCase;
 
-  position = search_backward (TAGS_TABLE_END_LABEL, &binding);
-
-  /* If there is a tag table, find the start of it, and grovel over it
-     extracting tag information. */
-  if (position != -1)
+  if (search_backward (TAGS_TABLE_END_LABEL, &binding, &position)
+      == search_success)
+    /* If there is a tag table, find the start of it, and grovel over it
+       extracting tag information. */
     while (1)
       {
         long tags_table_begin, tags_table_end;
@@ -436,9 +435,8 @@ build_tags_and_nodes (FILE_BUFFER *file_
         binding.end = 0;
 
         /* Locate the start of the tags table. */
-        position = search_backward (TAGS_TABLE_BEG_LABEL, &binding);
-
-        if (position == -1)
+        if (search_backward (TAGS_TABLE_BEG_LABEL, &binding, &position)
+           != search_success)
           break;
 
         binding.end = position;
@@ -476,9 +474,8 @@ build_tags_and_nodes (FILE_BUFFER *file_
             indirect.buffer = binding.buffer;
             indirect.flags = S_FoldCase;
 
-            position = search_backward (INDIRECT_TAGS_TABLE_LABEL, &indirect);
-
-            if (position == -1)
+            if (search_backward (INDIRECT_TAGS_TABLE_LABEL, &indirect,
+                                &position) != search_success)
               {
                 /* This file is malformed.  Give up. */
                 return;
@@ -622,7 +619,7 @@ get_nodes_of_tags_table (FILE_BUFFER *fi
 
   /* The tag table consists of lines containing node names and positions.
      Do each line until we find one that doesn't contain a node name. */
-  while ((position = search_forward ("\n", tmp_search)) != -1)
+  while (search_forward ("\n", tmp_search, &position) == search_success)
     {
       TAG *entry;
       char *nodedef;
Index: info/search.c
===================================================================
RCS file: /cvsroot/texinfo/texinfo/info/search.c,v
retrieving revision 1.9
diff -p -u -r1.9 search.c
--- info/search.c       11 Jun 2008 09:55:42 -0000      1.9
+++ info/search.c       23 Jan 2009 09:12:14 -0000
@@ -1,7 +1,7 @@
 /* search.c -- searching large bodies of text.
    $Id: search.c,v 1.9 2008/06/11 09:55:42 gray Exp $
 
-   Copyright (C) 1993, 1997, 1998, 2002, 2004, 2007, 2008
+   Copyright (C) 1993, 1997, 1998, 2002, 2004, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
@@ -70,16 +70,16 @@ copy_binding (SEARCH_BINDING *binding)
 
 /* Search forwards or backwards for the text delimited by BINDING.
    The search is forwards if BINDING->start is greater than BINDING->end. */
-long
-search (char *string, SEARCH_BINDING *binding)
+enum search_result
+search (char *string, SEARCH_BINDING *binding, long *poff)
 {
-  long result;
+  enum search_result result;
 
   /* If the search is backwards, then search backwards, otherwise forwards. */
   if (binding->start > binding->end)
-    result = search_backward (string, binding);
+    result = search_backward (string, binding, poff);
   else
-    result = search_forward (string, binding);
+    result = search_forward (string, binding, poff);
 
   return result;
 }
@@ -88,13 +88,13 @@ search (char *string, SEARCH_BINDING *bi
    delimited by BINDING. The search is forwards if BINDING->start is greater
    than BINDING->end.
 
-   If PRET is specified, it receives a copy of BINDING at the end of a
+   If PEND is specified, it receives a copy of BINDING at the end of a
    succeded search.  Its START and END fields contain bounds of the found
    string instance. 
 */
-long
+enum search_result
 regexp_search (char *regexp, SEARCH_BINDING *binding, long length,
-              SEARCH_BINDING *pret)
+              long *poff, SEARCH_BINDING *pend)
 {
   static char *previous_regexp = NULL;
   static char *previous_content = NULL;
@@ -164,7 +164,7 @@ regexp_search (char *regexp, SEARCH_BIND
           char *buf = xmalloc (size);
           regerror (result, &preg, buf, size);
           info_error (_("regexp error: %s"), buf, NULL);
-          return -1;
+          return search_failure;
         }
 
       previous_regexp = xstrdup(regexp);
@@ -225,14 +225,15 @@ regexp_search (char *regexp, SEARCH_BIND
         {
           if (matches[i].rm_so <= pos)
            {
-             if (pret)
+             if (pend)
                {
-                 pret->buffer = binding->buffer;
-                 pret->flags = binding->flags;
-                 pret->start = matches[i].rm_so;
-                 pret->end = matches[i].rm_eo;
+                 pend->buffer = binding->buffer;
+                 pend->flags = binding->flags;
+                 pend->start = matches[i].rm_so;
+                 pend->end = matches[i].rm_eo;
                }
-             return matches[i].rm_so;
+             *poff = matches[i].rm_so;
+             return search_success;
            }
         }
     }
@@ -244,28 +245,29 @@ regexp_search (char *regexp, SEARCH_BIND
         {
           if (matches[i].rm_so >= pos)
             {
-             if (pret)
+             if (pend)
                {
-                 pret->buffer = binding->buffer;
-                 pret->flags = binding->flags;
-                 pret->start = matches[i].rm_so;
-                 pret->end = matches[i].rm_eo;
+                 pend->buffer = binding->buffer;
+                 pend->flags = binding->flags;
+                 pend->start = matches[i].rm_so;
+                 pend->end = matches[i].rm_eo;
                }
               if (binding->flags & S_SkipDest)
-                return matches[i].rm_eo;
+                *poff = matches[i].rm_eo;
               else
-                return matches[i].rm_so;
+                *poff = matches[i].rm_so;
+             return search_success;
             }
         }
     }
 
   /* not found */
-  return -1;
+  return search_not_found;
 }
 
 /* Search forwards for STRING through the text delimited in BINDING. */
-long
-search_forward (char *string, SEARCH_BINDING *binding)
+enum search_result
+search_forward (char *string, SEARCH_BINDING *binding, long *poff)
 {
   register int c, i, len;
   register char *buff, *end;
@@ -310,7 +312,8 @@ search_forward (char *string, SEARCH_BIN
             free (alternate);
           if (binding->flags & S_SkipDest)
             buff += len;
-          return buff - binding->buffer;
+          *poff = buff - binding->buffer;
+         return search_success;
         }
 
       buff++;
@@ -319,12 +322,12 @@ search_forward (char *string, SEARCH_BIN
   if (alternate)
     free (alternate);
 
-  return -1;
+  return search_not_found;
 }
 
 /* Search for STRING backwards through the text delimited in BINDING. */
-long
-search_backward (char *input_string, SEARCH_BINDING *binding)
+enum search_result
+search_backward (char *input_string, SEARCH_BINDING *binding, long *poff)
 {
   register int c, i, len;
   register char *buff, *end;
@@ -379,7 +382,8 @@ search_backward (char *input_string, SEA
 
           if (binding->flags & S_SkipDest)
             buff -= len;
-          return 1 + buff - binding->buffer;
+          *poff = 1 + buff - binding->buffer;
+         return search_success;
         }
 
       buff--;
@@ -389,7 +393,7 @@ search_backward (char *input_string, SEA
   if (alternate)
     free (alternate);
 
-  return -1;
+  return search_not_found;
 }
 
 /* Find STRING in LINE, returning the offset of the end of the string.
@@ -400,7 +404,8 @@ string_in_line (char *string, char *line
 {
   register int end;
   SEARCH_BINDING binding;
-
+  long offset;
+  
   /* Find the end of the line. */
   for (end = 0; line[end] && line[end] != '\n'; end++);
 
@@ -410,7 +415,9 @@ string_in_line (char *string, char *line
   binding.end = end;
   binding.flags = S_FoldCase | S_SkipDest;
 
-  return search_forward (string, &binding);
+  if (search_forward (string, &binding, &offset) == search_success)
+    return offset;
+  return -1;
 }
 
 /* Return non-zero if STRING is the first text to appear at BINDING. */
@@ -419,7 +426,8 @@ looking_at (char *string, SEARCH_BINDING
 {
   long search_end;
 
-  search_end = search (string, binding);
+  if (search (string, binding, &search_end) != search_success)
+    return 0;
 
   /* If the string was not found, SEARCH_END is -1.  If the string was found,
      but not right away, SEARCH_END is != binding->start.  Otherwise, the
Index: info/search.h
===================================================================
RCS file: /cvsroot/texinfo/texinfo/info/search.h,v
retrieving revision 1.8
diff -p -u -r1.8 search.h
--- info/search.h       11 Jun 2008 09:02:11 -0000      1.8
+++ info/search.h       23 Jan 2009 09:12:14 -0000
@@ -42,13 +42,26 @@ typedef struct {
 #define S_FoldCase      0x01    /* Set means fold case in searches. */
 #define S_SkipDest      0x02    /* Set means return pointing after the dest. */
 
+enum search_result
+  {
+    search_success,             
+    search_not_found,
+    search_failure
+  };
+
 SEARCH_BINDING *make_binding (char *buffer, long int start, long int end);
 SEARCH_BINDING *copy_binding (SEARCH_BINDING *binding);
-extern long search_forward (char *string, SEARCH_BINDING *binding);
-extern long search_backward (char *input_string, SEARCH_BINDING *binding);
-extern long search (char *string, SEARCH_BINDING *binding);
-extern long regexp_search (char *regexp, SEARCH_BINDING *binding, long length,
-                          SEARCH_BINDING *pret);
+extern enum search_result search_forward (char *string,
+                                         SEARCH_BINDING *binding, long *poff);
+extern enum search_result search_backward (char *input_string,
+                                          SEARCH_BINDING *binding,
+                                          long *poff);
+extern enum search_result search (char *string, SEARCH_BINDING *binding,
+                                 long *poff);
+extern enum search_result regexp_search (char *regexp,
+                                        SEARCH_BINDING *binding, long length,
+                                        long *poff,
+                                        SEARCH_BINDING *pret);
 extern int looking_at (char *string, SEARCH_BINDING *binding);
 
 /* Note that STRING_IN_LINE () always returns the offset of the 1st character
Index: info/session.c
===================================================================
RCS file: /cvsroot/texinfo/texinfo/info/session.c,v
retrieving revision 1.45
diff -p -u -r1.45 session.c
--- info/session.c      9 Oct 2008 12:20:28 -0000       1.45
+++ info/session.c      23 Jan 2009 09:12:14 -0000
@@ -2671,16 +2671,14 @@ DECLARE_INFO_COMMAND (info_find_menu, _(
   binding.end = window->node->nodelen;
   binding.flags = S_FoldCase | S_SkipDest;
 
-  position = search (INFO_MENU_LABEL, &binding);
-
-  if (position == -1)
-    info_error (msg_no_menu_node, NULL, NULL);
-  else
+  if (search (INFO_MENU_LABEL, &binding, &position) == search_success)
     {
       window->point = position;
       window_adjust_pagetop (window);
       window->flags |= W_UpdateWindow;
     }
+  else
+    info_error (msg_no_menu_node, NULL, NULL);
 }
 
 /* Visit as many menu items as is possible, each in a separate window. */
@@ -3729,26 +3727,25 @@ file_buffer_of_window (WINDOW *window)
   return NULL;
 }
 
-/* Search for STRING in NODE starting at START.  Return -1 if the string
-   was not found, or the location of the string if it was.  If WINDOW is
-   passed as non-null, set the window's node to be NODE, its point to be
-   the found string, and readjust the window's pagetop.  The DIR argument
-   says which direction to search in.  If it is positive, search
-   forward, else backwards.
+/* Search for STRING in NODE starting at START.  If the string was found,
+   return its location in POFF.  If WINDOW is passed as non-null, set the
+   window's node to be NODE, its point to be the found string, and readjust
+   the window's pagetop.  The DIR argument says which direction to search
+   in.  If it is positive, search forward, else backwards.
 
    The last argument, RESBND, makes sense only when USE_REGEX is set.
    If the regexp search succeeds, RESBND is filled with the final state
    of the search binding.  In particular, its START and END fields contain
    bounds of the found string instance.
 */
-static long
+static enum search_result
 info_search_in_node_internal (char *string, NODE *node, long int start,
                              WINDOW *window, int dir, int case_sensitive,
-                             SEARCH_BINDING *resbnd)
+                             long *poff, SEARCH_BINDING *resbnd)
 {
   SEARCH_BINDING binding;
-  long offset;
-
+  enum search_result result;
+  
   binding.buffer = node->contents;
   binding.start = start;
   binding.end = node->nodelen;
@@ -3769,27 +3766,30 @@ info_search_in_node_internal (char *stri
   if (isearch_is_active)
     binding.flags |= S_SkipDest;
 
-  offset = (use_regex ? 
-            regexp_search (string, &binding, node->nodelen, resbnd):
-            search (string, &binding));
-
-  if (offset != -1 && window)
+  result = (use_regex ? 
+           regexp_search (string, &binding, node->nodelen, poff, resbnd):
+           search (string, &binding, poff));
+  if (result == search_success && window)
     {
       set_remembered_pagetop_and_point (window);
       if (window->node != node)
         window_set_node_of_window (window, node);
-      window->point = offset;
+      window->point = *poff;
       window_adjust_pagetop (window);
     }
-  return offset;
+  return result;
 }
 
 long
 info_search_in_node (char *string, NODE *node, long int start,
                     WINDOW *window, int dir, int case_sensitive)
 {
-  return info_search_in_node_internal (string, node, start,
-                                      window, dir, case_sensitive, NULL);
+  long offset;
+  if (info_search_in_node_internal (string, node, start,
+                                   window, dir, case_sensitive,
+                                   &offset, NULL) == search_success)
+    return offset;
+  return -1;
 }
 
 /* Search NODE, looking for the largest possible match of STRING.  Start the
@@ -3845,7 +3845,8 @@ info_search_internal (char *string, WIND
   FILE_BUFFER *file_buffer;
   char *initial_nodename;
   long ret, start;
-
+  enum search_result result;
+  
   file_buffer = file_buffer_of_window (window);
   initial_nodename = window->node->nodename;
 
@@ -3859,16 +3860,23 @@ info_search_internal (char *string, WIND
        ``finding'' a string that is already under the cursor, anyway.  */
     start = window->point + dir;
   
-  ret = info_search_in_node_internal
-        (string, window->node, start, window, dir,
-         case_sensitive, resbnd);
-  
-  if (ret != -1)
+  result = info_search_in_node_internal
+             (string, window->node, start, window, dir,
+             case_sensitive, &ret, resbnd);
+
+  switch (result)
     {
+    case search_success:
       /* We won! */
       if (!echo_area_is_active && !isearch_is_active)
         window_clear_echo_area ();
       return 0;
+
+    case search_not_found:
+      break;
+      
+    case search_failure:
+      return -1;
     }
   
   start = 0;
@@ -3966,12 +3974,12 @@ info_search_internal (char *string, WIND
           if (dir < 0)
             start = tag->nodelen;
 
-          ret =
+          result =
             info_search_in_node_internal (string, node, start, window, dir,
-                                         case_sensitive, resbnd);
+                                         case_sensitive, &ret, resbnd);
 
           /* Did we find the string in this node? */
-          if (ret != -1)
+          if (result == search_success)
             {
               /* Yes!  We win. */
               remember_window_and_node (window, node);
@@ -3989,7 +3997,8 @@ info_search_internal (char *string, WIND
              our starting point. */
           free (node);
 
-          if (strcmp (initial_nodename, tag->nodename) == 0)
+          if (result == search_failure
+             || strcmp (initial_nodename, tag->nodename) == 0)
             return -1;
         }
     }




reply via email to

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