File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / readline / histsearch.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jul 30 08:16:45 2014 UTC (9 years, 11 months ago) by misho
Branches: readline, MAIN
CVS tags: v6_3p10_cross, v6_3p10, v6_3, p6, HEAD
readline 6.3

    1: /* histsearch.c -- searching the history list. */
    2: 
    3: /* Copyright (C) 1989, 1992-2009 Free Software Foundation, Inc.
    4: 
    5:    This file contains the GNU History Library (History), a set of
    6:    routines for managing the text of previously typed lines.
    7: 
    8:    History is free software: you can redistribute it and/or modify
    9:    it under the terms of the GNU General Public License as published by
   10:    the Free Software Foundation, either version 3 of the License, or
   11:    (at your option) any later version.
   12: 
   13:    History is distributed in the hope that it will be useful,
   14:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   15:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16:    GNU General Public License for more details.
   17: 
   18:    You should have received a copy of the GNU General Public License
   19:    along with History.  If not, see <http://www.gnu.org/licenses/>.
   20: */
   21: 
   22: #define READLINE_LIBRARY
   23: 
   24: #if defined (HAVE_CONFIG_H)
   25: #  include <config.h>
   26: #endif
   27: 
   28: #include <stdio.h>
   29: #if defined (HAVE_STDLIB_H)
   30: #  include <stdlib.h>
   31: #else
   32: #  include "ansi_stdlib.h"
   33: #endif /* HAVE_STDLIB_H */
   34: 
   35: #if defined (HAVE_UNISTD_H)
   36: #  ifdef _MINIX
   37: #    include <sys/types.h>
   38: #  endif
   39: #  include <unistd.h>
   40: #endif
   41: 
   42: #include "history.h"
   43: #include "histlib.h"
   44: 
   45: /* The list of alternate characters that can delimit a history search
   46:    string. */
   47: char *history_search_delimiter_chars = (char *)NULL;
   48: 
   49: static int history_search_internal PARAMS((const char *, int, int));
   50: 
   51: /* Search the history for STRING, starting at history_offset.
   52:    If DIRECTION < 0, then the search is through previous entries, else
   53:    through subsequent.  If ANCHORED is non-zero, the string must
   54:    appear at the beginning of a history line, otherwise, the string
   55:    may appear anywhere in the line.  If the string is found, then
   56:    current_history () is the history entry, and the value of this
   57:    function is the offset in the line of that history entry that the
   58:    string was found in.  Otherwise, nothing is changed, and a -1 is
   59:    returned. */
   60: 
   61: static int
   62: history_search_internal (string, direction, anchored)
   63:      const char *string;
   64:      int direction, anchored;
   65: {
   66:   register int i, reverse;
   67:   register char *line;
   68:   register int line_index;
   69:   int string_len;
   70:   HIST_ENTRY **the_history; 	/* local */
   71: 
   72:   i = history_offset;
   73:   reverse = (direction < 0);
   74: 
   75:   /* Take care of trivial cases first. */
   76:   if (string == 0 || *string == '\0')
   77:     return (-1);
   78: 
   79:   if (!history_length || ((i >= history_length) && !reverse))
   80:     return (-1);
   81: 
   82:   if (reverse && (i >= history_length))
   83:     i = history_length - 1;
   84: 
   85: #define NEXT_LINE() do { if (reverse) i--; else i++; } while (0)
   86: 
   87:   the_history = history_list ();
   88:   string_len = strlen (string);
   89:   while (1)
   90:     {
   91:       /* Search each line in the history list for STRING. */
   92: 
   93:       /* At limit for direction? */
   94:       if ((reverse && i < 0) || (!reverse && i == history_length))
   95: 	return (-1);
   96: 
   97:       line = the_history[i]->line;
   98:       line_index = strlen (line);
   99: 
  100:       /* If STRING is longer than line, no match. */
  101:       if (string_len > line_index)
  102: 	{
  103: 	  NEXT_LINE ();
  104: 	  continue;
  105: 	}
  106: 
  107:       /* Handle anchored searches first. */
  108:       if (anchored == ANCHORED_SEARCH)
  109: 	{
  110: 	  if (STREQN (string, line, string_len))
  111: 	    {
  112: 	      history_offset = i;
  113: 	      return (0);
  114: 	    }
  115: 
  116: 	  NEXT_LINE ();
  117: 	  continue;
  118: 	}
  119: 
  120:       /* Do substring search. */
  121:       if (reverse)
  122: 	{
  123: 	  line_index -= string_len;
  124: 
  125: 	  while (line_index >= 0)
  126: 	    {
  127: 	      if (STREQN (string, line + line_index, string_len))
  128: 		{
  129: 		  history_offset = i;
  130: 		  return (line_index);
  131: 		}
  132: 	      line_index--;
  133: 	    }
  134: 	}
  135:       else
  136: 	{
  137: 	  register int limit;
  138: 
  139: 	  limit = line_index - string_len + 1;
  140: 	  line_index = 0;
  141: 
  142: 	  while (line_index < limit)
  143: 	    {
  144: 	      if (STREQN (string, line + line_index, string_len))
  145: 		{
  146: 		  history_offset = i;
  147: 		  return (line_index);
  148: 		}
  149: 	      line_index++;
  150: 	    }
  151: 	}
  152:       NEXT_LINE ();
  153:     }
  154: }
  155: 
  156: /* Do a non-anchored search for STRING through the history in DIRECTION. */
  157: int
  158: history_search (string, direction)
  159:      const char *string;
  160:      int direction;
  161: {
  162:   return (history_search_internal (string, direction, NON_ANCHORED_SEARCH));
  163: }
  164: 
  165: /* Do an anchored search for string through the history in DIRECTION. */
  166: int
  167: history_search_prefix (string, direction)
  168:      const char *string;
  169:      int direction;
  170: {
  171:   return (history_search_internal (string, direction, ANCHORED_SEARCH));
  172: }
  173: 
  174: /* Search for STRING in the history list.  DIR is < 0 for searching
  175:    backwards.  POS is an absolute index into the history list at
  176:    which point to begin searching. */
  177: int
  178: history_search_pos (string, dir, pos)
  179:      const char *string;
  180:      int dir, pos;
  181: {
  182:   int ret, old;
  183: 
  184:   old = where_history ();
  185:   history_set_pos (pos);
  186:   if (history_search (string, dir) == -1)
  187:     {
  188:       history_set_pos (old);
  189:       return (-1);
  190:     }
  191:   ret = where_history ();
  192:   history_set_pos (old);
  193:   return ret;
  194: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>