Annotation of embedaddon/readline/histsearch.c, revision 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>