Annotation of embedaddon/readline/histsearch.c, revision 1.1.1.1

1.1       misho       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>