The Library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 1, or (at your option)
+ the Free Software Foundation; either version 2, or (at your option)
any later version.
The Library is distributed in the hope that it will be useful, but
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
- 675 Mass Ave, Cambridge, MA 02139, USA. */
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "history.h"
#include "histlib.h"
+#include "rlshell.h"
+#include "xmalloc.h"
+
#define HISTORY_WORD_DELIMITERS " \t\n;&()|<>"
#define HISTORY_QUOTE_CHARACTERS "\"'`"
+typedef int _hist_search_func_t __P((const char *, int));
+
static char error_pointer;
static char *subst_lhs;
static int subst_lhs_len;
static int subst_rhs_len;
-static char *get_history_word_specifier ();
-static char *history_find_word ();
-
-extern int history_offset;
+static char *get_history_word_specifier __P((char *, char *, int *));
+static char *history_find_word __P((char *, int));
-extern char *single_quote ();
-static char *quote_breaks ();
-
-extern char *xmalloc (), *xrealloc ();
+static char *quote_breaks __P((char *));
/* Variables exported by this file. */
/* The character that represents the start of a history expansion
The default is 0. */
int history_quotes_inhibit_expansion = 0;
+/* Used to split words by history_tokenize_internal. */
+char *history_word_delimiters = HISTORY_WORD_DELIMITERS;
+
/* If set, this points to a function that is called to verify that a
particular history expansion should be performed. */
-Function *history_inhibit_expansion_function;
+rl_linebuf_func_t *history_inhibit_expansion_function;
/* **************************************************************** */
/* */
line = get_history_event ("!echo:p", &index, 0); */
char *
get_history_event (string, caller_index, delimiting_quote)
- char *string;
+ const char *string;
int *caller_index;
int delimiting_quote;
{
register char c;
HIST_ENTRY *entry;
int which, sign, local_index, substring_okay;
- Function *search_func;
+ _hist_search_func_t *search_func;
char *temp;
/* The event can be specified in a number of ways.
char *s;
int start, current, errtype;
{
- char *temp, *emsg;
+ char *temp;
+ const char *emsg;
int ll, elen;
ll = current - start;
emsg = "unrecognized history modifier";
elen = 29;
break;
+ case NO_PREV_SUBST:
+ emsg = "no previous substitution";
+ elen = 24;
+ break;
default:
emsg = "unknown expansion error";
elen = 23;
case '&':
case 's':
{
- char *new_event, *t;
+ char *new_event;
int delimiter, failed, si, l_temp;
if (c == 's')
}
}
- /* If there is no lhs, the substitution can't succeed. */
- if (subst_lhs_len == 0)
- {
- *ret_string = hist_error (string, starting_index, i, SUBST_FAILED);
- free (result);
- free (temp);
- return -1;
- }
-
FREE (subst_rhs);
subst_rhs = get_subst_pattern (string, &i, delimiter, 1, &subst_rhs_len);
else
i += 2;
+ /* If there is no lhs, the substitution can't succeed. */
+ if (subst_lhs_len == 0)
+ {
+ *ret_string = hist_error (string, starting_index, i, NO_PREV_SUBST);
+ free (result);
+ free (temp);
+ return -1;
+ }
+
l_temp = strlen (temp);
/* Ignore impossible cases. */
if (subst_lhs_len > l_temp)
char *x;
if (want_quotes == 'q')
- x = single_quote (temp);
+ x = sh_single_quote (temp);
else if (want_quotes == 'x')
x = quote_breaks (temp);
else
/* Used when adding the string. */
char *temp;
+ if (output == 0)
+ return 0;
+
/* Setting the history expansion character to 0 inhibits all
history expansion. */
if (history_expansion_char == 0)
history expansion performed on it.
Skip the rest of the line and break out of the loop. */
if (history_comment_char && string[i] == history_comment_char &&
- (i == 0 || member (string[i - 1], HISTORY_WORD_DELIMITERS)))
+ (i == 0 || member (string[i - 1], history_word_delimiters)))
{
while (string[i])
i++;
}
case -2: /* history_comment_char */
- if (i == 0 || member (string[i - 1], HISTORY_WORD_DELIMITERS))
+ if (i == 0 || member (string[i - 1], history_word_delimiters))
{
temp = xmalloc (l - i + 1);
strcpy (temp, string + i);
char *
history_arg_extract (first, last, string)
int first, last;
- char *string;
+ const char *string;
{
register int i, len;
char *result;
*INDP. */
static char **
history_tokenize_internal (string, wind, indp)
- char *string;
+ const char *string;
int wind, *indp;
{
char **result;
register int i, start, result_index, size;
int len, delimiter;
+ /* If we're searching for a string that's not part of a word (e.g., " "),
+ make sure we set *INDP to a reasonable value. */
+ if (indp && wind != -1)
+ *indp = -1;
+
/* Get a token, and stuff it into RESULT. The tokens are split
exactly where the shell would split them. */
for (i = result_index = size = 0, result = (char **)NULL; string[i]; )
continue;
}
- if (!delimiter && (member (string[i], HISTORY_WORD_DELIMITERS)))
+ if (!delimiter && (member (string[i], history_word_delimiters)))
break;
if (!delimiter && member (string[i], HISTORY_QUOTE_CHARACTERS))
parsed out of STRING. */
char **
history_tokenize (string)
- char *string;
+ const char *string;
{
return (history_tokenize_internal (string, -1, (int *)NULL));
}
int i, wind;
words = history_tokenize_internal (line, ind, &wind);
- if (wind == -1)
+ if (wind == -1 || words == 0)
return ((char *)NULL);
s = words[wind];
for (i = 0; i < wind; i++)