commit bash-20161118 snapshot

This commit is contained in:
Chet Ramey
2016-11-21 14:50:59 -05:00
parent 5c1f20964a
commit 31a8d95a37
14 changed files with 530 additions and 34 deletions
+8 -2
View File
@@ -69,11 +69,17 @@ extern char *strchr ();
#define NO_PREV_SUBST 4
/* Possible definitions for history starting point specification. */
#define ANCHORED_SEARCH 1
#define NON_ANCHORED_SEARCH 0
#define NON_ANCHORED_SEARCH 0
#define ANCHORED_SEARCH 0x01
#define PATTERN_SEARCH 0x02
/* Possible definitions for what style of writing the history file we want. */
#define HISTORY_APPEND 0
#define HISTORY_OVERWRITE 1
/* internal extern function declarations used by other parts of the library */
/* histsearch.c */
extern int _hs_history_patsearch PARAMS((const char *, int, int));
#endif /* !_HISTLIB_H_ */
+94 -5
View File
@@ -39,8 +39,13 @@
# include <unistd.h>
#endif
#if defined (HAVE_FNMATCH)
# include <fnmatch.h>
#endif
#include "history.h"
#include "histlib.h"
#include "xmalloc.h"
/* The list of alternate characters that can delimit a history search
string. */
@@ -59,18 +64,24 @@ static int history_search_internal PARAMS((const char *, int, int));
returned. */
static int
history_search_internal (string, direction, anchored)
history_search_internal (string, direction, flags)
const char *string;
int direction, anchored;
int direction, flags;
{
register int i, reverse;
register char *line;
register int line_index;
int string_len;
int string_len, anchored, patsearch;
HIST_ENTRY **the_history; /* local */
i = history_offset;
reverse = (direction < 0);
anchored = (flags & ANCHORED_SEARCH);
#if defined (HAVE_FNMATCH)
patsearch = (flags & PATTERN_SEARCH);
#else
patsearch = 0;
#endif
/* Take care of trivial cases first. */
if (string == 0 || *string == '\0')
@@ -98,7 +109,7 @@ history_search_internal (string, direction, anchored)
line_index = strlen (line);
/* If STRING is longer than line, no match. */
if (string_len > line_index)
if (patsearch == 0 && (string_len > line_index))
{
NEXT_LINE ();
continue;
@@ -107,6 +118,17 @@ history_search_internal (string, direction, anchored)
/* Handle anchored searches first. */
if (anchored == ANCHORED_SEARCH)
{
#if defined (HAVE_FNMATCH)
if (patsearch)
{
if (fnmatch (string, line, 0) == 0)
{
history_offset = i;
return (0);
}
}
else
#endif
if (STREQN (string, line, string_len))
{
history_offset = i;
@@ -120,10 +142,21 @@ history_search_internal (string, direction, anchored)
/* Do substring search. */
if (reverse)
{
line_index -= string_len;
line_index -= (patsearch == 0) ? string_len : 1;
while (line_index >= 0)
{
#if defined (HAVE_FNMATCH)
if (patsearch)
{
if (fnmatch (string, line + line_index, 0) == 0)
{
history_offset = i;
return (line_index);
}
}
else
#endif
if (STREQN (string, line + line_index, string_len))
{
history_offset = i;
@@ -141,6 +174,17 @@ history_search_internal (string, direction, anchored)
while (line_index < limit)
{
#if defined (HAVE_FNMATCH)
if (patsearch)
{
if (fnmatch (string, line + line_index, 0) == 0)
{
history_offset = i;
return (line_index);
}
}
else
#endif
if (STREQN (string, line + line_index, string_len))
{
history_offset = i;
@@ -153,6 +197,51 @@ history_search_internal (string, direction, anchored)
}
}
int
_hs_history_patsearch (string, direction, flags)
const char *string;
int direction, flags;
{
char *pat;
size_t len;
int ret, unescaped_backslash;
#if defined (HAVE_FNMATCH)
/* Assume that the string passed does not have a leading `^' and any
anchored search request is captured in FLAGS */
len = strlen (string);
ret = len - 1;
/* fnmatch is required to reject a pattern that ends with an unescaped
backslash */
if (unescaped_backslash = (string[ret] == '\\'))
{
while (ret > 0 && string[--ret] == '\\')
unescaped_backslash = 1 - unescaped_backslash;
}
if (unescaped_backslash)
return -1;
pat = (char *)xmalloc (len + 2);
/* Attempt to reduce the number of searches by tacking a `*' onto the end
of a pattern that doesn't have one. Assume a pattern that ends in a
backslash contains an even number of trailing backslashes; we check
above */
strcpy (pat, string);
if (pat[len - 1] != '*')
{
pat[len] = '*'; /* XXX */
pat[len+1] = '\0';
}
#else
pat = string;
#endif
ret = history_search_internal (pat, direction, flags|PATTERN_SEARCH);
if (pat != string)
free (pat);
return ret;
}
/* Do a non-anchored search for STRING through the history in DIRECTION. */
int
history_search (string, direction)
+1
View File
@@ -64,6 +64,7 @@
#define SF_FOUND 0x02
#define SF_FAILED 0x04
#define SF_CHGKMAP 0x08
#define SF_PATTERN 0x10 /* unused so far */
typedef struct __rl_search_context
{
+57 -17
View File
@@ -1,6 +1,6 @@
/* search.c - code for non-incremental searching in emacs and vi modes. */
/* Copyright (C) 1992-2015 Free Software Foundation, Inc.
/* Copyright (C) 1992-2016 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -73,8 +73,8 @@ static char *history_search_string;
static int history_string_size;
static void make_history_line_current PARAMS((HIST_ENTRY *));
static int noninc_search_from_pos PARAMS((char *, int, int));
static int noninc_dosearch PARAMS((char *, int));
static int noninc_search_from_pos PARAMS((char *, int, int, int, int *));
static int noninc_dosearch PARAMS((char *, int, int));
static int noninc_search PARAMS((int, int));
static int rl_history_search_internal PARAMS((int, int));
static void rl_history_search_reinit PARAMS((int));
@@ -112,11 +112,13 @@ make_history_line_current (entry)
for STRING. DIR < 0 means to search backwards through the history list,
DIR >= 0 means to search forward. */
static int
noninc_search_from_pos (string, pos, dir)
noninc_search_from_pos (string, pos, dir, flags, ncp)
char *string;
int pos, dir;
int pos, dir, flags;
int *ncp;
{
int ret, old;
int ret, old, sflags;
char *s;
if (pos < 0)
return -1;
@@ -126,12 +128,28 @@ noninc_search_from_pos (string, pos, dir)
return -1;
RL_SETSTATE(RL_STATE_SEARCH);
if (*string == '^')
/* These functions return the match offset in the line; history_offset gives
the matching line in the history list */
if (flags & SF_PATTERN)
{
s = string;
sflags = 0; /* Non-anchored search */
if (*s == '^')
{
sflags |= ANCHORED_SEARCH;
s++;
}
ret = _hs_history_patsearch (string, dir, sflags);
}
else if (*string == '^')
ret = history_search_prefix (string + 1, dir);
else
ret = history_search (string, dir);
RL_UNSETSTATE(RL_STATE_SEARCH);
if (ncp)
*ncp = ret; /* caller will catch -1 to indicate no-op */
if (ret != -1)
ret = where_history ();
@@ -143,9 +161,10 @@ noninc_search_from_pos (string, pos, dir)
search is backwards through previous entries, else through subsequent
entries. Returns 1 if the search was successful, 0 otherwise. */
static int
noninc_dosearch (string, dir)
noninc_dosearch (string, dir, flags)
char *string;
int dir;
int flags;
{
int oldpos, pos;
HIST_ENTRY *entry;
@@ -156,7 +175,7 @@ noninc_dosearch (string, dir)
return 0;
}
pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir);
pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir, flags, (int *)0);
if (pos == -1)
{
/* Search failed, current history position unchanged. */
@@ -197,6 +216,10 @@ _rl_nsearch_init (dir, pchar)
cxt = _rl_scxt_alloc (RL_SEARCH_NSEARCH, 0);
if (dir < 0)
cxt->sflags |= SF_REVERSE; /* not strictly needed */
#if defined (VI_MODE)
if (VI_COMMAND_MODE() && (pchar == '?' || pchar == '/'))
cxt->sflags |= SF_PATTERN;
#endif
cxt->direction = dir;
cxt->history_pos = cxt->save_line;
@@ -340,7 +363,7 @@ _rl_nsearch_dosearch (cxt)
}
rl_restore_prompt ();
return (noninc_dosearch (noninc_search_string, cxt->direction));
return (noninc_dosearch (noninc_search_string, cxt->direction, cxt->sflags&SF_PATTERN));
}
/* Search non-interactively through the history list. DIR < 0 means to
@@ -400,7 +423,8 @@ rl_noninc_reverse_search (count, key)
}
/* Search forward through the history list for the last string searched
for. If there is no saved search string, abort. */
for. If there is no saved search string, abort. If the vi-mode code
calls this, KEY will be `N'. */
int
rl_noninc_forward_search_again (count, key)
int count, key;
@@ -412,12 +436,18 @@ rl_noninc_forward_search_again (count, key)
rl_ding ();
return (1);
}
r = noninc_dosearch (noninc_search_string, 1);
#if defined (VI_MODE)
if (VI_COMMAND_MODE() && key == 'N')
r = noninc_dosearch (noninc_search_string, 1, SF_PATTERN);
else
#endif
r = noninc_dosearch (noninc_search_string, 1, 0);
return (r != 1);
}
/* Reverse search in the history list for the last string searched
for. If there is no saved search string, abort. */
for. If there is no saved search string, abort. If the vi-mode code
calls this, KEY will be `n'. */
int
rl_noninc_reverse_search_again (count, key)
int count, key;
@@ -429,7 +459,12 @@ rl_noninc_reverse_search_again (count, key)
rl_ding ();
return (1);
}
r = noninc_dosearch (noninc_search_string, -1);
#if defined (VI_MODE)
if (VI_COMMAND_MODE() && key == 'n')
r = noninc_dosearch (noninc_search_string, -1, SF_PATTERN);
else
#endif
r = noninc_dosearch (noninc_search_string, -1, 0);
return (r != 1);
}
@@ -455,7 +490,7 @@ rl_history_search_internal (count, dir)
int count, dir;
{
HIST_ENTRY *temp;
int ret, oldpos;
int ret, oldpos, newcol;
char *t;
rl_maybe_save_line ();
@@ -469,7 +504,7 @@ rl_history_search_internal (count, dir)
while (count)
{
RL_CHECK_SIGNALS ();
ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir);
ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir, 0, &newcol);
if (ret == -1)
break;
@@ -512,12 +547,17 @@ rl_history_search_internal (count, dir)
/* Copy the line we found into the current line buffer. */
make_history_line_current (temp);
/* decide where to put rl_point -- need to change this for pattern search */
if (rl_history_search_flags & ANCHORED_SEARCH)
rl_point = rl_history_search_len; /* easy case */
else
{
t = strstr (rl_line_buffer, history_search_string);
#if 0
t = strstr (rl_line_buffer, history_search_string); /* XXX */
rl_point = t ? (int)(t - rl_line_buffer) + rl_history_search_len : rl_end;
#else
rl_point = (newcol >= 0) ? newcol : rl_end;
#endif
}
rl_mark = rl_end;