diff options
Diffstat (limited to 'cmd-line-utils')
41 files changed, 2856 insertions, 1312 deletions
diff --git a/cmd-line-utils/libedit/Makefile.am b/cmd-line-utils/libedit/Makefile.am index a3d73a7082a..0a8458e51f7 100644 --- a/cmd-line-utils/libedit/Makefile.am +++ b/cmd-line-utils/libedit/Makefile.am @@ -20,7 +20,7 @@ EXTRA_libedit_a_SOURCES = np/unvis.c np/strlcpy.c np/vis.c np/strlcat.c \ libedit_a_LIBADD = @LIBEDIT_LOBJECTS@ libedit_a_DEPENDENCIES = @LIBEDIT_LOBJECTS@ -pkginclude_HEADERS = readline/readline.h +pkginclude_HEADERS = editline/readline.h noinst_HEADERS = chared.h el.h histedit.h key.h parse.h refresh.h sig.h \ sys.h tokenizer.h config.h hist.h map.h prompt.h read.h \ diff --git a/cmd-line-utils/libedit/chared.c b/cmd-line-utils/libedit/chared.c index 62a407e66a8..21fc8bc2c1d 100644 --- a/cmd-line-utils/libedit/chared.c +++ b/cmd-line-utils/libedit/chared.c @@ -1,4 +1,4 @@ -/* $NetBSD: chared.c,v 1.18 2002/11/20 16:50:08 christos Exp $ */ +/* $NetBSD: chared.c,v 1.22 2004/08/13 12:10:38 mycroft Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,14 +32,7 @@ * SUCH DAMAGE. */ -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: chared.c,v 1.18 2002/11/20 16:50:08 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ +#include <config.h> /* * chared.c: Character editor utilities @@ -62,13 +51,13 @@ cv_undo(EditLine *el) { c_undo_t *vu = &el->el_chared.c_undo; c_redo_t *r = &el->el_chared.c_redo; - int size; + uint size; /* Save entire line for undo */ size = el->el_line.lastchar - el->el_line.buffer; vu->len = size; vu->cursor = el->el_line.cursor - el->el_line.buffer; - memcpy(vu->buf, el->el_line.buffer, (size_t)size); + memcpy(vu->buf, el->el_line.buffer, size); /* save command info for redo */ r->count = el->el_state.doingarg ? el->el_state.argument : 0; @@ -139,6 +128,21 @@ c_delafter(EditLine *el, int num) } +/* c_delafter1(): + * Delete the character after the cursor, do not yank + */ +protected void +c_delafter1(EditLine *el) +{ + char *cp; + + for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++) + *cp = cp[1]; + + el->el_line.lastchar--; +} + + /* c_delbefore(): * Delete num characters before the cursor */ @@ -167,6 +171,21 @@ c_delbefore(EditLine *el, int num) } +/* c_delbefore1(): + * Delete the character before the cursor, do not yank + */ +protected void +c_delbefore1(EditLine *el) +{ + char *cp; + + for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++) + *cp = cp[1]; + + el->el_line.lastchar--; +} + + /* ce__isword(): * Return if p is part of a word according to emacs */ @@ -460,8 +479,8 @@ ch_init(EditLine *el) el->el_state.argument = 1; el->el_state.lastcmd = ED_UNASSIGNED; - el->el_chared.c_macro.nline = NULL; el->el_chared.c_macro.level = -1; + el->el_chared.c_macro.offset = 0; el->el_chared.c_macro.macro = (char **) el_malloc(EL_MAXMACRO * sizeof(char *)); if (el->el_chared.c_macro.macro == NULL) @@ -582,7 +601,7 @@ ch_enlargebufs(el, addlen) return 0; /* Safe to set enlarged buffer size */ - el->el_line.limit = &newbuffer[newsz - EL_LEAVE]; + el->el_line.limit = &el->el_line.buffer[newsz - EL_LEAVE]; return 1; } diff --git a/cmd-line-utils/libedit/chared.h b/cmd-line-utils/libedit/chared.h index d2e6f742413..2dd0a5795c7 100644 --- a/cmd-line-utils/libedit/chared.h +++ b/cmd-line-utils/libedit/chared.h @@ -1,4 +1,4 @@ -/* $NetBSD: chared.h,v 1.11 2002/11/20 16:50:08 christos Exp $ */ +/* $NetBSD: chared.h,v 1.14 2004/08/13 12:10:39 mycroft Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -66,8 +62,8 @@ typedef struct c_macro_t { int level; + int offset; char **macro; - char *nline; } c_macro_t; /* @@ -158,7 +154,9 @@ protected char *c__next_word(char *, char *, int, int (*)(int)); protected char *c__prev_word(char *, char *, int, int (*)(int)); protected void c_insert(EditLine *, int); protected void c_delbefore(EditLine *, int); +protected void c_delbefore1(EditLine *); protected void c_delafter(EditLine *, int); +protected void c_delafter1(EditLine *); protected int c_gets(EditLine *, char *, const char *); protected int c_hpos(EditLine *); diff --git a/cmd-line-utils/libedit/common.c b/cmd-line-utils/libedit/common.c index f290057568a..81bf9bf29ff 100644 --- a/cmd-line-utils/libedit/common.c +++ b/cmd-line-utils/libedit/common.c @@ -1,4 +1,4 @@ -/* $NetBSD: common.c,v 1.14 2002/11/20 16:50:08 christos Exp $ */ +/* $NetBSD: common.c,v 1.16 2003/08/07 16:44:30 agc Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,14 +32,7 @@ * SUCH DAMAGE. */ -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: common.c,v 1.14 2002/11/20 16:50:08 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ +#include <config.h> /* * common.c: Common Editor functions @@ -56,7 +45,7 @@ __RCSID("$NetBSD: common.c,v 1.14 2002/11/20 16:50:08 christos Exp $"); */ protected el_action_t /*ARGSUSED*/ -ed_end_of_file(EditLine *el, int c __attribute__((unused))) +ed_end_of_file(EditLine *el, int c __attribute__((__unused__))) { re_goto_bottom(el); @@ -113,7 +102,7 @@ ed_insert(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -ed_delete_prev_word(EditLine *el, int c __attribute__((unused))) +ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__))) { char *cp, *p, *kp; @@ -141,7 +130,7 @@ ed_delete_prev_word(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -ed_delete_next_char(EditLine *el, int c __attribute__((unused))) +ed_delete_next_char(EditLine *el, int c __attribute__((__unused__))) { #ifdef notdef /* XXX */ #define EL el->el_line @@ -192,7 +181,7 @@ ed_delete_next_char(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -ed_kill_line(EditLine *el, int c __attribute__((unused))) +ed_kill_line(EditLine *el, int c __attribute__((__unused__))) { char *kp, *cp; @@ -213,7 +202,7 @@ ed_kill_line(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -ed_move_to_end(EditLine *el, int c __attribute__((unused))) +ed_move_to_end(EditLine *el, int c __attribute__((__unused__))) { el->el_line.cursor = el->el_line.lastchar; @@ -236,7 +225,7 @@ ed_move_to_end(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -ed_move_to_beg(EditLine *el, int c __attribute__((unused))) +ed_move_to_beg(EditLine *el, int c __attribute__((__unused__))) { el->el_line.cursor = el->el_line.buffer; @@ -285,7 +274,7 @@ ed_transpose_chars(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -ed_next_char(EditLine *el, int c __attribute__((unused))) +ed_next_char(EditLine *el, int c __attribute__((__unused__))) { char *lim = el->el_line.lastchar; @@ -314,7 +303,7 @@ ed_next_char(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -ed_prev_word(EditLine *el, int c __attribute__((unused))) +ed_prev_word(EditLine *el, int c __attribute__((__unused__))) { if (el->el_line.cursor == el->el_line.buffer) @@ -340,7 +329,7 @@ ed_prev_word(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -ed_prev_char(EditLine *el, int c __attribute__((unused))) +ed_prev_char(EditLine *el, int c __attribute__((__unused__))) { if (el->el_line.cursor > el->el_line.buffer) { @@ -437,8 +426,7 @@ ed_argument_digit(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -ed_unassigned(EditLine *el __attribute__((unused)), - int c __attribute__((unused))) +ed_unassigned(EditLine *el, int c __attribute__((__unused__))) { return (CC_ERROR); @@ -455,8 +443,8 @@ ed_unassigned(EditLine *el __attribute__((unused)), */ protected el_action_t /*ARGSUSED*/ -ed_tty_sigint(EditLine *el __attribute__((unused)), - int c __attribute__((unused))) +ed_tty_sigint(EditLine *el __attribute__((__unused__)), + int c __attribute__((__unused__))) { return (CC_NORM); @@ -469,8 +457,8 @@ ed_tty_sigint(EditLine *el __attribute__((unused)), */ protected el_action_t /*ARGSUSED*/ -ed_tty_dsusp(EditLine *el __attribute__((unused)), - int c __attribute__((unused))) +ed_tty_dsusp(EditLine *el __attribute__((__unused__)), + int c __attribute__((__unused__))) { return (CC_NORM); @@ -483,8 +471,8 @@ ed_tty_dsusp(EditLine *el __attribute__((unused)), */ protected el_action_t /*ARGSUSED*/ -ed_tty_flush_output(EditLine *el __attribute__((unused)), - int c __attribute__((unused))) +ed_tty_flush_output(EditLine *el __attribute__((__unused__)), + int c __attribute__((__unused__))) { return (CC_NORM); @@ -497,8 +485,8 @@ ed_tty_flush_output(EditLine *el __attribute__((unused)), */ protected el_action_t /*ARGSUSED*/ -ed_tty_sigquit(EditLine *el __attribute__((unused)), - int c __attribute__((unused))) +ed_tty_sigquit(EditLine *el __attribute__((__unused__)), + int c __attribute__((__unused__))) { return (CC_NORM); @@ -511,8 +499,8 @@ ed_tty_sigquit(EditLine *el __attribute__((unused)), */ protected el_action_t /*ARGSUSED*/ -ed_tty_sigtstp(EditLine *el __attribute__((unused)), - int c __attribute__((unused))) +ed_tty_sigtstp(EditLine *el __attribute__((__unused__)), + int c __attribute__((__unused__))) { return (CC_NORM); @@ -525,8 +513,8 @@ ed_tty_sigtstp(EditLine *el __attribute__((unused)), */ protected el_action_t /*ARGSUSED*/ -ed_tty_stop_output(EditLine *el __attribute__((unused)), - int c __attribute__((unused))) +ed_tty_stop_output(EditLine *el __attribute__((__unused__)), + int c __attribute__((__unused__))) { return (CC_NORM); @@ -539,8 +527,8 @@ ed_tty_stop_output(EditLine *el __attribute__((unused)), */ protected el_action_t /*ARGSUSED*/ -ed_tty_start_output(EditLine *el __attribute__((unused)), - int c __attribute__((unused))) +ed_tty_start_output(EditLine *el __attribute__((__unused__)), + int c __attribute__((__unused__))) { return (CC_NORM); @@ -553,7 +541,7 @@ ed_tty_start_output(EditLine *el __attribute__((unused)), */ protected el_action_t /*ARGSUSED*/ -ed_newline(EditLine *el, int c __attribute__((unused))) +ed_newline(EditLine *el, int c __attribute__((__unused__))) { re_goto_bottom(el); @@ -569,7 +557,7 @@ ed_newline(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -ed_delete_prev_char(EditLine *el, int c __attribute__((unused))) +ed_delete_prev_char(EditLine *el, int c __attribute__((__unused__))) { if (el->el_line.cursor <= el->el_line.buffer) @@ -589,7 +577,7 @@ ed_delete_prev_char(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -ed_clear_screen(EditLine *el, int c __attribute__((unused))) +ed_clear_screen(EditLine *el, int c __attribute__((__unused__))) { term_clear_screen(el); /* clear the whole real screen */ @@ -604,8 +592,8 @@ ed_clear_screen(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -ed_redisplay(EditLine *el __attribute__((unused)), - int c __attribute__((unused))) +ed_redisplay(EditLine *el __attribute__((__unused__)), + int c __attribute__((__unused__))) { return (CC_REDISPLAY); @@ -618,7 +606,7 @@ ed_redisplay(EditLine *el __attribute__((unused)), */ protected el_action_t /*ARGSUSED*/ -ed_start_over(EditLine *el, int c __attribute__((unused))) +ed_start_over(EditLine *el, int c __attribute__((__unused__))) { ch_reset(el); @@ -632,8 +620,8 @@ ed_start_over(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -ed_sequence_lead_in(EditLine *el __attribute__((unused)), - int c __attribute__((unused))) +ed_sequence_lead_in(EditLine *el __attribute__((__unused__)), + int c __attribute__((__unused__))) { return (CC_NORM); @@ -646,7 +634,7 @@ ed_sequence_lead_in(EditLine *el __attribute__((unused)), */ protected el_action_t /*ARGSUSED*/ -ed_prev_history(EditLine *el, int c __attribute__((unused))) +ed_prev_history(EditLine *el, int c __attribute__((__unused__))) { char beep = 0; int sv_event = el->el_history.eventno; @@ -684,7 +672,7 @@ ed_prev_history(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -ed_next_history(EditLine *el, int c __attribute__((unused))) +ed_next_history(EditLine *el, int c __attribute__((__unused__))) { el_action_t beep = CC_REFRESH, rval; @@ -711,7 +699,7 @@ ed_next_history(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -ed_search_prev_history(EditLine *el, int c __attribute__((unused))) +ed_search_prev_history(EditLine *el, int c __attribute__((__unused__))) { const char *hp; int h; @@ -779,7 +767,7 @@ ed_search_prev_history(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -ed_search_next_history(EditLine *el, int c __attribute__((unused))) +ed_search_next_history(EditLine *el, int c __attribute__((__unused__))) { const char *hp; int h; @@ -833,7 +821,7 @@ ed_search_next_history(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -ed_prev_line(EditLine *el, int c __attribute__((unused))) +ed_prev_line(EditLine *el, int c __attribute__((__unused__))) { char *ptr; int nchars = c_hpos(el); @@ -876,7 +864,7 @@ ed_prev_line(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -ed_next_line(EditLine *el, int c __attribute__((unused))) +ed_next_line(EditLine *el, int c __attribute__((__unused__))) { char *ptr; int nchars = c_hpos(el); @@ -910,7 +898,7 @@ ed_next_line(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -ed_command(EditLine *el, int c __attribute__((unused))) +ed_command(EditLine *el, int c __attribute__((__unused__))) { char tmpbuf[EL_BUFSIZ]; int tmplen; diff --git a/cmd-line-utils/libedit/readline/readline.h b/cmd-line-utils/libedit/editline/readline.h index 7485dde4052..902179c208a 100644 --- a/cmd-line-utils/libedit/readline/readline.h +++ b/cmd-line-utils/libedit/editline/readline.h @@ -1,4 +1,4 @@ -/* $NetBSD: readline.h,v 1.1 2001/01/05 21:15:50 jdolecek Exp $ */ +/* $NetBSD: readline.h,v 1.12 2004/09/08 18:15:37 christos Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -36,7 +36,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _READLINE_H_ -#define _READLINE_H_ +#define _READLINE_H_ #include <sys/types.h> @@ -48,11 +48,45 @@ typedef void VFunction(void); typedef char *CPFunction(const char *, int); typedef char **CPPFunction(const char *, int, int); +typedef void *histdata_t; + typedef struct _hist_entry { const char *line; - const char *data; + histdata_t *data; } HIST_ENTRY; +typedef struct _keymap_entry { + char type; +#define ISFUNC 0 +#define ISKMAP 1 +#define ISMACR 2 + Function *function; +} KEYMAP_ENTRY; + +#define KEYMAP_SIZE 256 + +typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[KEYMAP_SIZE]; +typedef KEYMAP_ENTRY *Keymap; + +#define control_character_threshold 0x20 +#define control_character_bit 0x40 + +#ifndef CTRL +#include <sys/ioctl.h> +#ifdef __GLIBC__ +#include <sys/ttydefaults.h> +#endif +#ifndef CTRL +#define CTRL(c) ((c) & 037) +#endif +#endif +#ifndef UNCTRL +#define UNCTRL(c) (((c) - 'a' + 'A')|control_character_bit) +#endif + +#define RUBOUT 0x7f +#define ABORT_CHAR CTRL('G') + /* global variables used by readline enabled applications */ #ifdef __cplusplus extern "C" { @@ -68,12 +102,31 @@ extern int max_input_history; extern char *rl_basic_word_break_characters; extern char *rl_completer_word_break_characters; extern char *rl_completer_quote_characters; -extern CPFunction *rl_completion_entry_function; +extern Function *rl_completion_entry_function; extern CPPFunction *rl_attempted_completion_function; extern int rl_completion_type; extern int rl_completion_query_items; extern char *rl_special_prefixes; extern int rl_completion_append_character; +extern int rl_inhibit_completion; +extern Function *rl_pre_input_hook; +extern Function *rl_startup_hook; +extern char *rl_terminal_name; +extern int rl_already_prompted; +extern char *rl_prompt; +/* + * The following is not implemented + */ +extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap, + emacs_meta_keymap, + emacs_ctlx_keymap; +extern int rl_filename_completion_desired; +extern int rl_ignore_completion_duplicates; +extern Function *rl_getc_function; +extern VFunction *rl_redisplay_function; +extern VFunction *rl_completion_display_matches_hook; +extern VFunction *rl_prep_term_function; +extern VFunction *rl_deprep_term_function; /* supported functions */ char *readline(const char *); @@ -99,6 +152,8 @@ int read_history(const char *); int write_history(const char *); int history_expand(char *, char **); char **history_tokenize(const char *); +const char *get_history_event(const char *, int *, int); +char *history_arg_extract(int, int, const char *); char *tilde_expand(char *); char *filename_completion_function(const char *, int); @@ -111,6 +166,26 @@ void rl_display_match_list(char **, int, int); int rl_insert(int, int); void rl_reset_terminal(const char *); int rl_bind_key(int, int (*)(int, int)); +int rl_newline(int, int); +void rl_callback_read_char(void); +void rl_callback_handler_install(const char *, VFunction *); +void rl_callback_handler_remove(void); +void rl_redisplay(void); +int rl_get_previous_history(int, int); +void rl_prep_terminal(int); +void rl_deprep_terminal(void); +int rl_read_init_file(const char *); +int rl_parse_and_bind(const char *); +void rl_stuff_char(int); +int rl_add_defun(const char *, Function *, int); + +/* + * The following are not implemented + */ +Keymap rl_get_keymap(void); +Keymap rl_make_bare_keymap(void); +int rl_generic_bind(int, const char *, const char *, Keymap); +int rl_bind_key_in_map(int, Function *, Keymap); #ifdef __cplusplus } #endif diff --git a/cmd-line-utils/libedit/el.c b/cmd-line-utils/libedit/el.c index 1b445d40f1c..c32a01b2151 100644 --- a/cmd-line-utils/libedit/el.c +++ b/cmd-line-utils/libedit/el.c @@ -1,4 +1,4 @@ -/* $NetBSD: el.c,v 1.30 2002/11/12 00:00:23 thorpej Exp $ */ +/* $NetBSD: el.c,v 1.39 2004/07/08 00:51:36 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,14 +32,7 @@ * SUCH DAMAGE. */ -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94"; -#else -__RCSID("$NetBSD: el.c,v 1.30 2002/11/12 00:00:23 thorpej Exp $"); -#endif -#endif /* not lint && not SCCSID */ +#include <config.h> /* * el.c: EditLine interface functions @@ -72,7 +61,10 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr) el->el_infd = fileno(fin); el->el_outfile = fout; el->el_errfile = ferr; - el->el_prog = strdup(prog); + if ((el->el_prog = el_strdup(prog)) == NULL) { + el_free(el); + return NULL; + } /* * Initialize all the modules. Order is important!!! @@ -80,11 +72,11 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr) el->el_flags = 0; if (term_init(el) == -1) { - free(el->el_prog); + el_free(el->el_prog); el_free(el); return NULL; } - (void) el_key_init(el); + (void) key_init(el); (void) map_init(el); if (tty_init(el) == -1) el->el_flags |= NO_TTY; @@ -112,7 +104,7 @@ el_end(EditLine *el) el_reset(el); term_end(el); - el_key_end(el); + key_end(el); map_end(el); tty_end(el); ch_end(el); @@ -257,6 +249,27 @@ el_set(EditLine *el, int op, ...) el->el_data = va_arg(va, void *); break; + case EL_UNBUFFERED: + rv = va_arg(va, int); + if (rv && !(el->el_flags & UNBUFFERED)) { + el->el_flags |= UNBUFFERED; + read_prepare(el); + } else if (!rv && (el->el_flags & UNBUFFERED)) { + el->el_flags &= ~UNBUFFERED; + read_finish(el); + } + rv = 0; + break; + + case EL_PREP_TERM: + rv = va_arg(va, int); + if (rv) + (void) tty_rawmode(el); + else + (void) tty_cookedmode(el); + rv = 0; + break; + default: rv = -1; break; @@ -297,21 +310,22 @@ el_get(EditLine *el, int op, void *ret) rv = 0; break; -#if 0 /* XXX */ case EL_TERMINAL: - rv = term_get(el, (const char *) &ret); + term_get(el, (const char **)ret); + rv = 0; break; +#if 0 /* XXX */ case EL_BIND: case EL_TELLTC: case EL_SETTC: case EL_ECHOTC: case EL_SETTY: { - char *argv[20]; + const char *argv[20]; int i; - for (i = 1; i < 20; i++) + for (i = 1; i < sizeof(argv) / sizeof(argv[0]); i++) if ((argv[i] = va_arg(va, char *)) == NULL) break; @@ -378,6 +392,11 @@ el_get(EditLine *el, int op, void *ret) rv = 0; break; + case EL_UNBUFFERED: + *((int *) ret) = (!(el->el_flags & UNBUFFERED)); + rv = 0; + break; + default: rv = -1; } @@ -409,12 +428,17 @@ el_source(EditLine *el, const char *fname) fp = NULL; if (fname == NULL) { -#ifdef HAVE_ISSETUGID static const char elpath[] = "/.editrc"; +#ifdef MAXPATHLEN char path[MAXPATHLEN]; +#else + char path[4096]; +#endif +#ifdef HAVE_ISSETUGID if (issetugid()) return (-1); +#endif if ((ptr = getenv("HOME")) == NULL) return (-1); if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path)) @@ -422,14 +446,6 @@ el_source(EditLine *el, const char *fname) if (strlcat(path, elpath, sizeof(path)) >= sizeof(path)) return (-1); fname = path; -#else - /* - * If issetugid() is missing, always return an error, in order - * to keep from inadvertently opening up the user to a security - * hole. - */ - return (-1); -#endif } if (fp == NULL) fp = fopen(fname, "r"); @@ -496,10 +512,13 @@ el_editmode(EditLine *el, int argc, const char **argv) return (-1); how = argv[1]; - if (strcmp(how, "on") == 0) + if (strcmp(how, "on") == 0) { el->el_flags &= ~EDIT_DISABLED; - else if (strcmp(how, "off") == 0) + tty_rawmode(el); + } else if (strcmp(how, "off") == 0) { + tty_cookedmode(el); el->el_flags |= EDIT_DISABLED; + } else { (void) fprintf(el->el_errfile, "edit: Bad value `%s'.\n", how); return (-1); diff --git a/cmd-line-utils/libedit/el.h b/cmd-line-utils/libedit/el.h index 49bd462ad3b..c4b6cff2186 100644 --- a/cmd-line-utils/libedit/el.h +++ b/cmd-line-utils/libedit/el.h @@ -1,4 +1,4 @@ -/* $NetBSD: el.h,v 1.13 2002/11/15 14:32:33 christos Exp $ */ +/* $NetBSD: el.h,v 1.16 2003/10/18 23:48:42 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -55,9 +51,10 @@ #define EL_BUFSIZ 1024 /* Maximum line size */ -#define HANDLE_SIGNALS 1<<0 -#define NO_TTY 1<<1 -#define EDIT_DISABLED 1<<2 +#define HANDLE_SIGNALS 0x01 +#define NO_TTY 0x02 +#define EDIT_DISABLED 0x04 +#define UNBUFFERED 0x08 typedef int bool_t; /* True or not */ @@ -91,6 +88,7 @@ typedef struct el_state_t { /* * Until we come up with something better... */ +#define el_strdup(a) strdup(a) #define el_malloc(a) malloc(a) #define el_realloc(a,b) realloc(a, b) #define el_free(a) free(a) @@ -98,7 +96,7 @@ typedef struct el_state_t { #include "tty.h" #include "prompt.h" #include "key.h" -#include "libedit_term.h" +#include "el_term.h" #include "refresh.h" #include "chared.h" #include "common.h" diff --git a/cmd-line-utils/libedit/el_term.h b/cmd-line-utils/libedit/el_term.h new file mode 100644 index 00000000000..9e5588ee96f --- /dev/null +++ b/cmd-line-utils/libedit/el_term.h @@ -0,0 +1,131 @@ +/* $NetBSD: term.h,v 1.15 2003/09/14 21:48:55 christos Exp $ */ + +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Christos Zoulas of Cornell University. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)term.h 8.1 (Berkeley) 6/4/93 + */ + +/* + * el.term.h: Termcap header + */ +#ifndef _h_el_term +#define _h_el_term + +#include "histedit.h" + +typedef struct { /* Symbolic function key bindings */ + const char *name; /* name of the key */ + int key; /* Index in termcap table */ + key_value_t fun; /* Function bound to it */ + int type; /* Type of function */ +} fkey_t; + +typedef struct { + const char *t_name; /* the terminal name */ + coord_t t_size; /* # lines and cols */ + int t_flags; +#define TERM_CAN_INSERT 0x001 /* Has insert cap */ +#define TERM_CAN_DELETE 0x002 /* Has delete cap */ +#define TERM_CAN_CEOL 0x004 /* Has CEOL cap */ +#define TERM_CAN_TAB 0x008 /* Can use tabs */ +#define TERM_CAN_ME 0x010 /* Can turn all attrs. */ +#define TERM_CAN_UP 0x020 /* Can move up */ +#define TERM_HAS_META 0x040 /* Has a meta key */ +#define TERM_HAS_AUTO_MARGINS 0x080 /* Has auto margins */ +#define TERM_HAS_MAGIC_MARGINS 0x100 /* Has magic margins */ + char *t_buf; /* Termcap buffer */ + int t_loc; /* location used */ + char **t_str; /* termcap strings */ + int *t_val; /* termcap values */ + char *t_cap; /* Termcap buffer */ + fkey_t *t_fkey; /* Array of keys */ +} el_term_t; + +/* + * fKey indexes + */ +#define A_K_DN 0 +#define A_K_UP 1 +#define A_K_LT 2 +#define A_K_RT 3 +#define A_K_HO 4 +#define A_K_EN 5 +#define A_K_NKEYS 6 + +#ifdef _SUNOS +extern int tgetent(char *, const char *); +extern int tgetflag(char *); +extern int tgetnum(char *); +extern int tputs(const char *, int, int (*)(int)); +extern char* tgoto(const char*, int, int); +extern char* tgetstr(char*, char**); +#endif + +protected void term_move_to_line(EditLine *, int); +protected void term_move_to_char(EditLine *, int); +protected void term_clear_EOL(EditLine *, int); +protected void term_overwrite(EditLine *, const char *, int); +protected void term_insertwrite(EditLine *, char *, int); +protected void term_deletechars(EditLine *, int); +protected void term_clear_screen(EditLine *); +protected void term_beep(EditLine *); +protected int term_change_size(EditLine *, int, int); +protected int term_get_size(EditLine *, int *, int *); +protected int term_init(EditLine *); +protected void term_bind_arrow(EditLine *); +protected void term_print_arrow(EditLine *, const char *); +protected int term_clear_arrow(EditLine *, const char *); +protected int term_set_arrow(EditLine *, const char *, key_value_t *, int); +protected void term_end(EditLine *); +protected void term_get(EditLine *, const char **); +protected int term_set(EditLine *, const char *); +protected int term_settc(EditLine *, int, const char **); +protected int term_telltc(EditLine *, int, const char **); +protected int term_echotc(EditLine *, int, const char **); +protected int term__putc(int); +protected void term__flush(void); + +/* + * Easy access macros + */ +#define EL_FLAGS (el)->el_term.t_flags + +#define EL_CAN_INSERT (EL_FLAGS & TERM_CAN_INSERT) +#define EL_CAN_DELETE (EL_FLAGS & TERM_CAN_DELETE) +#define EL_CAN_CEOL (EL_FLAGS & TERM_CAN_CEOL) +#define EL_CAN_TAB (EL_FLAGS & TERM_CAN_TAB) +#define EL_CAN_ME (EL_FLAGS & TERM_CAN_ME) +#define EL_HAS_META (EL_FLAGS & TERM_HAS_META) +#define EL_HAS_AUTO_MARGINS (EL_FLAGS & TERM_HAS_AUTO_MARGINS) +#define EL_HAS_MAGIC_MARGINS (EL_FLAGS & TERM_HAS_MAGIC_MARGINS) + +#endif /* _h_el_term */ diff --git a/cmd-line-utils/libedit/emacs.c b/cmd-line-utils/libedit/emacs.c index d58d1620693..79f2bf0c818 100644 --- a/cmd-line-utils/libedit/emacs.c +++ b/cmd-line-utils/libedit/emacs.c @@ -1,4 +1,4 @@ -/* $NetBSD: emacs.c,v 1.12 2002/11/15 14:32:33 christos Exp $ */ +/* $NetBSD: emacs.c,v 1.19 2004/10/28 21:14:52 dsl Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,14 +32,7 @@ * SUCH DAMAGE. */ -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: emacs.c,v 1.12 2002/11/15 14:32:33 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ +#include <config.h> /* * emacs.c: Emacs functions @@ -56,7 +45,7 @@ __RCSID("$NetBSD: emacs.c,v 1.12 2002/11/15 14:32:33 christos Exp $"); */ protected el_action_t /*ARGSUSED*/ -em_delete_or_list(EditLine *el, int c __attribute__((unused))) +em_delete_or_list(EditLine *el, int c __attribute__((__unused__))) { if (el->el_line.cursor == el->el_line.lastchar) { @@ -75,7 +64,10 @@ em_delete_or_list(EditLine *el, int c __attribute__((unused))) return (CC_ERROR); } } else { - c_delafter(el, el->el_state.argument); /* delete after dot */ + if (el->el_state.doingarg) + c_delafter(el, el->el_state.argument); + else + c_delafter1(el); if (el->el_line.cursor > el->el_line.lastchar) el->el_line.cursor = el->el_line.lastchar; /* bounds check */ @@ -90,7 +82,7 @@ em_delete_or_list(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -em_delete_next_word(EditLine *el, int c __attribute__((unused))) +em_delete_next_word(EditLine *el, int c __attribute__((__unused__))) { char *cp, *p, *kp; @@ -119,14 +111,12 @@ em_delete_next_word(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -em_yank(EditLine *el, int c __attribute__((unused))) +em_yank(EditLine *el, int c __attribute__((__unused__))) { char *kp, *cp; - if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf) { - if (!ch_enlargebufs(el, 1)) - return (CC_ERROR); - } + if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf) + return (CC_NORM); if (el->el_line.lastchar + (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >= @@ -156,7 +146,7 @@ em_yank(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -em_kill_line(EditLine *el, int c __attribute__((unused))) +em_kill_line(EditLine *el, int c __attribute__((__unused__))) { char *kp, *cp; @@ -178,7 +168,7 @@ em_kill_line(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -em_kill_region(EditLine *el, int c __attribute__((unused))) +em_kill_region(EditLine *el, int c __attribute__((__unused__))) { char *kp, *cp; @@ -211,7 +201,7 @@ em_kill_region(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -em_copy_region(EditLine *el, int c __attribute__((unused))) +em_copy_region(EditLine *el, int c __attribute__((__unused__))) { char *kp, *cp; @@ -235,12 +225,12 @@ em_copy_region(EditLine *el, int c __attribute__((unused))) } -/* em_gosmacs_traspose(): +/* em_gosmacs_transpose(): * Exchange the two characters before the cursor * Gosling emacs transpose chars [^T] */ protected el_action_t -em_gosmacs_traspose(EditLine *el, int c) +em_gosmacs_transpose(EditLine *el, int c) { if (el->el_line.cursor > &el->el_line.buffer[1]) { @@ -260,7 +250,7 @@ em_gosmacs_traspose(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -em_next_word(EditLine *el, int c __attribute__((unused))) +em_next_word(EditLine *el, int c __attribute__((__unused__))) { if (el->el_line.cursor == el->el_line.lastchar) return (CC_ERROR); @@ -285,7 +275,7 @@ em_next_word(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -em_upper_case(EditLine *el, int c __attribute__((unused))) +em_upper_case(EditLine *el, int c __attribute__((__unused__))) { char *cp, *ep; @@ -293,8 +283,8 @@ em_upper_case(EditLine *el, int c __attribute__((unused))) el->el_state.argument, ce__isword); for (cp = el->el_line.cursor; cp < ep; cp++) - if (islower((unsigned char) *cp)) - *cp = toupper(*cp); + if (islower((unsigned char)*cp)) + *cp = toupper((unsigned char)*cp); el->el_line.cursor = ep; if (el->el_line.cursor > el->el_line.lastchar) @@ -309,7 +299,7 @@ em_upper_case(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -em_capitol_case(EditLine *el, int c __attribute__((unused))) +em_capitol_case(EditLine *el, int c __attribute__((__unused__))) { char *cp, *ep; @@ -317,16 +307,16 @@ em_capitol_case(EditLine *el, int c __attribute__((unused))) el->el_state.argument, ce__isword); for (cp = el->el_line.cursor; cp < ep; cp++) { - if (isalpha((unsigned char) *cp)) { - if (islower((unsigned char) *cp)) - *cp = toupper(*cp); + if (isalpha((unsigned char)*cp)) { + if (islower((unsigned char)*cp)) + *cp = toupper((unsigned char)*cp); cp++; break; } } for (; cp < ep; cp++) - if (isupper((unsigned char) *cp)) - *cp = tolower(*cp); + if (isupper((unsigned char)*cp)) + *cp = tolower((unsigned char)*cp); el->el_line.cursor = ep; if (el->el_line.cursor > el->el_line.lastchar) @@ -341,7 +331,7 @@ em_capitol_case(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -em_lower_case(EditLine *el, int c __attribute__((unused))) +em_lower_case(EditLine *el, int c __attribute__((__unused__))) { char *cp, *ep; @@ -349,8 +339,8 @@ em_lower_case(EditLine *el, int c __attribute__((unused))) el->el_state.argument, ce__isword); for (cp = el->el_line.cursor; cp < ep; cp++) - if (isupper((unsigned char) *cp)) - *cp = tolower(*cp); + if (isupper((unsigned char)*cp)) + *cp = tolower((unsigned char)*cp); el->el_line.cursor = ep; if (el->el_line.cursor > el->el_line.lastchar) @@ -365,7 +355,7 @@ em_lower_case(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -em_set_mark(EditLine *el, int c __attribute__((unused))) +em_set_mark(EditLine *el, int c __attribute__((__unused__))) { el->el_chared.c_kill.mark = el->el_line.cursor; @@ -379,7 +369,7 @@ em_set_mark(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -em_exchange_mark(EditLine *el, int c __attribute__((unused))) +em_exchange_mark(EditLine *el, int c __attribute__((__unused__))) { char *cp; @@ -396,7 +386,7 @@ em_exchange_mark(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -em_universal_argument(EditLine *el, int c __attribute__((unused))) +em_universal_argument(EditLine *el, int c __attribute__((__unused__))) { /* multiply current argument by 4 */ if (el->el_state.argument > 1000000) @@ -413,7 +403,7 @@ em_universal_argument(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -em_meta_next(EditLine *el, int c __attribute__((unused))) +em_meta_next(EditLine *el, int c __attribute__((__unused__))) { el->el_state.metanext = 1; @@ -426,7 +416,7 @@ em_meta_next(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -em_toggle_overwrite(EditLine *el, int c __attribute__((unused))) +em_toggle_overwrite(EditLine *el, int c __attribute__((__unused__))) { el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ? @@ -440,7 +430,7 @@ em_toggle_overwrite(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -em_copy_prev_word(EditLine *el, int c __attribute__((unused))) +em_copy_prev_word(EditLine *el, int c __attribute__((__unused__))) { char *cp, *oldc, *dp; @@ -467,7 +457,7 @@ em_copy_prev_word(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -em_inc_search_next(EditLine *el, int c __attribute__((unused))) +em_inc_search_next(EditLine *el, int c __attribute__((__unused__))) { el->el_search.patlen = 0; @@ -480,9 +470,32 @@ em_inc_search_next(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -em_inc_search_prev(EditLine *el, int c __attribute__((unused))) +em_inc_search_prev(EditLine *el, int c __attribute__((__unused__))) { el->el_search.patlen = 0; return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY)); } + + +/* em_delete_prev_char(): + * Delete the character to the left of the cursor + * [^?] + */ +protected el_action_t +/*ARGSUSED*/ +em_delete_prev_char(EditLine *el, int c __attribute__((__unused__))) +{ + + if (el->el_line.cursor <= el->el_line.buffer) + return (CC_ERROR); + + if (el->el_state.doingarg) + c_delbefore(el, el->el_state.argument); + else + c_delbefore1(el); + el->el_line.cursor -= el->el_state.argument; + if (el->el_line.cursor < el->el_line.buffer) + el->el_line.cursor = el->el_line.buffer; + return (CC_REFRESH); +} diff --git a/cmd-line-utils/libedit/fgetln.c b/cmd-line-utils/libedit/fgetln.c index 4f7416a4c8d..5b95b2f6584 100644 --- a/cmd-line-utils/libedit/fgetln.c +++ b/cmd-line-utils/libedit/fgetln.c @@ -1,109 +1,88 @@ +/* $NetBSD: fgetln.c,v 1.2 2003/12/10 01:30:27 lukem Exp $ */ + +/*- + * Copyright (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <config.h> #include <stdio.h> -#include "compat.h" +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> -#ifndef HAVE_FGETLN -#ifdef HAVE_GETLINE - -extern int getline (char **lineptr, size_t *n, FILE *stream); - -#else - -/* The interface here is that of GNU libc's getline */ -static int -getline (char **lineptr, size_t *n, FILE *stream) +char * +fgetln(FILE *fp, size_t *len) { -#define EXPAND_CHUNK 16 - - int n_read = 0; - char *line = *lineptr; - - if (lineptr == NULL) return -1; - if (n == NULL) return -1; - if (stream == NULL) return -1; - if (*lineptr == NULL || *n == 0) return -1; - -#ifdef HAVE_FLOCKFILE - flockfile (stream); -#endif - - while (1) - { - int c; - -#ifdef HAVE_FLOCKFILE - c = getc_unlocked (stream); -#else - c = getc (stream); -#endif - - if (c == EOF) - { - if (n_read > 0) - line[n_read] = '\0'; - break; - } - - if (n_read + 2 >= *n) - { - size_t new_size; - - if (*n == 0) - new_size = 16; - else - new_size = *n * 2; - - if (*n >= new_size) /* Overflowed size_t */ - line = NULL; - else - line = (char *) (*lineptr ? (char*) realloc(*lineptr, new_size) : - (char*) malloc(new_size)); - - if (line) - { - *lineptr = line; - *n = new_size; - } - else - { - if (*n > 0) - { - (*lineptr)[*n - 1] = '\0'; - n_read = *n - 2; - } - break; - } - } - - line[n_read] = c; - n_read++; - - if (c == '\n') - { - line[n_read] = '\0'; - break; - } - } - -#ifdef HAVE_FLOCKFILE - funlockfile (stream); -#endif - - return n_read - 1; + static char *buf = NULL; + static size_t bufsiz = 0; + char *ptr; + + + if (buf == NULL) { + bufsiz = BUFSIZ; + if ((buf = malloc(bufsiz)) == NULL) + return NULL; + } + + if (fgets(buf, bufsiz, fp) == NULL) + return NULL; + *len = 0; + + while ((ptr = strchr(&buf[*len], '\n')) == NULL) { + size_t nbufsiz = bufsiz + BUFSIZ; + char *nbuf = realloc(buf, nbufsiz); + + if (nbuf == NULL) { + int oerrno = errno; + free(buf); + errno = oerrno; + buf = NULL; + return NULL; + } else + buf = nbuf; + + *len = bufsiz; + if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL) + return buf; + + bufsiz = nbufsiz; + } + + *len = (ptr - buf) + 1; + return buf; } -#endif /* ! HAVE_GETLINE */ -char *fgetln(FILE *stream, size_t *len) -{ - char *ptr = NULL; - int sz; - size_t length= 0; - - sz = getline(&ptr, &length, stream); - if(len) { - *len = sz; - } - - return sz >= 0 ? ptr : NULL; -} -#endif diff --git a/cmd-line-utils/libedit/hist.c b/cmd-line-utils/libedit/hist.c index 59c2f39dd34..e8f5c0f39ba 100644 --- a/cmd-line-utils/libedit/hist.c +++ b/cmd-line-utils/libedit/hist.c @@ -1,4 +1,4 @@ -/* $NetBSD: hist.c,v 1.12 2003/01/21 18:40:23 christos Exp $ */ +/* $NetBSD: hist.c,v 1.15 2003/11/01 23:36:39 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,14 +32,7 @@ * SUCH DAMAGE. */ -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: hist.c,v 1.12 2003/01/21 18:40:23 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ +#include <config.h> /* * hist.c: History access functions @@ -157,7 +146,6 @@ hist_get(EditLine *el) * process a history command */ protected int -/*ARGSUSED*/ hist_command(EditLine *el, int argc, const char **argv) { const char *str; @@ -167,7 +155,7 @@ hist_command(EditLine *el, int argc, const char **argv) if (el->el_history.ref == NULL) return (-1); - if (argc == 0 || strcmp(argv[0], "list") == 1) { + if (argc == 1 || strcmp(argv[1], "list") == 0) { /* List history entries */ for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el)) @@ -176,15 +164,15 @@ hist_command(EditLine *el, int argc, const char **argv) return (0); } - if (argc != 2) + if (argc != 3) return (-1); - num = (int)strtol(argv[1], NULL, 0); + num = (int)strtol(argv[2], NULL, 0); - if (strcmp(argv[0], "size") == 0) + if (strcmp(argv[1], "size") == 0) return history(el->el_history.ref, &ev, H_SETSIZE, num); - if (strcmp(argv[0], "unique") == 0) + if (strcmp(argv[1], "unique") == 0) return history(el->el_history.ref, &ev, H_SETUNIQUE, num); return -1; diff --git a/cmd-line-utils/libedit/hist.h b/cmd-line-utils/libedit/hist.h index b713281b382..46e14634adf 100644 --- a/cmd-line-utils/libedit/hist.h +++ b/cmd-line-utils/libedit/hist.h @@ -1,4 +1,4 @@ -/* $NetBSD: hist.h,v 1.9 2003/01/21 18:40:23 christos Exp $ */ +/* $NetBSD: hist.h,v 1.10 2003/08/07 16:44:31 agc Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/cmd-line-utils/libedit/histedit.h b/cmd-line-utils/libedit/histedit.h index 3137bd680a7..c58eb62dcfa 100644 --- a/cmd-line-utils/libedit/histedit.h +++ b/cmd-line-utils/libedit/histedit.h @@ -1,4 +1,4 @@ -/* $NetBSD: histedit.h,v 1.21 2003/01/21 18:40:24 christos Exp $ */ +/* $NetBSD: histedit.h,v 1.25 2003/12/05 13:37:48 lukem Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -45,7 +41,7 @@ #define _HISTEDIT_H_ #define LIBEDIT_MAJOR 2 -#define LIBEDIT_MINOR 6 +#define LIBEDIT_MINOR 9 #include <sys/types.h> #include <stdio.h> @@ -53,6 +49,7 @@ /* * ==== Editing ==== */ + typedef struct editline EditLine; /* @@ -64,7 +61,6 @@ typedef struct lineinfo { const char *lastchar; } LineInfo; - /* * EditLine editor function return codes. * For user-defined function interface @@ -84,9 +80,8 @@ typedef struct lineinfo { * Initialization, cleanup, and resetting */ EditLine *el_init(const char *, FILE *, FILE *, FILE *); -void el_reset(EditLine *); void el_end(EditLine *); - +void el_reset(EditLine *); /* * Get a line, a character or push a string back in the input queue @@ -131,6 +126,8 @@ int el_get(EditLine *, int, void *); #define EL_RPROMPT 12 /* , el_pfunc_t); */ #define EL_GETCFN 13 /* , el_rfunc_t); */ #define EL_CLIENTDATA 14 /* , void *); */ +#define EL_UNBUFFERED 15 /* , int); */ +#define EL_PREP_TERM 16 /* , int); */ #define EL_BUILTIN_GETCFN (NULL) @@ -146,7 +143,6 @@ int el_source(EditLine *, const char *); */ void el_resize(EditLine *); - /* * User-defined function interface. */ @@ -154,6 +150,7 @@ const LineInfo *el_line(EditLine *); int el_insertstr(EditLine *, const char *); void el_deletestr(EditLine *, int); + /* * ==== History ==== */ @@ -196,4 +193,22 @@ int history(History *, HistEvent *, int, ...); #define H_SETUNIQUE 20 /* , int); */ #define H_GETUNIQUE 21 /* , void); */ + +/* + * ==== Tokenization ==== + */ + +typedef struct tokenizer Tokenizer; + +/* + * String tokenization functions, using simplified sh(1) quoting rules + */ +Tokenizer *tok_init(const char *); +void tok_end(Tokenizer *); +void tok_reset(Tokenizer *); +int tok_line(Tokenizer *, const LineInfo *, + int *, const char ***, int *, int *); +int tok_str(Tokenizer *, const char *, + int *, const char ***); + #endif /* _HISTEDIT_H_ */ diff --git a/cmd-line-utils/libedit/history.c b/cmd-line-utils/libedit/history.c index 53648203bf0..1da6a864181 100644 --- a/cmd-line-utils/libedit/history.c +++ b/cmd-line-utils/libedit/history.c @@ -1,4 +1,4 @@ -/* $NetBSD: history.c,v 1.22 2003/01/21 18:40:24 christos Exp $ */ +/* $NetBSD: history.c,v 1.28 2004/11/27 18:31:45 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,14 +32,7 @@ * SUCH DAMAGE. */ -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: history.c,v 1.22 2003/01/21 18:40:24 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ +#include <config.h> /* * hist.c: History access functions @@ -51,11 +40,7 @@ __RCSID("$NetBSD: history.c,v 1.22 2003/01/21 18:40:24 christos Exp $"); #include <string.h> #include <stdlib.h> #include <stdarg.h> -#ifdef HAVE_VIS_H #include <vis.h> -#else -#include "np/vis.h" -#endif #include <sys/stat.h> static const char hist_cookie[] = "_HiStOrY_V2_\n"; @@ -91,6 +76,7 @@ struct history { #define HENTER(h, ev, str) (*(h)->h_enter)((h)->h_ref, ev, str) #define HADD(h, ev, str) (*(h)->h_add)((h)->h_ref, ev, str) +#define h_strdup(a) strdup(a) #define h_malloc(a) malloc(a) #define h_realloc(a, b) realloc((a), (b)) #define h_free(a) free(a) @@ -249,20 +235,19 @@ history_def_next(ptr_t p, HistEvent *ev) { history_t *h = (history_t *) p; - if (h->cursor != &h->list) - h->cursor = h->cursor->next; - else { + if (h->cursor == &h->list) { he_seterrev(ev, _HE_EMPTY_LIST); return (-1); } - if (h->cursor != &h->list) - *ev = h->cursor->ev; - else { + if (h->cursor->next == &h->list) { he_seterrev(ev, _HE_END_REACHED); return (-1); } + h->cursor = h->cursor->next; + *ev = h->cursor->ev; + return (0); } @@ -275,21 +260,20 @@ history_def_prev(ptr_t p, HistEvent *ev) { history_t *h = (history_t *) p; - if (h->cursor != &h->list) - h->cursor = h->cursor->prev; - else { + if (h->cursor == &h->list) { he_seterrev(ev, (h->cur > 0) ? _HE_END_REACHED : _HE_EMPTY_LIST); return (-1); } - if (h->cursor != &h->list) - *ev = h->cursor->ev; - else { + if (h->cursor->prev == &h->list) { he_seterrev(ev, _HE_START_REACHED); return (-1); } + h->cursor = h->cursor->prev; + *ev = h->cursor->ev; + return (0); } @@ -374,7 +358,8 @@ history_def_add(ptr_t p, HistEvent *ev, const char *str) */ /* ARGSUSED */ private void -history_def_delete(history_t *h, HistEvent *ev __attribute__((unused)), hentry_t *hp) +history_def_delete(history_t *h, + HistEvent *ev __attribute__((__unused__)), hentry_t *hp) { HistEventPrivate *evp = (void *)&hp->ev; if (hp == &h->list) @@ -397,7 +382,7 @@ history_def_insert(history_t *h, HistEvent *ev, const char *str) h->cursor = (hentry_t *) h_malloc(sizeof(hentry_t)); if (h->cursor == NULL) goto oomem; - if ((h->cursor->ev.str = strdup(str)) == NULL) { + if ((h->cursor->ev.str = h_strdup(str)) == NULL) { h_free((ptr_t)h->cursor); goto oomem; } @@ -447,7 +432,7 @@ history_def_enter(ptr_t p, HistEvent *ev, const char *str) */ /* ARGSUSED */ private int -history_def_init(ptr_t *p, HistEvent *ev __attribute__((unused)), int n) +history_def_init(ptr_t *p, HistEvent *ev __attribute__((__unused__)), int n) { history_t *h = (history_t *) h_malloc(sizeof(history_t)); if (h == NULL) @@ -661,6 +646,12 @@ history_load(History *h, const char *fname) if ((fp = fopen(fname, "r")) == NULL) return (i); + if ((line = fgetln(fp, &sz)) == NULL) + goto done; + + if (strncmp(line, hist_cookie, sz) != 0) + goto done; + ptr = h_malloc(max_size = 1024); if (ptr == NULL) goto done; @@ -674,7 +665,7 @@ history_load(History *h, const char *fname) if (max_size < sz) { char *nptr; - max_size = (sz + 1023) & ~1023; + max_size = (sz + 1024) & ~1023; nptr = h_realloc(ptr, max_size); if (nptr == NULL) { i = -1; @@ -714,16 +705,18 @@ history_save(History *h, const char *fname) if (fchmod(fileno(fp), S_IRUSR|S_IWUSR) == -1) goto done; + if (fputs(hist_cookie, fp) == EOF) + goto done; ptr = h_malloc(max_size = 1024); if (ptr == NULL) goto done; for (i = 0, retval = HLAST(h, &ev); retval != -1; retval = HPREV(h, &ev), i++) { - len = strlen(ev.str) * 4 + 1; + len = strlen(ev.str) * 4; if (len >= max_size) { char *nptr; - max_size = (len + 1023) & ~1023; + max_size = (len + 1024) & ~1023; nptr = h_realloc(ptr, max_size); if (nptr == NULL) { i = -1; @@ -732,7 +725,7 @@ history_save(History *h, const char *fname) ptr = nptr; } (void) strvis(ptr, ev.str, VIS_WHITE); - (void) fprintf(fp, "%s\n", ev.str); + (void) fprintf(fp, "%s\n", ptr); } oomem: h_free((ptr_t)ptr); diff --git a/cmd-line-utils/libedit/key.c b/cmd-line-utils/libedit/key.c index e75db00ce1b..090a2684e92 100644 --- a/cmd-line-utils/libedit/key.c +++ b/cmd-line-utils/libedit/key.c @@ -1,4 +1,4 @@ -/* $NetBSD: key.c,v 1.13 2002/03/18 16:00:55 christos Exp $ */ +/* $NetBSD: key.c,v 1.15 2003/10/18 23:48:42 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,14 +32,7 @@ * SUCH DAMAGE. */ -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: key.c,v 1.13 2002/03/18 16:00:55 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ +#include <config.h> /* * key.c: This module contains the procedures for maintaining @@ -103,14 +92,14 @@ private int key__decode_char(char *, int, int); * Initialize the key maps */ protected int -el_key_init(EditLine *el) +key_init(EditLine *el) { el->el_key.buf = (char *) el_malloc(KEY_BUFSIZ); if (el->el_key.buf == NULL) return (-1); el->el_key.map = NULL; - el_key_reset(el); + key_reset(el); return (0); } @@ -119,7 +108,7 @@ el_key_init(EditLine *el) * Free the key maps */ protected void -el_key_end(EditLine *el) +key_end(EditLine *el) { el_free((ptr_t) el->el_key.buf); @@ -133,7 +122,7 @@ el_key_end(EditLine *el) * Associate cmd with a key value */ protected key_value_t * -el_key_map_cmd(EditLine *el, int cmd) +key_map_cmd(EditLine *el, int cmd) { el->el_key.val.cmd = (el_action_t) cmd; @@ -145,7 +134,7 @@ el_key_map_cmd(EditLine *el, int cmd) * Associate str with a key value */ protected key_value_t * -el_key_map_str(EditLine *el, char *str) +key_map_str(EditLine *el, char *str) { el->el_key.val.str = str; @@ -159,7 +148,7 @@ el_key_map_str(EditLine *el, char *str) * [Always bind the ansi arrow keys?] */ protected void -el_key_reset(EditLine *el) +key_reset(EditLine *el) { node__put(el, el->el_key.map); @@ -177,7 +166,7 @@ el_key_reset(EditLine *el) * The last character read is returned in *ch. */ protected int -el_key_get(EditLine *el, char *ch, key_value_t *val) +key_get(EditLine *el, char *ch, key_value_t *val) { return (node_trav(el, el->el_key.map, ch, val)); @@ -191,7 +180,7 @@ el_key_get(EditLine *el, char *ch, key_value_t *val) * out str or a unix command. */ protected void -el_key_add(EditLine *el, const char *key, key_value_t *val, int ntype) +key_add(EditLine *el, const char *key, key_value_t *val, int ntype) { if (key[0] == '\0') { @@ -219,7 +208,7 @@ el_key_add(EditLine *el, const char *key, key_value_t *val, int ntype) * */ protected void -el_key_clear(EditLine *el, el_action_t *map, const char *in) +key_clear(EditLine *el, el_action_t *map, const char *in) { if ((map[(unsigned char)*in] == ED_SEQUENCE_LEAD_IN) && @@ -227,7 +216,7 @@ el_key_clear(EditLine *el, el_action_t *map, const char *in) el->el_map.alt[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN) || (map == el->el_map.alt && el->el_map.key[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN))) - (void) el_key_delete(el, in); + (void) key_delete(el, in); } @@ -236,7 +225,7 @@ el_key_clear(EditLine *el, el_action_t *map, const char *in) * they exists. */ protected int -el_key_delete(EditLine *el, const char *key) +key_delete(EditLine *el, const char *key) { if (key[0] == '\0') { @@ -257,7 +246,7 @@ el_key_delete(EditLine *el, const char *key) * Print entire el->el_key.map if null */ protected void -el_key_print(EditLine *el, const char *key) +key_print(EditLine *el, const char *key) { /* do nothing if el->el_key.map is empty and null key specified */ @@ -356,7 +345,8 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int break; case XK_STR: case XK_EXE: - ptr->val.str = strdup(val->str); + if ((ptr->val.str = el_strdup(val->str)) == NULL) + return -1; break; default: EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype)); @@ -504,7 +494,7 @@ node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt) if (str[1] == 0) { el->el_key.buf[ncnt + 1] = '"'; el->el_key.buf[ncnt + 2] = '\0'; - el_key_kprint(el, el->el_key.buf, + key_kprint(el, el->el_key.buf, &ptr->val, ptr->type); return (0); } else @@ -552,7 +542,7 @@ node_enum(EditLine *el, key_node_t *ptr, int cnt) /* print this key and function */ el->el_key.buf[ncnt + 1] = '"'; el->el_key.buf[ncnt + 2] = '\0'; - el_key_kprint(el, el->el_key.buf, &ptr->val, ptr->type); + key_kprint(el, el->el_key.buf, &ptr->val, ptr->type); } else (void) node_enum(el, ptr->next, ncnt + 1); @@ -568,7 +558,7 @@ node_enum(EditLine *el, key_node_t *ptr, int cnt) * function specified by val */ protected void -el_key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype) +key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype) { el_bindings_t *fp; char unparsbuf[EL_BUFSIZ]; @@ -579,7 +569,7 @@ el_key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype) case XK_STR: case XK_EXE: (void) fprintf(el->el_outfile, fmt, key, - el_key__decode_str(val->str, unparsbuf, + key__decode_str(val->str, unparsbuf, ntype == XK_STR ? "\"\"" : "[]")); break; case XK_CMD: @@ -644,7 +634,7 @@ key__decode_char(char *buf, int cnt, int ch) * Make a printable version of the ey */ protected char * -el_key__decode_str(const char *str, char *buf, const char *sep) +key__decode_str(const char *str, char *buf, const char *sep) { char *b; const char *p; diff --git a/cmd-line-utils/libedit/key.h b/cmd-line-utils/libedit/key.h index 9d83d7c2521..39a075c504e 100644 --- a/cmd-line-utils/libedit/key.h +++ b/cmd-line-utils/libedit/key.h @@ -1,4 +1,4 @@ -/* $NetBSD: key.h,v 1.6 2002/03/18 16:00:55 christos Exp $ */ +/* $NetBSD: key.h,v 1.8 2003/08/07 16:44:32 agc Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -62,19 +58,22 @@ typedef struct el_key_t { #define XK_NOD 2 #define XK_EXE 3 -protected int el_key_init(EditLine *); -protected void el_key_end(EditLine *); -protected key_value_t *el_key_map_cmd(EditLine *, int); -protected key_value_t *el_key_map_str(EditLine *, char *); -protected void el_key_reset(EditLine *); -protected int el_key_get(EditLine *, char *, key_value_t *); -protected void el_key_add(EditLine *, - const char *, key_value_t *, int); -protected void el_key_clear(EditLine *, el_action_t *, const char *); -protected int el_key_delete(EditLine *, const char *); -protected void el_key_print(EditLine *, const char *); -protected void el_key_kprint(EditLine *, const char *, key_value_t *, +#undef key_end +#undef key_clear +#undef key_print + +protected int key_init(EditLine *); +protected void key_end(EditLine *); +protected key_value_t *key_map_cmd(EditLine *, int); +protected key_value_t *key_map_str(EditLine *, char *); +protected void key_reset(EditLine *); +protected int key_get(EditLine *, char *, key_value_t *); +protected void key_add(EditLine *, const char *, key_value_t *, int); +protected void key_clear(EditLine *, el_action_t *, const char *); +protected int key_delete(EditLine *, const char *); +protected void key_print(EditLine *, const char *); +protected void key_kprint(EditLine *, const char *, key_value_t *, int); -protected char *el_key__decode_str(const char *, char *, const char *); +protected char *key__decode_str(const char *, char *, const char *); #endif /* _h_el_key */ diff --git a/cmd-line-utils/libedit/map.c b/cmd-line-utils/libedit/map.c index a16625311ae..d99c36ff665 100644 --- a/cmd-line-utils/libedit/map.c +++ b/cmd-line-utils/libedit/map.c @@ -1,4 +1,4 @@ -/* $NetBSD: map.c,v 1.18 2002/11/15 14:32:33 christos Exp $ */ +/* $NetBSD: map.c,v 1.20 2004/08/13 12:10:39 mycroft Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,14 +32,7 @@ * SUCH DAMAGE. */ -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: map.c,v 1.18 2002/11/15 14:32:33 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ +#include <config.h> /* * map.c: Editor function definitions @@ -71,7 +60,7 @@ private const el_action_t el_map_emacs[] = { /* 5 */ ED_MOVE_TO_END, /* ^E */ /* 6 */ ED_NEXT_CHAR, /* ^F */ /* 7 */ ED_UNASSIGNED, /* ^G */ - /* 8 */ ED_DELETE_PREV_CHAR, /* ^H */ + /* 8 */ EM_DELETE_PREV_CHAR, /* ^H */ /* 9 */ ED_UNASSIGNED, /* ^I */ /* 10 */ ED_NEWLINE, /* ^J */ /* 11 */ ED_KILL_LINE, /* ^K */ @@ -190,7 +179,7 @@ private const el_action_t el_map_emacs[] = { /* 124 */ ED_INSERT, /* | */ /* 125 */ ED_INSERT, /* } */ /* 126 */ ED_INSERT, /* ~ */ - /* 127 */ ED_DELETE_PREV_CHAR, /* ^? */ + /* 127 */ EM_DELETE_PREV_CHAR, /* ^? */ /* 128 */ ED_UNASSIGNED, /* M-^@ */ /* 129 */ ED_UNASSIGNED, /* M-^A */ /* 130 */ ED_UNASSIGNED, /* M-^B */ @@ -1011,8 +1000,7 @@ map_init_meta(EditLine *el) break; default: buf[1] = i & 0177; - el_key_add(el, buf, - el_key_map_cmd(el, (int) map[i]), XK_CMD); + key_add(el, buf, key_map_cmd(el, (int) map[i]), XK_CMD); break; } map[(int) buf[0]] = ED_SEQUENCE_LEAD_IN; @@ -1034,7 +1022,7 @@ map_init_vi(EditLine *el) el->el_map.type = MAP_VI; el->el_map.current = el->el_map.key; - el_key_reset(el); + key_reset(el); for (i = 0; i < N_KEYS; i++) { key[i] = vii[i]; @@ -1063,7 +1051,7 @@ map_init_emacs(EditLine *el) el->el_map.type = MAP_EMACS; el->el_map.current = el->el_map.key; - el_key_reset(el); + key_reset(el); for (i = 0; i < N_KEYS; i++) { key[i] = emacs[i]; @@ -1076,7 +1064,7 @@ map_init_emacs(EditLine *el) buf[0] = CONTROL('X'); buf[1] = CONTROL('X'); buf[2] = 0; - el_key_add(el, buf, el_key_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD); + key_add(el, buf, key_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD); tty_bind_char(el, 1); term_bind_arrow(el); @@ -1133,7 +1121,7 @@ map_print_key(EditLine *el, el_action_t *map, const char *in) el_bindings_t *bp; if (in[0] == '\0' || in[1] == '\0') { - (void) el_key__decode_str(in, outbuf, ""); + (void) key__decode_str(in, outbuf, ""); for (bp = el->el_map.help; bp->name != NULL; bp++) if (bp->func == map[(unsigned char) *in]) { (void) fprintf(el->el_outfile, @@ -1141,7 +1129,7 @@ map_print_key(EditLine *el, el_action_t *map, const char *in) return; } } else - el_key_print(el, in); + key_print(el, in); } @@ -1163,20 +1151,20 @@ map_print_some_keys(EditLine *el, el_action_t *map, int first, int last) if (first == last) (void) fprintf(el->el_outfile, "%-15s-> is undefined\n", - el_key__decode_str(firstbuf, unparsbuf, STRQQ)); + key__decode_str(firstbuf, unparsbuf, STRQQ)); return; } for (bp = el->el_map.help; bp->name != NULL; bp++) { if (bp->func == map[first]) { if (first == last) { (void) fprintf(el->el_outfile, "%-15s-> %s\n", - el_key__decode_str(firstbuf, unparsbuf, STRQQ), + key__decode_str(firstbuf, unparsbuf, STRQQ), bp->name); } else { (void) fprintf(el->el_outfile, "%-4s to %-7s-> %s\n", - el_key__decode_str(firstbuf, unparsbuf, STRQQ), - el_key__decode_str(lastbuf, extrabuf, STRQQ), + key__decode_str(firstbuf, unparsbuf, STRQQ), + key__decode_str(lastbuf, extrabuf, STRQQ), bp->name); } return; @@ -1230,7 +1218,7 @@ map_print_all_keys(EditLine *el) map_print_some_keys(el, el->el_map.alt, prev, i - 1); (void) fprintf(el->el_outfile, "Multi-character bindings\n"); - el_key_print(el, ""); + key_print(el, ""); (void) fprintf(el->el_outfile, "Arrow key bindings\n"); term_print_arrow(el, ""); } @@ -1323,9 +1311,9 @@ map_bind(EditLine *el, int argc, const char **argv) return (-1); } if (in[1]) - (void) el_key_delete(el, in); + (void) key_delete(el, in); else if (map[(unsigned char) *in] == ED_SEQUENCE_LEAD_IN) - (void) el_key_delete(el, in); + (void) key_delete(el, in); else map[(unsigned char) *in] = ED_UNASSIGNED; return (0); @@ -1353,9 +1341,9 @@ map_bind(EditLine *el, int argc, const char **argv) return (-1); } if (key) - term_set_arrow(el, in, el_key_map_str(el, out), ntype); + term_set_arrow(el, in, key_map_str(el, out), ntype); else - el_key_add(el, in, el_key_map_str(el, out), ntype); + key_add(el, in, key_map_str(el, out), ntype); map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN; break; @@ -1366,13 +1354,13 @@ map_bind(EditLine *el, int argc, const char **argv) return (-1); } if (key) - term_set_arrow(el, in, el_key_map_str(el, out), ntype); + term_set_arrow(el, in, key_map_str(el, out), ntype); else { if (in[1]) { - el_key_add(el, in, el_key_map_cmd(el, cmd), ntype); + key_add(el, in, key_map_cmd(el, cmd), ntype); map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN; } else { - el_key_clear(el, map, in); + key_clear(el, map, in); map[(unsigned char) *in] = cmd; } } diff --git a/cmd-line-utils/libedit/map.h b/cmd-line-utils/libedit/map.h index 3c9948ccf88..3b08f48be7a 100644 --- a/cmd-line-utils/libedit/map.h +++ b/cmd-line-utils/libedit/map.h @@ -1,4 +1,4 @@ -/* $NetBSD: map.h,v 1.7 2002/03/18 16:00:56 christos Exp $ */ +/* $NetBSD: map.h,v 1.8 2003/08/07 16:44:32 agc Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/cmd-line-utils/libedit/parse.c b/cmd-line-utils/libedit/parse.c index d09b890c1ab..993cf5b752d 100644 --- a/cmd-line-utils/libedit/parse.c +++ b/cmd-line-utils/libedit/parse.c @@ -1,4 +1,4 @@ -/* $NetBSD: parse.c,v 1.16 2003/01/21 18:40:24 christos Exp $ */ +/* $NetBSD: parse.c,v 1.20 2003/12/05 13:37:48 lukem Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,14 +32,7 @@ * SUCH DAMAGE. */ -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: parse.c,v 1.16 2003/01/21 18:40:24 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ +#include <config.h> /* * parse.c: parse an editline extended command @@ -59,7 +48,6 @@ __RCSID("$NetBSD: parse.c,v 1.16 2003/01/21 18:40:24 christos Exp $"); * setty */ #include "el.h" -#include "tokenizer.h" #include <stdlib.h> private const struct { @@ -87,9 +75,8 @@ parse_line(EditLine *el, const char *line) int argc; Tokenizer *tok; - if (!(tok = tok_init(NULL))) - return -1; - tok_line(tok, line, &argc, &argv); + tok = tok_init(NULL); + tok_str(tok, line, &argc, &argv); argc = el_parse(el, argc, argv); tok_end(tok); return (argc); @@ -207,7 +194,7 @@ parse__escape(const char **const ptr) c = *p; break; } - } else if (*p == '^' && isalpha((unsigned char) p[1])) { + } else if (*p == '^') { p++; c = (*p == '?') ? '\177' : (*p & 0237); } else @@ -215,6 +202,7 @@ parse__escape(const char **const ptr) *ptr = ++p; return (c); } + /* parse__string(): * Parse the escapes from in and put the raw string out */ @@ -237,6 +225,14 @@ parse__string(char *out, const char *in) *out++ = n; break; + case 'M': + if (in[1] == '-' && in[2] != '\0') { + *out++ = '\033'; + in += 2; + break; + } + /*FALLTHROUGH*/ + default: *out++ = *in++; break; diff --git a/cmd-line-utils/libedit/parse.h b/cmd-line-utils/libedit/parse.h index 4aaef2f834a..4b796666b8e 100644 --- a/cmd-line-utils/libedit/parse.h +++ b/cmd-line-utils/libedit/parse.h @@ -1,4 +1,4 @@ -/* $NetBSD: parse.h,v 1.4 2000/09/04 22:06:31 lukem Exp $ */ +/* $NetBSD: parse.h,v 1.5 2003/08/07 16:44:32 agc Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/cmd-line-utils/libedit/prompt.c b/cmd-line-utils/libedit/prompt.c index 03d8309a991..455dd60331b 100644 --- a/cmd-line-utils/libedit/prompt.c +++ b/cmd-line-utils/libedit/prompt.c @@ -1,4 +1,4 @@ -/* $NetBSD: prompt.c,v 1.9 2002/03/18 16:00:56 christos Exp $ */ +/* $NetBSD: prompt.c,v 1.11 2003/08/07 16:44:32 agc Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,14 +32,7 @@ * SUCH DAMAGE. */ -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: prompt.c,v 1.9 2002/03/18 16:00:56 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ +#include <config.h> /* * prompt.c: Prompt printing functions @@ -59,7 +48,7 @@ private char *prompt_default_r(EditLine *); */ private char * /*ARGSUSED*/ -prompt_default(EditLine *el __attribute__((unused))) +prompt_default(EditLine *el __attribute__((__unused__))) { static char a[3] = {'?', ' ', '\0'}; @@ -72,7 +61,7 @@ prompt_default(EditLine *el __attribute__((unused))) */ private char * /*ARGSUSED*/ -prompt_default_r(EditLine *el __attribute__((unused))) +prompt_default_r(EditLine *el __attribute__((__unused__))) { static char a[1] = {'\0'}; @@ -127,7 +116,7 @@ prompt_init(EditLine *el) */ protected void /*ARGSUSED*/ -prompt_end(EditLine *el __attribute__((unused))) +prompt_end(EditLine *el __attribute__((__unused__))) { } diff --git a/cmd-line-utils/libedit/prompt.h b/cmd-line-utils/libedit/prompt.h index 08810e22a0c..d18110861f8 100644 --- a/cmd-line-utils/libedit/prompt.h +++ b/cmd-line-utils/libedit/prompt.h @@ -1,4 +1,4 @@ -/* $NetBSD: prompt.h,v 1.5 2000/09/04 22:06:31 lukem Exp $ */ +/* $NetBSD: prompt.h,v 1.6 2003/08/07 16:44:32 agc Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/cmd-line-utils/libedit/read.c b/cmd-line-utils/libedit/read.c index 5eaa83bf482..40093d6647f 100644 --- a/cmd-line-utils/libedit/read.c +++ b/cmd-line-utils/libedit/read.c @@ -1,4 +1,4 @@ -/* $NetBSD: read.c,v 1.24 2002/11/20 16:50:08 christos Exp $ */ +/* $NetBSD: read.c,v 1.35 2005/03/09 23:55:02 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,20 +32,14 @@ * SUCH DAMAGE. */ -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: read.c,v 1.24 2002/11/20 16:50:08 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ +#include <config.h> /* * read.c: Clean this junk up! This is horrible code. * Terminal read functions */ #include <errno.h> +#include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include "el.h" @@ -97,6 +87,10 @@ el_read_getfn(EditLine *el) } +#ifndef MIN +#define MIN(A,B) ((A) < (B) ? (A) : (B)) +#endif + #ifdef DEBUG_EDIT private void read_debug(EditLine *el) @@ -121,11 +115,7 @@ read_debug(EditLine *el) */ /* ARGSUSED */ private int -read__fixio(int fd -#if !(defined(TRY_AGAIN) && (defined(FIONBIO) || (defined(F_SETFL) && defined(O_NDELAY)))) - __attribute__((unused)) -#endif /* !(defined(TRY_AGAIN) && (defined(FIONBIO) || (defined(F_SETFL) && defined(O_NDELAY)))) */ -, int e) +read__fixio(int fd __attribute__((__unused__)), int e) { switch (e) { @@ -190,18 +180,10 @@ read_preread(EditLine *el) { int chrs = 0; - if (el->el_chared.c_macro.nline) { - el_free((ptr_t) el->el_chared.c_macro.nline); - el->el_chared.c_macro.nline = NULL; - } if (el->el_tty.t_mode == ED_IO) return (0); #ifdef FIONREAD - -#ifndef MIN // definition of MIN is lacking on hpux.. -#define MIN(x,y) (((x)<(y))?(x):(y)) -#endif (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs); if (chrs > 0) { char buf[EL_BUFSIZ]; @@ -210,8 +192,7 @@ read_preread(EditLine *el) (size_t) MIN(chrs, EL_BUFSIZ - 1)); if (chrs > 0) { buf[chrs] = '\0'; - el->el_chared.c_macro.nline = strdup(buf); - el_push(el, el->el_chared.c_macro.nline); + el_push(el, buf); } } #endif /* FIONREAD */ @@ -230,11 +211,12 @@ el_push(EditLine *el, char *str) if (str != NULL && ma->level + 1 < EL_MAXMACRO) { ma->level++; - ma->macro[ma->level] = str; - } else { - term_beep(el); - term__flush(); + if ((ma->macro[ma->level] = el_strdup(str)) != NULL) + return; + ma->level--; } + term_beep(el); + term__flush(); } @@ -266,7 +248,7 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch) cmd = el->el_map.current[(unsigned char) *ch]; if (cmd == ED_SEQUENCE_LEAD_IN) { key_value_t val; - switch (el_key_get(el, ch, &val)) { + switch (key_get(el, ch, &val)) { case XK_CMD: cmd = val.cmd; break; @@ -331,14 +313,16 @@ el_getc(EditLine *el, char *cp) if (ma->level < 0) break; - if (*ma->macro[ma->level] == 0) { - ma->level--; + if (ma->macro[ma->level][ma->offset] == '\0') { + el_free(ma->macro[ma->level--]); + ma->offset = 0; continue; } - *cp = *ma->macro[ma->level]++ & 0377; - if (*ma->macro[ma->level] == 0) { /* Needed for QuoteMode - * On */ - ma->level--; + *cp = ma->macro[ma->level][ma->offset++] & 0377; + if (ma->macro[ma->level][ma->offset] == '\0') { + /* Needed for QuoteMode On */ + el_free(ma->macro[ma->level--]); + ma->offset = 0; } return (1); } @@ -359,6 +343,35 @@ el_getc(EditLine *el, char *cp) return (num_read); } +protected void +read_prepare(EditLine *el) +{ + if (el->el_flags & HANDLE_SIGNALS) + sig_set(el); + if (el->el_flags & NO_TTY) + return; + if ((el->el_flags & (UNBUFFERED|EDIT_DISABLED)) == UNBUFFERED) + tty_rawmode(el); + + /* This is relatively cheap, and things go terribly wrong if + we have the wrong size. */ + el_resize(el); + re_clear_display(el); /* reset the display stuff */ + ch_reset(el); + re_refresh(el); /* print the prompt */ + + if (el->el_flags & UNBUFFERED) + term__flush(); +} + +protected void +read_finish(EditLine *el) +{ + if ((el->el_flags & UNBUFFERED) == 0) + (void) tty_cookedmode(el); + if (el->el_flags & HANDLE_SIGNALS) + sig_clr(el); +} public const char * el_gets(EditLine *el, int *nread) @@ -367,13 +380,11 @@ el_gets(EditLine *el, int *nread) el_action_t cmdnum = 0; int num; /* how many chars we have read at NL */ char ch; + int crlf = 0; #ifdef FIONREAD c_macro_t *ma = &el->el_chared.c_macro; #endif /* FIONREAD */ - if (el->el_flags & HANDLE_SIGNALS) - sig_set(el); - if (el->el_flags & NO_TTY) { char *cp = el->el_line.buffer; size_t idx; @@ -387,6 +398,8 @@ el_gets(EditLine *el, int *nread) cp = &el->el_line.buffer[idx]; } cp++; + if (el->el_flags & UNBUFFERED) + break; if (cp[-1] == '\r' || cp[-1] == '\n') break; } @@ -398,12 +411,6 @@ el_gets(EditLine *el, int *nread) return (el->el_line.buffer); } - /* This is relatively cheap, and things go terribly wrong if - we have the wrong size. */ - el_resize(el); - - re_clear_display(el); /* reset the display stuff */ - ch_reset(el); #ifdef FIONREAD if (el->el_tty.t_mode == EX_IO && ma->level < 0) { @@ -420,11 +427,16 @@ el_gets(EditLine *el, int *nread) } #endif /* FIONREAD */ - re_refresh(el); /* print the prompt */ + if ((el->el_flags & UNBUFFERED) == 0) + read_prepare(el); if (el->el_flags & EDIT_DISABLED) { - char *cp = el->el_line.buffer; + char *cp; size_t idx; + if ((el->el_flags & UNBUFFERED) == 0) + cp = el->el_line.buffer; + else + cp = el->el_line.lastchar; term__flush(); @@ -439,7 +451,10 @@ el_gets(EditLine *el, int *nread) if (*cp == 4) /* ought to be stty eof */ break; cp++; - if (cp[-1] == '\r' || cp[-1] == '\n') + crlf = cp[-1] == '\r' || cp[-1] == '\n'; + if (el->el_flags & UNBUFFERED) + break; + if (crlf) break; } @@ -463,8 +478,7 @@ el_gets(EditLine *el, int *nread) #endif /* DEBUG_READ */ break; } - if ((unsigned int)cmdnum >= (unsigned int)(el->el_map.nfunc)) - { /* BUG CHECK command */ + if ((uint)cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */ #ifdef DEBUG_EDIT (void) fprintf(el->el_errfile, "ERROR: illegal command from key 0%o\r\n", ch); @@ -494,7 +508,7 @@ el_gets(EditLine *el, int *nread) el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) { if (cmdnum == VI_DELETE_PREV_CHAR && el->el_chared.c_redo.pos != el->el_chared.c_redo.buf - && isprint(el->el_chared.c_redo.pos[-1])) + && isprint((unsigned char)el->el_chared.c_redo.pos[-1])) el->el_chared.c_redo.pos--; else *el->el_chared.c_redo.pos++ = ch; @@ -536,7 +550,13 @@ el_gets(EditLine *el, int *nread) continue; /* keep going... */ case CC_EOF: /* end of file typed */ - num = 0; + if ((el->el_flags & UNBUFFERED) == 0) + num = 0; + else if (num == -1) { + *el->el_line.lastchar++ = CONTROL('d'); + el->el_line.cursor = el->el_line.lastchar; + num = 1; + } break; case CC_NEWLINE: /* normal end of line */ @@ -567,14 +587,19 @@ el_gets(EditLine *el, int *nread) el->el_state.argument = 1; el->el_state.doingarg = 0; el->el_chared.c_vcmd.action = NOP; + if (el->el_flags & UNBUFFERED) + break; } term__flush(); /* flush any buffered output */ /* make sure the tty is set up correctly */ - (void) tty_cookedmode(el); - if (el->el_flags & HANDLE_SIGNALS) - sig_clr(el); - if (nread) - *nread = num; + if ((el->el_flags & UNBUFFERED) == 0) { + read_finish(el); + if (nread) + *nread = num; + } else { + if (nread) + *nread = el->el_line.lastchar - el->el_line.buffer; + } return (num ? el->el_line.buffer : NULL); } diff --git a/cmd-line-utils/libedit/read.h b/cmd-line-utils/libedit/read.h index b01e77db239..1982f47253b 100644 --- a/cmd-line-utils/libedit/read.h +++ b/cmd-line-utils/libedit/read.h @@ -1,4 +1,4 @@ -/* $NetBSD: read.h,v 1.1 2001/09/27 19:29:50 christos Exp $ */ +/* $NetBSD: read.h,v 1.4 2004/02/27 14:52:18 christos Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -49,6 +49,8 @@ typedef struct el_read_t { } el_read_t; protected int read_init(EditLine *); +protected void read_prepare(EditLine *); +protected void read_finish(EditLine *); protected int el_read_setfn(EditLine *, el_rfunc_t); protected el_rfunc_t el_read_getfn(EditLine *); diff --git a/cmd-line-utils/libedit/readline.c b/cmd-line-utils/libedit/readline.c index 5b40ade582c..761acffc13f 100644 --- a/cmd-line-utils/libedit/readline.c +++ b/cmd-line-utils/libedit/readline.c @@ -1,4 +1,4 @@ -/* $NetBSD: readline.c,v 1.28 2003/03/10 01:14:54 christos Exp $ */ +/* $NetBSD: readline.c,v 1.49 2005/03/10 19:34:46 christos Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -36,10 +36,25 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -__RCSID("$NetBSD: readline.c,v 1.28 2003/03/10 01:14:54 christos Exp $"); -#endif /* not lint && not SCCSID */ +/* AIX requires this to be the first thing in the file. */ +#if defined (_AIX) && !defined (__GNUC__) + #pragma alloca +#endif + +#include <config.h> + +#ifdef __GNUC__ +# undef alloca +# define alloca(n) __builtin_alloca (n) +#else +# ifdef HAVE_ALLOCA_H +# include <alloca.h> +# else +# ifndef _AIX +extern char *alloca (); +# endif +# endif +#endif #include <sys/types.h> #include <sys/stat.h> @@ -51,19 +66,20 @@ __RCSID("$NetBSD: readline.c,v 1.28 2003/03/10 01:14:54 christos Exp $"); #include <stdlib.h> #include <unistd.h> #include <limits.h> -#ifdef HAVE_ALLOCA_H -#include <alloca.h> -#endif -#include "histedit.h" -#include "readline/readline.h" +#include <errno.h> +#include <fcntl.h> +#include <vis.h> + #include "el.h" #include "fcns.h" /* for EL_NUM_FCNS */ +#include "histedit.h" +#include "editline/readline.h" /* for rl_complete() */ -#define TAB '\r' +#define TAB '\r' /* see comment at the #ifdef for sense of this */ -#define GDB_411_HACK +/* #define GDB_411_HACK */ /* readline compatibility stuff - look at readline sources/documentation */ /* to see what these variables mean */ @@ -78,6 +94,9 @@ FILE *rl_outstream = NULL; int rl_point = 0; int rl_end = 0; char *rl_line_buffer = NULL; +VFunction *rl_linefunc = NULL; +int rl_done = 0; +VFunction *rl_event_hook = NULL; int history_base = 1; /* probably never subject to change */ int history_length = 0; @@ -86,16 +105,34 @@ char history_expansion_char = '!'; char history_subst_char = '^'; char *history_no_expand_chars = expand_chars; Function *history_inhibit_expansion_function = NULL; +char *history_arg_extract(int start, int end, const char *str); int rl_inhibit_completion = 0; int rl_attempted_completion_over = 0; char *rl_basic_word_break_characters = break_chars; char *rl_completer_word_break_characters = NULL; char *rl_completer_quote_characters = NULL; -CPFunction *rl_completion_entry_function = NULL; +Function *rl_completion_entry_function = NULL; CPPFunction *rl_attempted_completion_function = NULL; +Function *rl_pre_input_hook = NULL; +Function *rl_startup1_hook = NULL; +Function *rl_getc_function = NULL; +char *rl_terminal_name = NULL; +int rl_already_prompted = 0; +int rl_filename_completion_desired = 0; +int rl_ignore_completion_duplicates = 0; +int rl_catch_signals = 1; +VFunction *rl_redisplay_function = NULL; +Function *rl_startup_hook = NULL; +VFunction *rl_completion_display_matches_hook = NULL; +VFunction *rl_prep_term_function = NULL; +VFunction *rl_deprep_term_function = NULL; /* + * The current prompt string. + */ +char *rl_prompt = NULL; +/* * This is set to character indicating type of completion being done by * rl_complete_internal(); this is available for application completion * functions. @@ -128,30 +165,30 @@ static int _rl_complete_show_all = 0; static History *h = NULL; static EditLine *e = NULL; +static Function *map[256]; static int el_rl_complete_cmdnum = 0; /* internal functions */ static unsigned char _el_rl_complete(EditLine *, int); +static unsigned char _el_rl_tstp(EditLine *, int); static char *_get_prompt(EditLine *); static HIST_ENTRY *_move_history(int); -static int _history_search_gen(const char *, int, int); -static int _history_expand_command(const char *, size_t, char **); +static int _history_expand_command(const char *, size_t, size_t, + char **); static char *_rl_compat_sub(const char *, const char *, - const char *, int); -static int rl_complete_internal(int); + const char *, int); +static int _rl_complete_internal(int); static int _rl_qsort_string_compare(const void *, const void *); - -/* - * needed for prompt switching in readline() - */ -static char *el_rl_prompt = NULL; +static int _rl_event_read_char(EditLine *, char *); +static void _rl_update_pos(void); /* ARGSUSED */ static char * -_get_prompt(EditLine *el __attribute__((unused))) +_get_prompt(EditLine *el __attribute__((__unused__))) { - return (el_rl_prompt); + rl_already_prompted = 1; + return (rl_prompt); } @@ -168,7 +205,7 @@ _move_history(int op) return (HIST_ENTRY *) NULL; rl_he.line = ev.str; - rl_he.data = ""; + rl_he.data = (histdata_t) &(ev.num); return (&rl_he); } @@ -221,29 +258,41 @@ rl_initialize(void) el_set(e, EL_HIST, history, h); /* for proper prompt printing in readline() */ - el_rl_prompt = strdup(""); - if (el_rl_prompt == NULL) { + rl_prompt = strdup(""); + if (rl_prompt == NULL) { history_end(h); el_end(e); return -1; } el_set(e, EL_PROMPT, _get_prompt); - el_set(e, EL_SIGNAL, 1); + el_set(e, EL_SIGNAL, rl_catch_signals); /* set default mode to "emacs"-style and read setting afterwards */ /* so this can be overriden */ el_set(e, EL_EDITOR, "emacs"); + if (rl_terminal_name != NULL) + el_set(e, EL_TERMINAL, rl_terminal_name); + else + el_get(e, EL_TERMINAL, &rl_terminal_name); /* - * Word completition - this has to go AFTER rebinding keys + * Word completion - this has to go AFTER rebinding keys * to emacs-style. */ el_set(e, EL_ADDFN, "rl_complete", - "ReadLine compatible completition function", + "ReadLine compatible completion function", _el_rl_complete); el_set(e, EL_BIND, "^I", "rl_complete", NULL); /* + * Send TSTP when ^Z is pressed. + */ + el_set(e, EL_ADDFN, "rl_tstp", + "ReadLine compatible suspend function", + _el_rl_tstp); + el_set(e, EL_BIND, "^Z", "rl_tstp", NULL); + + /* * Find out where the rl_complete function was added; this is * used later to detect that lastcmd was also rl_complete. */ @@ -264,7 +313,10 @@ rl_initialize(void) li = el_line(e); /* a cheesy way to get rid of const cast. */ rl_line_buffer = memchr(li->buffer, *li->buffer, 1); - rl_point = rl_end = 0; + _rl_update_pos(); + + if (rl_startup_hook) + (*rl_startup_hook)(NULL, 0); return (0); } @@ -281,19 +333,38 @@ readline(const char *prompt) int count; const char *ret; char *buf; + static int used_event_hook; if (e == NULL || h == NULL) rl_initialize(); + rl_done = 0; + /* update prompt accordingly to what has been passed */ if (!prompt) prompt = ""; - if (strcmp(el_rl_prompt, prompt) != 0) { - free(el_rl_prompt); - el_rl_prompt = strdup(prompt); - if (el_rl_prompt == NULL) + if (strcmp(rl_prompt, prompt) != 0) { + free(rl_prompt); + rl_prompt = strdup(prompt); + if (rl_prompt == NULL) return NULL; } + + if (rl_pre_input_hook) + (*rl_pre_input_hook)(NULL, 0); + + if (rl_event_hook && !(e->el_flags&NO_TTY)) { + el_set(e, EL_GETCFN, _rl_event_read_char); + used_event_hook = 1; + } + + if (!rl_event_hook && used_event_hook) { + el_set(e, EL_GETCFN, EL_BUILTIN_GETCFN); + used_event_hook = 0; + } + + rl_already_prompted = 0; + /* get one line from input stream */ ret = el_gets(e, &count); @@ -333,73 +404,178 @@ using_history(void) /* * substitute ``what'' with ``with'', returning resulting string; if - * globally == 1, substitutes all occurences of what, otherwise only the + * globally == 1, substitutes all occurrences of what, otherwise only the * first one */ static char * _rl_compat_sub(const char *str, const char *what, const char *with, int globally) { - char *result; - const char *temp, *new; - unsigned int len, with_len, what_len, add; - size_t size, i; + const char *s; + char *r, *result; + size_t len, with_len, what_len; - result = malloc((size = 16)); - if (result == NULL) - return NULL; - temp = str; + len = strlen(str); with_len = strlen(with); what_len = strlen(what); - len = 0; - do { - new = strstr(temp, what); - if (new) { - i = new - temp; - add = i + with_len; - if (i + add + 1 >= size) { - char *nresult; - size += add + 1; - nresult = realloc(result, size); - if (nresult == NULL) { - free(result); - return NULL; - } - result = nresult; - } - (void) strncpy(&result[len], temp, i); - len += i; - (void) strcpy(&result[len], with); /* safe */ - len += with_len; - temp = new + what_len; - } else { - add = strlen(temp); - if (len + add + 1 >= size) { - char *nresult; - size += add + 1; - nresult = realloc(result, size); - if (nresult == NULL) { - free(result); - return NULL; - } - result = nresult; + + /* calculate length we need for result */ + s = str; + while (*s) { + if (*s == *what && !strncmp(s, what, what_len)) { + len += with_len - what_len; + if (!globally) + break; + s += what_len; + } else + s++; + } + r = result = malloc(len + 1); + if (result == NULL) + return NULL; + s = str; + while (*s) { + if (*s == *what && !strncmp(s, what, what_len)) { + (void)strncpy(r, with, with_len); + r += with_len; + s += what_len; + if (!globally) { + (void)strcpy(r, s); + return(result); } - (void) strcpy(&result[len], temp); /* safe */ - len += add; - temp = NULL; + } else + *r++ = *s++; + } + *r = 0; + return(result); +} + +static char *last_search_pat; /* last !?pat[?] search pattern */ +static char *last_search_match; /* last !?pat[?] that matched */ + +const char * +get_history_event(const char *cmd, int *cindex, int qchar) +{ + int idx, sign, sub, num, begin, ret; + size_t len; + char *pat; + const char *rptr; + HistEvent ev; + + idx = *cindex; + if (cmd[idx++] != history_expansion_char) + return(NULL); + + /* find out which event to take */ + if (cmd[idx] == history_expansion_char || cmd[idx] == 0) { + if (history(h, &ev, H_FIRST) != 0) + return(NULL); + *cindex = cmd[idx]? (idx + 1):idx; + return(ev.str); + } + sign = 0; + if (cmd[idx] == '-') { + sign = 1; + idx++; + } + + if ('0' <= cmd[idx] && cmd[idx] <= '9') { + HIST_ENTRY *rl_he; + + num = 0; + while (cmd[idx] && '0' <= cmd[idx] && cmd[idx] <= '9') { + num = num * 10 + cmd[idx] - '0'; + idx++; } - } while (temp && globally); - result[len] = '\0'; + if (sign) + num = history_length - num + 1; - return (result); -} + if (!(rl_he = history_get(num))) + return(NULL); + + *cindex = idx; + return(rl_he->line); + } + sub = 0; + if (cmd[idx] == '?') { + sub = 1; + idx++; + } + begin = idx; + while (cmd[idx]) { + if (cmd[idx] == '\n') + break; + if (sub && cmd[idx] == '?') + break; + if (!sub && (cmd[idx] == ':' || cmd[idx] == ' ' + || cmd[idx] == '\t' || cmd[idx] == qchar)) + break; + idx++; + } + len = idx - begin; + if (sub && cmd[idx] == '?') + idx++; + if (sub && len == 0 && last_search_pat && *last_search_pat) + pat = last_search_pat; + else if (len == 0) + return(NULL); + else { + if ((pat = malloc(len + 1)) == NULL) + return NULL; + (void)strncpy(pat, cmd + begin, len); + pat[len] = '\0'; + } + if (history(h, &ev, H_CURR) != 0) { + if (pat != last_search_pat) + free(pat); + return (NULL); + } + num = ev.num; + + if (sub) { + if (pat != last_search_pat) { + if (last_search_pat) + free(last_search_pat); + last_search_pat = pat; + } + ret = history_search(pat, -1); + } else + ret = history_search_prefix(pat, -1); + + if (ret == -1) { + /* restore to end of list on failed search */ + history(h, &ev, H_FIRST); + (void)fprintf(rl_outstream, "%s: Event not found\n", pat); + if (pat != last_search_pat) + free(pat); + return(NULL); + } + + if (sub && len) { + if (last_search_match && last_search_match != pat) + free(last_search_match); + last_search_match = pat; + } + + if (pat != last_search_pat) + free(pat); + + if (history(h, &ev, H_CURR) != 0) + return(NULL); + *cindex = idx; + rptr = ev.str; + + /* roll back to original position */ + (void)history(h, &ev, H_SET, num); + + return rptr; +} /* * the real function doing history expansion - takes as argument command * to do and data upon which the command should be executed * does expansion the way I've understood readline documentation - * word designator ``%'' isn't supported (yet ?) * * returns 0 if data was not modified, 1 if it was and 2 if the string * should be only printed and not executed; in case of error, @@ -407,144 +583,145 @@ _rl_compat_sub(const char *str, const char *what, const char *with, * it's callers responsibility to free() string returned in *result */ static int -_history_expand_command(const char *command, size_t cmdlen, char **result) +_history_expand_command(const char *command, size_t offs, size_t cmdlen, + char **result) { - char **arr, *tempcmd, *line, *search = NULL, *cmd; - const char *event_data = NULL; + char *tmp, *search = NULL, *aptr; + const char *ptr, *cmd; static char *from = NULL, *to = NULL; - int start = -1, end = -1, max, i, idx; - int h_on = 0, t_on = 0, r_on = 0, e_on = 0, p_on = 0, g_on = 0; - int event_num = 0, retval; - size_t cmdsize; + int start, end, idx, has_mods = 0; + int p_on = 0, g_on = 0; *result = NULL; + aptr = NULL; + ptr = NULL; - cmd = alloca(cmdlen + 1); - (void) strncpy(cmd, command, cmdlen); - cmd[cmdlen] = 0; + /* First get event specifier */ + idx = 0; - idx = 1; - /* find out which event to take */ - if (cmd[idx] == history_expansion_char) { - event_num = history_length; - idx++; + if (strchr(":^*$", command[offs + 1])) { + char str[4]; + /* + * "!:" is shorthand for "!!:". + * "!^", "!*" and "!$" are shorthand for + * "!!:^", "!!:*" and "!!:$" respectively. + */ + str[0] = str[1] = '!'; + str[2] = '0'; + ptr = get_history_event(str, &idx, 0); + idx = (command[offs + 1] == ':')? 1:0; + has_mods = 1; } else { - int off, num; - size_t len; - off = idx; - while (cmd[off] && !strchr(":^$*-%", cmd[off])) - off++; - num = atoi(&cmd[idx]); - if (num != 0) { - event_num = num; - if (num < 0) - event_num += history_length + 1; + if (command[offs + 1] == '#') { + /* use command so far */ + if ((aptr = malloc(offs + 1)) == NULL) + return -1; + (void)strncpy(aptr, command, offs); + aptr[offs] = '\0'; + idx = 1; } else { - int prefix = 1, curr_num; - HistEvent ev; - - len = off - idx; - if (cmd[idx] == '?') { - idx++, len--; - if (cmd[off - 1] == '?') - len--; - else if (cmd[off] != '\n' && cmd[off] != '\0') - return (-1); - prefix = 0; - } - search = alloca(len + 1); - (void) strncpy(search, &cmd[idx], len); - search[len] = '\0'; + int qchar; - if (history(h, &ev, H_CURR) != 0) - return (-1); - curr_num = ev.num; + qchar = (offs > 0 && command[offs - 1] == '"')? '"':0; + ptr = get_history_event(command + offs, &idx, qchar); + } + has_mods = command[offs + idx] == ':'; + } - if (prefix) - retval = history_search_prefix(search, -1); - else - retval = history_search(search, -1); + if (ptr == NULL && aptr == NULL) + return(-1); - if (retval == -1) { - fprintf(rl_outstream, "%s: Event not found\n", - search); - return (-1); - } - if (history(h, &ev, H_CURR) != 0) - return (-1); - event_data = ev.str; - - /* roll back to original position */ - history(h, &ev, H_NEXT_EVENT, curr_num); - } - idx = off; + if (!has_mods) { + *result = strdup(aptr? aptr : ptr); + if (aptr) + free(aptr); + return(1); } - if (!event_data && event_num >= 0) { - HIST_ENTRY *rl_he; - rl_he = history_get(event_num); - if (!rl_he) - return (0); - event_data = rl_he->line; + cmd = command + offs + idx + 1; + + /* Now parse any word designators */ + + if (*cmd == '%') /* last word matched by ?pat? */ + tmp = strdup(last_search_match? last_search_match:""); + else if (strchr("^*$-0123456789", *cmd)) { + start = end = -1; + if (*cmd == '^') + start = end = 1, cmd++; + else if (*cmd == '$') + start = -1, cmd++; + else if (*cmd == '*') + start = 1, cmd++; + else if (*cmd == '-' || isdigit((unsigned char) *cmd)) { + start = 0; + while (*cmd && '0' <= *cmd && *cmd <= '9') + start = start * 10 + *cmd++ - '0'; + + if (*cmd == '-') { + if (isdigit((unsigned char) cmd[1])) { + cmd++; + end = 0; + while (*cmd && '0' <= *cmd && *cmd <= '9') + end = end * 10 + *cmd++ - '0'; + } else if (cmd[1] == '$') { + cmd += 2; + end = -1; + } else { + cmd++; + end = -2; + } + } else if (*cmd == '*') + end = -1, cmd++; + else + end = start; + } + tmp = history_arg_extract(start, end, aptr? aptr:ptr); + if (tmp == NULL) { + (void)fprintf(rl_outstream, "%s: Bad word specifier", + command + offs + idx); + if (aptr) + free(aptr); + return(-1); + } } else - return (-1); + tmp = strdup(aptr? aptr:ptr); - if (cmd[idx] != ':') - return (-1); - cmd += idx + 1; - - /* recognize cmd */ - if (*cmd == '^') - start = end = 1, cmd++; - else if (*cmd == '$') - start = end = -1, cmd++; - else if (*cmd == '*') - start = 1, end = -1, cmd++; - else if (isdigit((unsigned char) *cmd)) { - const char *temp; - int shifted = 0; - - start = atoi(cmd); - temp = cmd; - for (; isdigit((unsigned char) *cmd); cmd++); - if (temp != cmd) - shifted = 1; - if (shifted && *cmd == '-') { - if (!isdigit((unsigned char) *(cmd + 1))) - end = -2; - else { - end = atoi(cmd + 1); - for (; isdigit((unsigned char) *cmd); cmd++); - } - } else if (shifted && *cmd == '*') - end = -1, cmd++; - else if (shifted) - end = start; + if (aptr) + free(aptr); + + if (*cmd == 0 || (cmd - (command + offs) >= cmdlen)) { + *result = tmp; + return(1); } - if (*cmd == ':') - cmd++; - line = strdup(event_data); - if (line == NULL) - return 0; for (; *cmd; cmd++) { if (*cmd == ':') continue; - else if (*cmd == 'h') - h_on = 1 | g_on, g_on = 0; - else if (*cmd == 't') - t_on = 1 | g_on, g_on = 0; - else if (*cmd == 'r') - r_on = 1 | g_on, g_on = 0; - else if (*cmd == 'e') - e_on = 1 | g_on, g_on = 0; - else if (*cmd == 'p') - p_on = 1 | g_on, g_on = 0; + else if (*cmd == 'h') { /* remove trailing path */ + if ((aptr = strrchr(tmp, '/')) != NULL) + *aptr = 0; + } else if (*cmd == 't') { /* remove leading path */ + if ((aptr = strrchr(tmp, '/')) != NULL) { + aptr = strdup(aptr + 1); + free(tmp); + tmp = aptr; + } + } else if (*cmd == 'r') { /* remove trailing suffix */ + if ((aptr = strrchr(tmp, '.')) != NULL) + *aptr = 0; + } else if (*cmd == 'e') { /* remove all but suffix */ + if ((aptr = strrchr(tmp, '.')) != NULL) { + aptr = strdup(aptr); + free(tmp); + tmp = aptr; + } + } else if (*cmd == 'p') /* print only */ + p_on = 1; else if (*cmd == 'g') g_on = 2; else if (*cmd == 's' || *cmd == '&') { char *what, *with, delim; - unsigned int len, from_len; + size_t len, from_len; size_t size; if (*cmd == '&' && (from == NULL || to == NULL)) @@ -559,13 +736,12 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) } len = 0; for (; *cmd && *cmd != delim; cmd++) { - if (*cmd == '\\' - && *(cmd + 1) == delim) + if (*cmd == '\\' && cmd[1] == delim) cmd++; if (len >= size) { char *nwhat; nwhat = realloc(what, - (size <<= 1)); + (size <<= 1)); if (nwhat == NULL) { free(what); return 0; @@ -612,7 +788,7 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) } if (*cmd == '&') { /* safe */ - (void) strcpy(&with[len], from); + (void)strcpy(&with[len], from); len += from_len; continue; } @@ -624,88 +800,18 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) } with[len] = '\0'; to = with; - - tempcmd = _rl_compat_sub(line, from, to, - (g_on) ? 1 : 0); - if (tempcmd) { - free(line); - line = tempcmd; - } - g_on = 0; } - } - } - - arr = history_tokenize(line); - free(line); /* no more needed */ - if (arr && *arr == NULL) - free(arr), arr = NULL; - if (!arr) - return (-1); - - /* find out max valid idx to array of array */ - max = 0; - for (i = 0; arr[i]; i++) - max++; - max--; - - /* set boundaries to something relevant */ - if (start < 0) - start = 1; - if (end < 0) - end = max - ((end < -1) ? 1 : 0); - - /* check boundaries ... */ - if (start > max || end > max || start > end) - return (-1); - - for (i = 0; i <= max; i++) { - char *temp; - if (h_on && (i == 1 || h_on > 1) && - (temp = strrchr(arr[i], '/'))) - *(temp + 1) = '\0'; - if (t_on && (i == 1 || t_on > 1) && - (temp = strrchr(arr[i], '/'))) - (void) strcpy(arr[i], temp + 1); - if (r_on && (i == 1 || r_on > 1) && - (temp = strrchr(arr[i], '.'))) - *temp = '\0'; - if (e_on && (i == 1 || e_on > 1) && - (temp = strrchr(arr[i], '.'))) - (void) strcpy(arr[i], temp); - } - cmdsize = 1, cmdlen = 0; - if ((tempcmd = malloc(cmdsize)) == NULL) - return 0; - for (i = start; start <= i && i <= end; i++) { - int arr_len; - - arr_len = strlen(arr[i]); - if (cmdlen + arr_len + 1 >= cmdsize) { - char *ntempcmd; - cmdsize += arr_len + 1; - ntempcmd = realloc(tempcmd, cmdsize); - if (ntempcmd == NULL) { - free(tempcmd); - return 0; + aptr = _rl_compat_sub(tmp, from, to, g_on); + if (aptr) { + free(tmp); + tmp = aptr; } - tempcmd = ntempcmd; + g_on = 0; } - (void) strcpy(&tempcmd[cmdlen], arr[i]); /* safe */ - cmdlen += arr_len; - tempcmd[cmdlen++] = ' '; /* add a space */ } - while (cmdlen > 0 && isspace((unsigned char) tempcmd[cmdlen - 1])) - cmdlen--; - tempcmd[cmdlen] = '\0'; - - *result = tempcmd; - - for (i = 0; i <= max; i++) - free(arr[i]); - free(arr), arr = (char **) NULL; - return (p_on) ? 2 : 1; + *result = tmp; + return (p_on? 2:1); } @@ -715,27 +821,36 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) int history_expand(char *str, char **output) { - int i, retval = 0, idx; - size_t size; - char *temp, *result; + int ret = 0; + size_t idx, i, size; + char *tmp, *result; if (h == NULL || e == NULL) rl_initialize(); - *output = strdup(str); /* do it early */ - if (*output == NULL) - return 0; + if (history_expansion_char == 0) { + *output = strdup(str); + return(0); + } + *output = NULL; if (str[0] == history_subst_char) { /* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */ - temp = alloca(4 + strlen(str) + 1); - temp[0] = temp[1] = history_expansion_char; - temp[2] = ':'; - temp[3] = 's'; - (void) strcpy(temp + 4, str); - str = temp; + *output = malloc(strlen(str) + 4 + 1); + if (*output == NULL) + return 0; + (*output)[0] = (*output)[1] = history_expansion_char; + (*output)[2] = ':'; + (*output)[3] = 's'; + (void)strcpy((*output) + 4, str); + str = *output; + } else { + *output = strdup(str); + if (*output == NULL) + return 0; } -#define ADD_STRING(what, len) \ + +#define ADD_STRING(what, len) \ { \ if (idx + len + 1 > size) { \ char *nresult = realloc(result, (size += len + 1));\ @@ -753,35 +868,35 @@ history_expand(char *str, char **output) result = NULL; size = idx = 0; for (i = 0; str[i];) { - int start, j, loop_again; - size_t len; + int qchar, loop_again; + size_t len, start, j; + qchar = 0; loop_again = 1; start = j = i; loop: for (; str[j]; j++) { if (str[j] == '\\' && str[j + 1] == history_expansion_char) { - (void) strcpy(&str[j], &str[j + 1]); + (void)strcpy(&str[j], &str[j + 1]); continue; } if (!loop_again) { - if (str[j] == '?') { - while (str[j] && str[++j] != '?'); - if (str[j] == '?') - j++; - } else if (isspace((unsigned char) str[j])) + if (isspace((unsigned char) str[j]) + || str[j] == qchar) break; } if (str[j] == history_expansion_char && !strchr(history_no_expand_chars, str[j + 1]) && (!history_inhibit_expansion_function || - (*history_inhibit_expansion_function)(str, j) == 0)) + (*history_inhibit_expansion_function)(str, + (int)j) == 0)) break; } - if (str[j] && str[j + 1] != '#' && loop_again) { + if (str[j] && loop_again) { i = j; + qchar = (j > 0 && str[j - 1] == '"' )? '"':0; j++; if (str[j] == history_expansion_char) j++; @@ -789,61 +904,116 @@ loop: goto loop; } len = i - start; - temp = &str[start]; - ADD_STRING(temp, len); + tmp = &str[start]; + ADD_STRING(tmp, len); - if (str[i] == '\0' || str[i] != history_expansion_char - || str[i + 1] == '#') { + if (str[i] == '\0' || str[i] != history_expansion_char) { len = j - i; - temp = &str[i]; - ADD_STRING(temp, len); + tmp = &str[i]; + ADD_STRING(tmp, len); if (start == 0) - retval = 0; + ret = 0; else - retval = 1; + ret = 1; break; } - retval = _history_expand_command(&str[i], (size_t) (j - i), - &temp); - if (retval != -1) { - len = strlen(temp); - ADD_STRING(temp, len); + ret = _history_expand_command (str, i, (j - i), &tmp); + if (ret > 0 && tmp) { + len = strlen(tmp); + ADD_STRING(tmp, len); + free(tmp); } i = j; - } /* for(i ...) */ + } - if (retval == 2) { - add_history(temp); + /* ret is 2 for "print only" option */ + if (ret == 2) { + add_history(result); #ifdef GDB_411_HACK /* gdb 4.11 has been shipped with readline, where */ /* history_expand() returned -1 when the line */ /* should not be executed; in readline 2.1+ */ /* it should return 2 in such a case */ - retval = -1; + ret = -1; #endif } free(*output); *output = result; - return (retval); + return (ret); } +/* +* Return a string consisting of arguments of "str" from "start" to "end". +*/ +char * +history_arg_extract(int start, int end, const char *str) +{ + size_t i, len, max; + char **arr, *result; + + arr = history_tokenize(str); + if (!arr) + return(NULL); + if (arr && *arr == NULL) { + free(arr); + return(NULL); + } + + for (max = 0; arr[max]; max++) + continue; + max--; + + if (start == '$') + start = max; + if (end == '$') + end = max; + if (end < 0) + end = max + end + 1; + if (start < 0) + start = end; + + if (start < 0 || end < 0 || start > max || end > max || start > end) + return(NULL); + + for (i = start, len = 0; i <= end; i++) + len += strlen(arr[i]) + 1; + len++; + result = malloc(len); + if (result == NULL) + return NULL; + + for (i = start, len = 0; i <= end; i++) { + (void)strcpy(result + len, arr[i]); + len += strlen(arr[i]); + if (i < end) + result[len++] = ' '; + } + result[len] = 0; + + for (i = 0; arr[i]; i++) + free(arr[i]); + free(arr); + + return(result); +} /* - * Parse the string into individual tokens, similarily to how shell would do it. + * Parse the string into individual tokens, + * similar to how shell would do it. */ char ** history_tokenize(const char *str) { - int size = 1, result_idx = 0, i, start; + int size = 1, idx = 0, i, start; size_t len; char **result = NULL, *temp, delim = '\0'; - for (i = 0; str[i]; i++) { + for (i = 0; str[i];) { while (isspace((unsigned char) str[i])) i++; start = i; - for (; str[i]; i++) { + for (; str[i];) { if (str[i] == '\\') { if (str[i+1] != '\0') i++; @@ -855,9 +1025,11 @@ history_tokenize(const char *str) break; else if (!delim && strchr("'`\"", str[i])) delim = str[i]; + if (str[i]) + i++; } - if (result_idx + 2 >= size) { + if (idx + 2 >= size) { char **nresult; size <<= 1; nresult = realloc(result, size * sizeof(char *)); @@ -870,15 +1042,18 @@ history_tokenize(const char *str) len = i - start; temp = malloc(len + 1); if (temp == NULL) { + for (i = 0; i < idx; i++) + free(result[i]); free(result); return NULL; } - (void) strncpy(temp, &str[start], len); + (void)strncpy(temp, &str[start], len); temp[len] = '\0'; - result[result_idx++] = temp; - result[result_idx] = NULL; + result[idx++] = temp; + result[idx] = NULL; + if (str[i]) + i++; } - return (result); } @@ -962,28 +1137,29 @@ history_get(int num) { static HIST_ENTRY she; HistEvent ev; - int i = 1, curr_num; + int curr_num; if (h == NULL || e == NULL) rl_initialize(); - /* rewind to beginning */ + /* save current position */ if (history(h, &ev, H_CURR) != 0) return (NULL); curr_num = ev.num; - if (history(h, &ev, H_LAST) != 0) + + /* start from most recent */ + if (history(h, &ev, H_FIRST) != 0) return (NULL); /* error */ - while (i < num && history(h, &ev, H_PREV) == 0) - i++; - if (i != num) - return (NULL); /* not so many entries */ + + /* look backwards for event matching specified offset */ + if (history(h, &ev, H_NEXT_EVENT, num)) + return (NULL); she.line = ev.str; she.data = NULL; - /* rewind history to the same event it was before */ - (void) history(h, &ev, H_FIRST); - (void) history(h, &ev, H_NEXT_EVENT, curr_num); + /* restore pointer to where it was */ + (void)history(h, &ev, H_SET, curr_num); return (&she); } @@ -1000,11 +1176,11 @@ add_history(const char *line) if (h == NULL || e == NULL) rl_initialize(); - (void) history(h, &ev, H_ENTER, line); + (void)history(h, &ev, H_ENTER, line); if (history(h, &ev, H_GETSIZE) == 0) history_length = ev.num; - return (!(history_length > 0)); /* return 0 if all is okay */ + return (!(history_length > 0)); /* return 0 if all is okay */ } @@ -1086,22 +1262,17 @@ int history_set_pos(int pos) { HistEvent ev; - int off, curr_num; + int curr_num; if (pos > history_length || pos < 0) return (-1); history(h, &ev, H_CURR); curr_num = ev.num; - history(h, &ev, H_FIRST); - off = 0; - while (off < pos && history(h, &ev, H_NEXT) == 0) - off++; - if (off != pos) { /* do a rollback in case of error */ - history(h, &ev, H_FIRST); - history(h, &ev, H_NEXT_EVENT, curr_num); - return (-1); + if (history(h, &ev, H_SET, pos)) { + history(h, &ev, H_SET, curr_num); + return(-1); } return (0); } @@ -1130,10 +1301,10 @@ next_history(void) /* - * generic history search function + * searches for first history event containing the str */ -static int -_history_search_gen(const char *str, int direction, int pos) +int +history_search(const char *str, int direction) { HistEvent ev; const char *strp; @@ -1144,38 +1315,25 @@ _history_search_gen(const char *str, int direction, int pos) curr_num = ev.num; for (;;) { - strp = strstr(ev.str, str); - if (strp && (pos < 0 || &ev.str[pos] == strp)) + if ((strp = strstr(ev.str, str)) != NULL) return (int) (strp - ev.str); - if (history(h, &ev, direction < 0 ? H_PREV : H_NEXT) != 0) + if (history(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0) break; } - - history(h, &ev, direction < 0 ? H_NEXT_EVENT : H_PREV_EVENT, curr_num); - + history(h, &ev, H_SET, curr_num); return (-1); } /* - * searches for first history event containing the str - */ -int -history_search(const char *str, int direction) -{ - - return (_history_search_gen(str, direction, -1)); -} - - -/* * searches for first history event beginning with str */ int history_search_prefix(const char *str, int direction) { + HistEvent ev; - return (_history_search_gen(str, direction, 0)); + return (history(h, &ev, direction < 0? H_PREV_STR:H_NEXT_STR, str)); } @@ -1185,8 +1343,8 @@ history_search_prefix(const char *str, int direction) */ /* ARGSUSED */ int -history_search_pos(const char *str, - int direction __attribute__((unused)), int pos) +history_search_pos(const char *str, + int direction __attribute__((__unused__)), int pos) { HistEvent ev; int curr_num, off; @@ -1217,7 +1375,7 @@ history_search_pos(const char *str, /********************************/ -/* completition functions */ +/* completion functions */ /* * does tilde expansion of strings of type ``~user/foo'' @@ -1246,7 +1404,7 @@ tilde_expand(char *txt) temp = malloc(len); if (temp == NULL) return NULL; - (void) strncpy(temp, txt + 1, len - 2); + (void)strncpy(temp, txt + 1, len - 2); temp[len - 2] = '\0'; } pass = getpwnam(temp); @@ -1261,7 +1419,7 @@ tilde_expand(char *txt) temp = malloc(strlen(pass->pw_dir) + 1 + strlen(txt) + 1); if (temp == NULL) return NULL; - (void) sprintf(temp, "%s/%s", pass->pw_dir, txt); + (void)sprintf(temp, "%s/%s", pass->pw_dir, txt); return (temp); } @@ -1295,7 +1453,7 @@ filename_completion_function(const char *text, int state) return NULL; } filename = nptr; - (void) strcpy(filename, temp); + (void)strcpy(filename, temp); len = temp - text; /* including last slash */ nptr = realloc(dirname, len + 1); if (nptr == NULL) { @@ -1303,12 +1461,16 @@ filename_completion_function(const char *text, int state) return NULL; } dirname = nptr; - (void) strncpy(dirname, text, len); + (void)strncpy(dirname, text, len); dirname[len] = '\0'; } else { - filename = strdup(text); - if (filename == NULL) - return NULL; + if (*text == 0) + filename = NULL; + else { + filename = strdup(text); + if (filename == NULL) + return NULL; + } dirname = NULL; } @@ -1324,13 +1486,11 @@ filename_completion_function(const char *text, int state) return NULL; } dirname = nptr; - (void) strcpy(dirname, temp); /* safe */ + (void)strcpy(dirname, temp); /* safe */ free(temp); /* no longer needed */ } /* will be used in cycle */ - filename_len = strlen(filename); - if (filename_len == 0) - return (NULL); /* no expansion possible */ + filename_len = filename ? strlen(filename) : 0; if (dir != NULL) { (void)closedir(dir); @@ -1342,14 +1502,17 @@ filename_completion_function(const char *text, int state) } /* find the match */ while ((entry = readdir(dir)) != NULL) { + /* skip . and .. */ + if (entry->d_name[0] == '.' && (!entry->d_name[1] + || (entry->d_name[1] == '.' && !entry->d_name[2]))) + continue; + if (filename_len == 0) + break; /* otherwise, get first entry where first */ /* filename_len characters are equal */ if (entry->d_name[0] == filename[0] -#ifndef STRUCT_DIRENT_HAS_D_NAMLEN + /* Some dirents have d_namlen, but it is not portable. */ && strlen(entry->d_name) >= filename_len -#else - && entry->d_namlen >= filename_len -#endif && strncmp(entry->d_name, filename, filename_len) == 0) break; @@ -1358,16 +1521,13 @@ filename_completion_function(const char *text, int state) if (entry) { /* match found */ struct stat stbuf; -#ifndef STRUCT_DIRENT_HAS_D_NAMLEN + /* Some dirents have d_namlen, but it is not portable. */ len = strlen(entry->d_name) + -#else - len = entry->d_namlen + -#endif ((dirname) ? strlen(dirname) : 0) + 1 + 1; temp = malloc(len); if (temp == NULL) return NULL; - (void) sprintf(temp, "%s%s", + (void)sprintf(temp, "%s%s", dirname ? dirname : "", entry->d_name); /* safe */ /* test, if it's directory */ @@ -1420,32 +1580,43 @@ username_completion_function(const char *text, int state) */ /* ARGSUSED */ static unsigned char -_el_rl_complete(EditLine *el __attribute__((unused)), int ch) +_el_rl_complete(EditLine *el __attribute__((__unused__)), int ch) { return (unsigned char) rl_complete(0, ch); } +/* + * el-compatible wrapper to send TSTP on ^Z + */ +/* ARGSUSED */ +static unsigned char +_el_rl_tstp(EditLine *el __attribute__((__unused__)), int ch __attribute__((__unused__))) +{ + (void)kill(0, SIGTSTP); + return CC_NORM; +} /* - * returns list of completitions for text given + * returns list of completions for text given */ char ** completion_matches(const char *text, CPFunction *genfunc) { char **match_list = NULL, *retstr, *prevstr; size_t match_list_len, max_equal, which, i; - unsigned int matches; + size_t matches; if (h == NULL || e == NULL) rl_initialize(); matches = 0; match_list_len = 1; - while ((retstr = (*genfunc) (text, matches)) != NULL) { + while ((retstr = (*genfunc) (text, (int)matches)) != NULL) { /* allow for list terminator here */ - if (matches + 2 >= match_list_len) { + if (matches + 3 >= match_list_len) { char **nmatch_list; - match_list_len <<= 1; + while (matches + 3 >= match_list_len) + match_list_len <<= 1; nmatch_list = realloc(match_list, match_list_len * sizeof(char *)); if (nmatch_list == NULL) { @@ -1477,7 +1648,7 @@ completion_matches(const char *text, CPFunction *genfunc) free(match_list); return NULL; } - (void) strncpy(retstr, match_list[1], max_equal); + (void)strncpy(retstr, match_list[1], max_equal); retstr[max_equal] = '\0'; match_list[0] = retstr; @@ -1532,9 +1703,10 @@ rl_display_match_list (matches, len, max) idx = 1; for(; count > 0; count--) { - for(i=0; i < limit && matches[idx]; i++, idx++) - fprintf(e->el_outfile, "%-*s ", max, matches[idx]); - fprintf(e->el_outfile, "\n"); + for(i = 0; i < limit && matches[idx]; i++, idx++) + (void)fprintf(e->el_outfile, "%-*s ", max, + matches[idx]); + (void)fprintf(e->el_outfile, "\n"); } } @@ -1550,9 +1722,9 @@ rl_display_match_list (matches, len, max) * Note: '*' support is not implemented */ static int -rl_complete_internal(int what_to_do) +_rl_complete_internal(int what_to_do) { - CPFunction *complet_func; + Function *complet_func; const LineInfo *li; char *temp, **matches; const char *ctemp; @@ -1565,7 +1737,7 @@ rl_complete_internal(int what_to_do) complet_func = rl_completion_entry_function; if (!complet_func) - complet_func = filename_completion_function; + complet_func = (Function *)(void *)filename_completion_function; /* We now look backwards for the start of a filename/variable word */ li = el_line(e); @@ -1573,26 +1745,26 @@ rl_complete_internal(int what_to_do) while (ctemp > li->buffer && !strchr(rl_basic_word_break_characters, ctemp[-1]) && (!rl_special_prefixes - || !strchr(rl_special_prefixes, ctemp[-1]) ) ) + || !strchr(rl_special_prefixes, ctemp[-1]) ) ) ctemp--; len = li->cursor - ctemp; temp = alloca(len + 1); - (void) strncpy(temp, ctemp, len); + (void)strncpy(temp, ctemp, len); temp[len] = '\0'; /* these can be used by function called in completion_matches() */ /* or (*rl_attempted_completion_function)() */ - rl_point = li->cursor - li->buffer; - rl_end = li->lastchar - li->buffer; + _rl_update_pos(); - if (!rl_attempted_completion_function) - matches = completion_matches(temp, complet_func); - else { + if (rl_attempted_completion_function) { int end = li->cursor - li->buffer; matches = (*rl_attempted_completion_function) (temp, (int) (end - len), end); - } + } else + matches = 0; + if (!rl_attempted_completion_function || !matches) + matches = completion_matches(temp, (CPFunction *)complet_func); if (matches) { int i, retval = CC_REFRESH; @@ -1613,11 +1785,12 @@ rl_complete_internal(int what_to_do) if (matches[2] == NULL && strcmp(matches[0], matches[1]) == 0) { /* * We found exact match. Add a space after - * it, unless we do filename completition and the + * it, unless we do filename completion and the * object is a directory. */ size_t alen = strlen(matches[0]); - if ((complet_func != filename_completion_function + if ((complet_func != + (Function *)filename_completion_function || (alen > 0 && (matches[0])[alen - 1] != '/')) && rl_completion_append_character) { char buf[2]; @@ -1640,20 +1813,20 @@ rl_complete_internal(int what_to_do) matches_num = i - 1; /* newline to get on next line from command line */ - fprintf(e->el_outfile, "\n"); + (void)fprintf(e->el_outfile, "\n"); /* * If there are too many items, ask user for display * confirmation. */ if (matches_num > rl_completion_query_items) { - fprintf(e->el_outfile, - "Display all %d possibilities? (y or n) ", - matches_num); - fflush(e->el_outfile); + (void)fprintf(e->el_outfile, + "Display all %d possibilities? (y or n) ", + matches_num); + (void)fflush(e->el_outfile); if (getc(stdin) != 'y') match_display = 0; - fprintf(e->el_outfile, "\n"); + (void)fprintf(e->el_outfile, "\n"); } if (match_display) @@ -1689,20 +1862,24 @@ rl_complete_internal(int what_to_do) * complete word at current point */ int +/*ARGSUSED*/ rl_complete(int ignore, int invoking_key) { if (h == NULL || e == NULL) rl_initialize(); if (rl_inhibit_completion) { - rl_insert(ignore, invoking_key); + char arr[2]; + arr[0] = (char)invoking_key; + arr[1] = '\0'; + el_insertstr(e, arr); return (CC_REFRESH); } else if (e->el_state.lastcmd == el_rl_complete_cmdnum) - return rl_complete_internal('?'); + return _rl_complete_internal('?'); else if (_rl_complete_show_all) - return rl_complete_internal('!'); + return _rl_complete_internal('!'); else - return (rl_complete_internal(TAB)); + return _rl_complete_internal(TAB); } @@ -1751,7 +1928,7 @@ rl_read_key(void) */ /* ARGSUSED */ void -rl_reset_terminal(const char *p __attribute__((unused))) +rl_reset_terminal(const char *p __attribute__((__unused__))) { if (h == NULL || e == NULL) @@ -1780,3 +1957,211 @@ rl_insert(int count, int c) return (0); } + +/*ARGSUSED*/ +int +rl_newline(int count, int c) +{ + /* + * Readline-4.0 appears to ignore the args. + */ + return rl_insert(1, '\n'); +} + +/*ARGSUSED*/ +static unsigned char +rl_bind_wrapper(EditLine *el, unsigned char c) +{ + if (map[c] == NULL) + return CC_ERROR; + + _rl_update_pos(); + + (*map[c])(NULL, c); + + /* If rl_done was set by the above call, deal with it here */ + if (rl_done) + return CC_EOF; + + return CC_NORM; +} + +int +rl_add_defun(const char *name, Function *fun, int c) +{ + char dest[8]; + if (c >= sizeof(map) / sizeof(map[0]) || c < 0) + return -1; + map[(unsigned char)c] = fun; + el_set(e, EL_ADDFN, name, name, rl_bind_wrapper); + vis(dest, c, VIS_WHITE|VIS_NOSLASH, 0); + el_set(e, EL_BIND, dest, name); + return 0; +} + +void +rl_callback_read_char() +{ + int count = 0, done = 0; + const char *buf = el_gets(e, &count); + char *wbuf; + + if (buf == NULL || count-- <= 0) + return; +#ifdef CTRL2 /* _AIX */ + if (count == 0 && buf[0] == CTRL2('d')) +#else + if (count == 0 && buf[0] == CTRL('d')) +#endif + done = 1; + if (buf[count] == '\n' || buf[count] == '\r') + done = 2; + + if (done && rl_linefunc != NULL) { + el_set(e, EL_UNBUFFERED, 0); + if (done == 2) { + if ((wbuf = strdup(buf)) != NULL) + wbuf[count] = '\0'; + } else + wbuf = NULL; + (*(void (*)(const char *))rl_linefunc)(wbuf); + el_set(e, EL_UNBUFFERED, 1); + } +} + +void +rl_callback_handler_install (const char *prompt, VFunction *linefunc) +{ + if (e == NULL) { + rl_initialize(); + } + if (rl_prompt) + free(rl_prompt); + rl_prompt = prompt ? strdup(strchr(prompt, *prompt)) : NULL; + rl_linefunc = linefunc; + el_set(e, EL_UNBUFFERED, 1); +} + +void +rl_callback_handler_remove(void) +{ + el_set(e, EL_UNBUFFERED, 0); +} + +void +rl_redisplay(void) +{ + char a[2]; +#ifdef CTRL2 /* _AIX */ + a[0] = CTRL2('r'); +#else + a[0] = CTRL('r'); +#endif + a[1] = '\0'; + el_push(e, a); +} + +int +rl_get_previous_history(int count, int key) +{ + char a[2]; + a[0] = key; + a[1] = '\0'; + while (count--) + el_push(e, a); + return 0; +} + +void +/*ARGSUSED*/ +rl_prep_terminal(int meta_flag) +{ + el_set(e, EL_PREP_TERM, 1); +} + +void +rl_deprep_terminal() +{ + el_set(e, EL_PREP_TERM, 0); +} + +int +rl_read_init_file(const char *s) +{ + return(el_source(e, s)); +} + +int +rl_parse_and_bind(const char *line) +{ + const char **argv; + int argc; + Tokenizer *tok; + + tok = tok_init(NULL); + tok_str(tok, line, &argc, &argv); + argc = el_parse(e, argc, argv); + tok_end(tok); + return (argc ? 1 : 0); +} + +void +rl_stuff_char(int c) +{ + char buf[2]; + + buf[0] = c; + buf[1] = '\0'; + el_insertstr(e, buf); +} + +static int +_rl_event_read_char(EditLine *el, char *cp) +{ + int n, num_read = 0; + + *cp = 0; + while (rl_event_hook) { + + (*rl_event_hook)(); + +#if defined(FIONREAD) + if (ioctl(el->el_infd, FIONREAD, &n) < 0) + return(-1); + if (n) + num_read = read(el->el_infd, cp, 1); + else + num_read = 0; +#elif defined(F_SETFL) && defined(O_NDELAY) + if ((n = fcntl(el->el_infd, F_GETFL, 0)) < 0) + return(-1); + if (fcntl(el->el_infd, F_SETFL, n|O_NDELAY) < 0) + return(-1); + num_read = read(el->el_infd, cp, 1); + if (fcntl(el->el_infd, F_SETFL, n)) + return(-1); +#else + /* not non-blocking, but what you gonna do? */ + num_read = read(el->el_infd, cp, 1); + return(-1); +#endif + + if (num_read < 0 && errno == EAGAIN) + continue; + if (num_read == 0) + continue; + break; + } + if (!rl_event_hook) + el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN); + return(num_read); +} + +static void +_rl_update_pos(void) +{ + const LineInfo *li = el_line(e); + + rl_point = li->cursor - li->buffer; + rl_end = li->lastchar - li->buffer; +} diff --git a/cmd-line-utils/libedit/refresh.c b/cmd-line-utils/libedit/refresh.c index e71bdba2b61..b2833d215c5 100644 --- a/cmd-line-utils/libedit/refresh.c +++ b/cmd-line-utils/libedit/refresh.c @@ -1,4 +1,4 @@ -/* $NetBSD: refresh.c,v 1.24 2003/03/10 21:18:49 christos Exp $ */ +/* $NetBSD: refresh.c,v 1.26 2003/08/07 16:44:33 agc Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,14 +32,7 @@ * SUCH DAMAGE. */ -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: refresh.c,v 1.24 2003/03/10 21:18:49 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ +#include <config.h> /* * refresh.c: Lower level screen refreshing functions @@ -57,8 +46,8 @@ __RCSID("$NetBSD: refresh.c,v 1.24 2003/03/10 21:18:49 christos Exp $"); private void re_addc(EditLine *, int); private void re_update_line(EditLine *, char *, char *, int); -private void re_insert (EditLine *el, char *, int, int, char *, int); -private void re_delete(EditLine *el, char *, int, int, int); +private void re_insert (EditLine *, char *, int, int, char *, int); +private void re_delete(EditLine *, char *, int, int, int); private void re_fastputc(EditLine *, int); private void re__strncopy(char *, char *, size_t); private void re__copy_and_pad(char *, const char *, size_t); @@ -338,8 +327,8 @@ re_goto_bottom(EditLine *el) */ private void /*ARGSUSED*/ -re_insert(EditLine *el __attribute__((unused)), - char *d, int dat, int dlen, char *s, int num) +re_insert(EditLine *el __attribute__((__unused__)), + char *d, int dat, int dlen, char *s, int num) { char *a, *b; @@ -382,8 +371,8 @@ re_insert(EditLine *el __attribute__((unused)), */ private void /*ARGSUSED*/ -re_delete(EditLine *el __attribute__((unused)), - char *d, int dat, int dlen, int num) +re_delete(EditLine *el __attribute__((__unused__)), + char *d, int dat, int dlen, int num) { char *a, *b; diff --git a/cmd-line-utils/libedit/refresh.h b/cmd-line-utils/libedit/refresh.h index 33c0887c1b3..dd2bd02094b 100644 --- a/cmd-line-utils/libedit/refresh.h +++ b/cmd-line-utils/libedit/refresh.h @@ -1,4 +1,4 @@ -/* $NetBSD: refresh.h,v 1.4 2001/01/10 07:45:42 jdolecek Exp $ */ +/* $NetBSD: refresh.h,v 1.5 2003/08/07 16:44:33 agc Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/cmd-line-utils/libedit/search.c b/cmd-line-utils/libedit/search.c index 0957529485c..848429e091b 100644 --- a/cmd-line-utils/libedit/search.c +++ b/cmd-line-utils/libedit/search.c @@ -1,4 +1,4 @@ -/* $NetBSD: search.c,v 1.14 2002/11/20 16:50:08 christos Exp $ */ +/* $NetBSD: search.c,v 1.20 2004/11/04 01:16:03 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,21 +32,13 @@ * SUCH DAMAGE. */ -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: search.c,v 1.14 2002/11/20 16:50:08 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ +#include <config.h> /* * search.c: History and character search functions */ #include <stdlib.h> #if defined(REGEX) -#include <sys/types.h> #include <regex.h> #elif defined(REGEXP) #include <regexp.h> @@ -227,8 +215,11 @@ ce_inc_search(EditLine *el, int dir) if (el->el_search.patlen == 0) { /* first round */ pchar = ':'; #ifdef ANCHOR +#define LEN 2 el->el_search.patbuf[el->el_search.patlen++] = '.'; el->el_search.patbuf[el->el_search.patlen++] = '*'; +#else +#define LEN 0 #endif } done = redo = 0; @@ -237,7 +228,7 @@ ce_inc_search(EditLine *el, int dir) *cp; *el->el_line.lastchar++ = *cp++) continue; *el->el_line.lastchar++ = pchar; - for (cp = &el->el_search.patbuf[1]; + for (cp = &el->el_search.patbuf[LEN]; cp < &el->el_search.patbuf[el->el_search.patlen]; *el->el_line.lastchar++ = *cp++) continue; @@ -250,7 +241,7 @@ ce_inc_search(EditLine *el, int dir) switch (el->el_map.current[(unsigned char) ch]) { case ED_INSERT: case ED_DIGIT: - if (el->el_search.patlen > EL_BUFSIZ - 3) + if (el->el_search.patlen >= EL_BUFSIZ - LEN) term_beep(el); else { el->el_search.patbuf[el->el_search.patlen++] = @@ -271,8 +262,9 @@ ce_inc_search(EditLine *el, int dir) redo++; break; + case EM_DELETE_PREV_CHAR: case ED_DELETE_PREV_CHAR: - if (el->el_search.patlen > 1) + if (el->el_search.patlen > LEN) done++; else term_beep(el); @@ -287,17 +279,18 @@ ce_inc_search(EditLine *el, int dir) case 0027: /* ^W: Append word */ /* No can do if globbing characters in pattern */ - for (cp = &el->el_search.patbuf[1];; cp++) - if (cp >= &el->el_search.patbuf[el->el_search.patlen]) { + for (cp = &el->el_search.patbuf[LEN];; cp++) + if (cp >= &el->el_search.patbuf[ + el->el_search.patlen]) { el->el_line.cursor += - el->el_search.patlen - 1; + el->el_search.patlen - LEN - 1; cp = c__next_word(el->el_line.cursor, el->el_line.lastchar, 1, ce__isword); while (el->el_line.cursor < cp && *el->el_line.cursor != '\n') { - if (el->el_search.patlen > - EL_BUFSIZ - 3) { + if (el->el_search.patlen >= + EL_BUFSIZ - LEN) { term_beep(el); break; } @@ -339,13 +332,13 @@ ce_inc_search(EditLine *el, int dir) /* Can't search if unmatched '[' */ for (cp = &el->el_search.patbuf[el->el_search.patlen-1], ch = ']'; - cp > el->el_search.patbuf; + cp >= &el->el_search.patbuf[LEN]; cp--) if (*cp == '[' || *cp == ']') { ch = *cp; break; } - if (el->el_search.patlen > 1 && ch != '[') { + if (el->el_search.patlen > LEN && ch != '[') { if (redo && newdir == dir) { if (pchar == '?') { /* wrap around */ el->el_history.eventno = @@ -375,9 +368,8 @@ ce_inc_search(EditLine *el, int dir) '\0'; if (el->el_line.cursor < el->el_line.buffer || el->el_line.cursor > el->el_line.lastchar || - (ret = ce_search_line(el, - &el->el_search.patbuf[1], - newdir)) == CC_ERROR) { + (ret = ce_search_line(el, newdir)) + == CC_ERROR) { /* avoid c_setpat */ el->el_state.lastcmd = (el_action_t) newdir; @@ -390,11 +382,11 @@ ce_inc_search(EditLine *el, int dir) el->el_line.lastchar : el->el_line.buffer; (void) ce_search_line(el, - &el->el_search.patbuf[1], newdir); } } - el->el_search.patbuf[--el->el_search.patlen] = + el->el_search.patlen -= LEN; + el->el_search.patbuf[el->el_search.patlen] = '\0'; if (ret == CC_ERROR) { term_beep(el); @@ -453,9 +445,6 @@ cv_search(EditLine *el, int dir) #ifdef ANCHOR tmpbuf[0] = '.'; tmpbuf[1] = '*'; -#define LEN 2 -#else -#define LEN 0 #endif tmplen = LEN; @@ -521,24 +510,39 @@ cv_search(EditLine *el, int dir) * Look for a pattern inside a line */ protected el_action_t -ce_search_line(EditLine *el, char *pattern, int dir) +ce_search_line(EditLine *el, int dir) { - char *cp; + char *cp = el->el_line.cursor; + char *pattern = el->el_search.patbuf; + char oc, *ocp; +#ifdef ANCHOR + ocp = &pattern[1]; + oc = *ocp; + *ocp = '^'; +#else + ocp = pattern; + oc = *ocp; +#endif if (dir == ED_SEARCH_PREV_HISTORY) { - for (cp = el->el_line.cursor; cp >= el->el_line.buffer; cp--) - if (el_match(cp, pattern)) { + for (; cp >= el->el_line.buffer; cp--) { + if (el_match(cp, ocp)) { + *ocp = oc; el->el_line.cursor = cp; return (CC_NORM); } + } + *ocp = oc; return (CC_ERROR); } else { - for (cp = el->el_line.cursor; *cp != '\0' && - cp < el->el_line.limit; cp++) - if (el_match(cp, pattern)) { + for (; *cp != '\0' && cp < el->el_line.limit; cp++) { + if (el_match(cp, ocp)) { + *ocp = oc; el->el_line.cursor = cp; return (CC_NORM); } + } + *ocp = oc; return (CC_ERROR); } } diff --git a/cmd-line-utils/libedit/search.h b/cmd-line-utils/libedit/search.h index a7363072a4c..2aa8f985013 100644 --- a/cmd-line-utils/libedit/search.h +++ b/cmd-line-utils/libedit/search.h @@ -1,4 +1,4 @@ -/* $NetBSD: search.h,v 1.6 2002/11/15 14:32:34 christos Exp $ */ +/* $NetBSD: search.h,v 1.8 2003/10/18 23:27:36 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -63,7 +59,7 @@ protected int c_hmatch(EditLine *, const char *); protected void c_setpat(EditLine *); protected el_action_t ce_inc_search(EditLine *, int); protected el_action_t cv_search(EditLine *, int); -protected el_action_t ce_search_line(EditLine *, char *, int); +protected el_action_t ce_search_line(EditLine *, int); protected el_action_t cv_repeat_srch(EditLine *, int); protected el_action_t cv_csearch(EditLine *, int, int, int, int); diff --git a/cmd-line-utils/libedit/sig.c b/cmd-line-utils/libedit/sig.c index 3730067ed5f..8e70933d606 100644 --- a/cmd-line-utils/libedit/sig.c +++ b/cmd-line-utils/libedit/sig.c @@ -1,4 +1,4 @@ -/* $NetBSD: sig.c,v 1.10 2003/03/10 00:58:05 christos Exp $ */ +/* $NetBSD: sig.c,v 1.11 2003/08/07 16:44:33 agc Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,14 +32,7 @@ * SUCH DAMAGE. */ -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: sig.c,v 1.10 2003/03/10 00:58:05 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ +#include <config.h> /* * sig.c: Signal handling stuff. diff --git a/cmd-line-utils/libedit/sig.h b/cmd-line-utils/libedit/sig.h index 8effea8e121..0bf1fc37e39 100644 --- a/cmd-line-utils/libedit/sig.h +++ b/cmd-line-utils/libedit/sig.h @@ -1,4 +1,4 @@ -/* $NetBSD: sig.h,v 1.4 2003/03/10 00:58:05 christos Exp $ */ +/* $NetBSD: sig.h,v 1.5 2003/08/07 16:44:33 agc Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/cmd-line-utils/libedit/strlcpy.c b/cmd-line-utils/libedit/strlcpy.c index 74317d99cd2..e38d6cf1c4b 100644 --- a/cmd-line-utils/libedit/strlcpy.c +++ b/cmd-line-utils/libedit/strlcpy.c @@ -1,28 +1,73 @@ +/* $NetBSD: strlcpy.c,v 1.14 2003/10/27 00:12:42 lukem Exp $ */ +/* $OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE + * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <config.h> + +#include <sys/types.h> +#include <assert.h> #include <string.h> -#ifndef HAVE_STRLCPY -size_t strlcpy(char *dst, const char *src, size_t size) +#ifdef _LIBC +# ifdef __weak_alias +__weak_alias(strlcpy, _strlcpy) +# endif +#endif + +#if !HAVE_STRLCPY +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t +#ifdef _LIBC +_strlcpy(dst, src, siz) +#else +strlcpy(dst, src, siz) +#endif + char *dst; + const char *src; + size_t siz; { - if(size) { - strncpy(dst, src, size-1); - dst[size-1] = '\0'; - } else { - dst[0] = '\0'; + char *d = dst; + const char *s = src; + size_t n = siz; + + _DIAGASSERT(dst != NULL); + _DIAGASSERT(src != NULL); + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); } - return strlen(src); -} -size_t strlcat(char *dst, const char *src, size_t size) -{ - int dl = strlen(dst); - int sz = size-dl-1; - - if(sz >= 0) { - strncat(dst, src, sz); - dst[sz] = '\0'; + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; } - return dl+strlen(src); + return(s - src - 1); /* count does not include NUL */ } - #endif diff --git a/cmd-line-utils/libedit/sys.h b/cmd-line-utils/libedit/sys.h index a7477d2c5ba..c8a29dbfb05 100644 --- a/cmd-line-utils/libedit/sys.h +++ b/cmd-line-utils/libedit/sys.h @@ -1,4 +1,4 @@ -/* $NetBSD: sys.h,v 1.6 2003/03/10 00:57:38 christos Exp $ */ +/* $NetBSD: sys.h,v 1.9 2004/01/17 17:57:40 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -48,6 +44,28 @@ #include <sys/cdefs.h> #endif +#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8) +# define __attribute__(A) +#endif + +#ifndef __P +# define __P(x) x +#endif + +#ifndef _DIAGASSERT +# define _DIAGASSERT(x) +#endif + +#ifndef __BEGIN_DECLS +# ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +# else +# define __BEGIN_DECLS +# define __END_DECLS +# endif +#endif + #ifndef public # define public /* Externally visible functions/variables */ #endif @@ -61,6 +79,10 @@ /* When we want to hide everything */ #endif +#ifndef HAVE_U_INT32_T +typedef unsigned int u_int32_t; +#endif + #ifndef _PTR_T # define _PTR_T typedef void *ptr_t; diff --git a/cmd-line-utils/libedit/term.c b/cmd-line-utils/libedit/term.c index c4ee0d30aab..b516d6753c3 100644 --- a/cmd-line-utils/libedit/term.c +++ b/cmd-line-utils/libedit/term.c @@ -1,4 +1,4 @@ -/* $NetBSD: term.c,v 1.35 2002/03/18 16:00:59 christos Exp $ */ +/* $NetBSD: term.c,v 1.40 2004/05/22 23:21:28 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,14 +32,7 @@ * SUCH DAMAGE. */ -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95"; -#else -__RCSID("$NetBSD: term.c,v 1.35 2002/03/18 16:00:59 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ +#include <config.h> /* * term.c: Editor/termcap-curses interface @@ -55,24 +44,23 @@ __RCSID("$NetBSD: term.c,v 1.35 2002/03/18 16:00:59 christos Exp $"); #include <string.h> #include <stdlib.h> #include <unistd.h> -#ifdef HAVE_TERMCAP_H -#include <termcap.h> -#endif + #ifdef HAVE_CURSES_H -#include <curses.h> -#endif -#ifdef HAVE_NCURSES_H -#include <ncurses.h> +# include <curses.h> +#elif HAVE_NCURSES_H +# include <ncurses.h> #endif -#include "el.h" - -#if !defined(HAVE_TERMCAP_H) && defined(HAVE_TERM_H) -#include <term.h> +/* Solaris's term.h does horrid things. */ +#if (defined(HAVE_TERM_H) && !defined(_SUNOS)) +# include <term.h> #endif + #include <sys/types.h> #include <sys/ioctl.h> +#include "el.h" + /* * IMPORTANT NOTE: these routines are allowed to look at the current screen * and the current possition assuming that it is correct. If this is not @@ -356,6 +344,7 @@ term_init(EditLine *el) term_init_arrow(el); return (0); } + /* term_end(): * Clean up the terminal stuff */ @@ -372,6 +361,8 @@ term_end(EditLine *el) el->el_term.t_str = NULL; el_free((ptr_t) el->el_term.t_val); el->el_term.t_val = NULL; + el_free((ptr_t) el->el_term.t_fkey); + el->el_term.t_fkey = NULL; term_free_display(el); } @@ -648,7 +639,8 @@ mc_again: * from col 0 */ if (EL_CAN_TAB ? - (((unsigned int)-del) > (((unsigned int) where >> 3) + + ((unsigned int)-del > + (((unsigned int) where >> 3) + (where & 07))) : (-del > where)) { term__putc('\r'); /* do a CR */ @@ -876,6 +868,12 @@ term_clear_to_bottom(EditLine *el) } #endif +protected void +term_get(EditLine *el, const char **term) +{ + *term = el->el_term.t_name; +} + /* term_set(): * Read in the terminal capabilities from the requested terminal @@ -937,8 +935,11 @@ term_set(EditLine *el, const char *term) /* Get the size */ Val(T_co) = tgetnum("co"); Val(T_li) = tgetnum("li"); - for (t = tstr; t->name != NULL; t++) - term_alloc(el, t, tgetstr(t->name, &area)); + for (t = tstr; t->name != NULL; t++) { + /* XXX: some systems tgetstr needs non const */ + term_alloc(el, t, tgetstr(strchr(t->name, *t->name), + &area)); + } } if (Val(T_co) < 2) @@ -957,6 +958,7 @@ term_set(EditLine *el, const char *term) return (-1); (void) sigprocmask(SIG_SETMASK, &oset, NULL); term_bind_arrow(el); + el->el_term.t_name = term; return (i <= 0 ? -1 : 0); } @@ -1078,32 +1080,32 @@ term_reset_arrow(EditLine *el) static const char stOH[] = {033, 'O', 'H', '\0'}; static const char stOF[] = {033, 'O', 'F', '\0'}; - el_key_add(el, strA, &arrow[A_K_UP].fun, arrow[A_K_UP].type); - el_key_add(el, strB, &arrow[A_K_DN].fun, arrow[A_K_DN].type); - el_key_add(el, strC, &arrow[A_K_RT].fun, arrow[A_K_RT].type); - el_key_add(el, strD, &arrow[A_K_LT].fun, arrow[A_K_LT].type); - el_key_add(el, strH, &arrow[A_K_HO].fun, arrow[A_K_HO].type); - el_key_add(el, strF, &arrow[A_K_EN].fun, arrow[A_K_EN].type); - el_key_add(el, stOA, &arrow[A_K_UP].fun, arrow[A_K_UP].type); - el_key_add(el, stOB, &arrow[A_K_DN].fun, arrow[A_K_DN].type); - el_key_add(el, stOC, &arrow[A_K_RT].fun, arrow[A_K_RT].type); - el_key_add(el, stOD, &arrow[A_K_LT].fun, arrow[A_K_LT].type); - el_key_add(el, stOH, &arrow[A_K_HO].fun, arrow[A_K_HO].type); - el_key_add(el, stOF, &arrow[A_K_EN].fun, arrow[A_K_EN].type); + key_add(el, strA, &arrow[A_K_UP].fun, arrow[A_K_UP].type); + key_add(el, strB, &arrow[A_K_DN].fun, arrow[A_K_DN].type); + key_add(el, strC, &arrow[A_K_RT].fun, arrow[A_K_RT].type); + key_add(el, strD, &arrow[A_K_LT].fun, arrow[A_K_LT].type); + key_add(el, strH, &arrow[A_K_HO].fun, arrow[A_K_HO].type); + key_add(el, strF, &arrow[A_K_EN].fun, arrow[A_K_EN].type); + key_add(el, stOA, &arrow[A_K_UP].fun, arrow[A_K_UP].type); + key_add(el, stOB, &arrow[A_K_DN].fun, arrow[A_K_DN].type); + key_add(el, stOC, &arrow[A_K_RT].fun, arrow[A_K_RT].type); + key_add(el, stOD, &arrow[A_K_LT].fun, arrow[A_K_LT].type); + key_add(el, stOH, &arrow[A_K_HO].fun, arrow[A_K_HO].type); + key_add(el, stOF, &arrow[A_K_EN].fun, arrow[A_K_EN].type); if (el->el_map.type == MAP_VI) { - el_key_add(el, &strA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type); - el_key_add(el, &strB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type); - el_key_add(el, &strC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type); - el_key_add(el, &strD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type); - el_key_add(el, &strH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type); - el_key_add(el, &strF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type); - el_key_add(el, &stOA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type); - el_key_add(el, &stOB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type); - el_key_add(el, &stOC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type); - el_key_add(el, &stOD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type); - el_key_add(el, &stOH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type); - el_key_add(el, &stOF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type); + key_add(el, &strA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type); + key_add(el, &strB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type); + key_add(el, &strC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type); + key_add(el, &strD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type); + key_add(el, &strH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type); + key_add(el, &strF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type); + key_add(el, &stOA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type); + key_add(el, &stOB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type); + key_add(el, &stOC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type); + key_add(el, &stOD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type); + key_add(el, &stOH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type); + key_add(el, &stOF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type); } } @@ -1157,7 +1159,7 @@ term_print_arrow(EditLine *el, const char *name) for (i = 0; i < A_K_NKEYS; i++) if (*name == '\0' || strcmp(name, arrow[i].name) == 0) if (arrow[i].type != XK_NOD) - el_key_kprint(el, arrow[i].name, &arrow[i].fun, + key_kprint(el, arrow[i].name, &arrow[i].fun, arrow[i].type); } @@ -1198,20 +1200,20 @@ term_bind_arrow(EditLine *el) * unassigned key. */ if (arrow[i].type == XK_NOD) - el_key_clear(el, map, p); + key_clear(el, map, p); else { if (p[1] && (dmap[j] == map[j] || map[j] == ED_SEQUENCE_LEAD_IN)) { - el_key_add(el, p, &arrow[i].fun, + key_add(el, p, &arrow[i].fun, arrow[i].type); map[j] = ED_SEQUENCE_LEAD_IN; } else if (map[j] == ED_UNASSIGNED) { - el_key_clear(el, map, p); + key_clear(el, map, p); if (arrow[i].type == XK_CMD) map[j] = arrow[i].fun.cmd; else - el_key_add(el, p, &arrow[i].fun, - arrow[i].type); + key_add(el, p, &arrow[i].fun, + arrow[i].type); } } } @@ -1244,12 +1246,10 @@ term__flush(void) /* term_telltc(): * Print the current termcap characteristics */ -char *el_key__decode_str(const char *, char *, const char *); - protected int /*ARGSUSED*/ -term_telltc(EditLine *el, int argc __attribute__((unused)), - const char **argv __attribute__((unused))) +term_telltc(EditLine *el, int argc __attribute__((__unused__)), + const char **argv __attribute__((__unused__))) { const struct termcapstr *t; char **ts; @@ -1273,7 +1273,7 @@ term_telltc(EditLine *el, int argc __attribute__((unused)), (void) fprintf(el->el_outfile, "\t%25s (%s) == %s\n", t->long_name, t->name, *ts && **ts ? - el_key__decode_str(*ts, upbuf, "") : "(empty)"); + key__decode_str(*ts, upbuf, "") : "(empty)"); (void) fputc('\n', el->el_outfile); return (0); } @@ -1284,8 +1284,8 @@ term_telltc(EditLine *el, int argc __attribute__((unused)), */ protected int /*ARGSUSED*/ -term_settc(EditLine *el, int argc __attribute__((unused)), - const char **argv __attribute__((unused))) +term_settc(EditLine *el, int argc __attribute__((__unused__)), + const char **argv) { const struct termcapstr *ts; const struct termcapval *tv; @@ -1361,9 +1361,8 @@ term_settc(EditLine *el, int argc __attribute__((unused)), */ protected int /*ARGSUSED*/ -term_echotc(EditLine *el __attribute__((unused)), - int argc __attribute__((unused)), - const char **argv __attribute__((unused))) +term_echotc(EditLine *el, int argc __attribute__((__unused__)), + const char **argv) { char *cap, *scap, *ep; int arg_need, arg_cols, arg_rows; @@ -1422,7 +1421,7 @@ term_echotc(EditLine *el __attribute__((unused)), } (void) fprintf(el->el_outfile, fmtd, 0); #else - (void) fprintf(el->el_outfile, fmtd, el->el_tty.t_speed); + (void) fprintf(el->el_outfile, fmtd, (int)el->el_tty.t_speed); #endif return (0); } else if (strcmp(*argv, "rows") == 0 || strcmp(*argv, "lines") == 0) { @@ -1441,8 +1440,10 @@ term_echotc(EditLine *el __attribute__((unused)), scap = el->el_term.t_str[t - tstr]; break; } - if (t->name == NULL) - scap = tgetstr(*argv, &area); + if (t->name == NULL) { + /* XXX: some systems tgetstr needs non const */ + scap = tgetstr(strchr(*argv, **argv), &area); + } if (!scap || scap[0] == '\0') { if (!silent) (void) fprintf(el->el_errfile, diff --git a/cmd-line-utils/libedit/tokenizer.c b/cmd-line-utils/libedit/tokenizer.c index f6892d9954c..561b41740f8 100644 --- a/cmd-line-utils/libedit/tokenizer.c +++ b/cmd-line-utils/libedit/tokenizer.c @@ -1,4 +1,4 @@ -/* $NetBSD: tokenizer.c,v 1.11 2002/10/27 20:24:29 christos Exp $ */ +/* $NetBSD: tokenizer.c,v 1.14 2003/12/05 13:37:48 lukem Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,21 +32,14 @@ * SUCH DAMAGE. */ -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: tokenizer.c,v 1.11 2002/10/27 20:24:29 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ +#include <config.h> /* * tokenize.c: Bourne shell like tokenizer */ #include <string.h> #include <stdlib.h> -#include "tokenizer.h" +#include "histedit.h" typedef enum { Q_none, Q_single, Q_double, Q_one, Q_doubleone @@ -64,6 +53,7 @@ typedef enum { #define WINCR 20 #define AINCR 10 +#define tok_strdup(a) strdup(a) #define tok_malloc(a) malloc(a) #define tok_free(a) free(a) #define tok_realloc(a, b) realloc(a, b) @@ -111,7 +101,7 @@ tok_init(const char *ifs) if (tok == NULL) return NULL; - tok->ifs = strdup(ifs ? ifs : IFS); + tok->ifs = tok_strdup(ifs ? ifs : IFS); if (tok->ifs == NULL) { tok_free((ptr_t)tok); return NULL; @@ -173,21 +163,39 @@ tok_end(Tokenizer *tok) /* tok_line(): - * Bourne shell like tokenizing - * Return: - * -1: Internal error - * 3: Quoted return - * 2: Unmatched double quote - * 1: Unmatched single quote - * 0: Ok + * Bourne shell (sh(1)) like tokenizing + * Arguments: + * tok current tokenizer state (setup with tok_init()) + * line line to parse + * Returns: + * -1 Internal error + * 3 Quoted return + * 2 Unmatched double quote + * 1 Unmatched single quote + * 0 Ok + * Modifies (if return value is 0): + * argc number of arguments + * argv argument array + * cursorc if !NULL, argv element containing cursor + * cursorv if !NULL, offset in argv[cursorc] of cursor */ public int -tok_line(Tokenizer *tok, const char *line, int *argc, const char ***argv) +tok_line(Tokenizer *tok, const LineInfo *line, + int *argc, const char ***argv, int *cursorc, int *cursoro) { const char *ptr; - - for (;;) { - switch (*(ptr = line++)) { + int cc, co; + + cc = co = -1; + ptr = line->buffer; + for (ptr = line->buffer; ;ptr++) { + if (ptr >= line->lastchar) + ptr = ""; + if (ptr == line->cursor) { + cc = tok->argc; + co = tok->wptr - tok->wstart; + } + switch (*ptr) { case '\'': tok->flags |= TOK_KEEP; tok->flags &= ~TOK_EAT; @@ -286,10 +294,7 @@ tok_line(Tokenizer *tok, const char *line, int *argc, const char ***argv) tok->flags &= ~TOK_EAT; switch (tok->quote) { case Q_none: - tok_finish(tok); - *argv = (const char **)tok->argv; - *argc = tok->argc; - return (0); + goto tok_line_outok; case Q_single: case Q_double: @@ -319,10 +324,7 @@ tok_line(Tokenizer *tok, const char *line, int *argc, const char ***argv) tok->flags &= ~TOK_EAT; return (3); } - tok_finish(tok); - *argv = (const char **)tok->argv; - *argc = tok->argc; - return (0); + goto tok_line_outok; case Q_single: return (1); @@ -407,4 +409,32 @@ tok_line(Tokenizer *tok, const char *line, int *argc, const char ***argv) tok->argv = p; } } + tok_line_outok: + if (cc == -1 && co == -1) { + cc = tok->argc; + co = tok->wptr - tok->wstart; + } + if (cursorc != NULL) + *cursorc = cc; + if (cursoro != NULL) + *cursoro = co; + tok_finish(tok); + *argv = (const char **)tok->argv; + *argc = tok->argc; + return (0); +} + +/* tok_str(): + * Simpler version of tok_line, taking a NUL terminated line + * and splitting into words, ignoring cursor state. + */ +public int +tok_str(Tokenizer *tok, const char *line, int *argc, const char ***argv) +{ + LineInfo li; + + memset(&li, 0, sizeof(li)); + li.buffer = line; + li.cursor = li.lastchar = strchr(line, '\0'); + return (tok_line(tok, &li, argc, argv, NULL, NULL)); } diff --git a/cmd-line-utils/libedit/tty.c b/cmd-line-utils/libedit/tty.c index fe81762fb82..6f73fb4f9e7 100644 --- a/cmd-line-utils/libedit/tty.c +++ b/cmd-line-utils/libedit/tty.c @@ -1,4 +1,4 @@ -/* $NetBSD: tty.c,v 1.16 2002/03/18 16:01:01 christos Exp $ */ +/* $NetBSD: tty.c,v 1.21 2004/08/13 12:10:39 mycroft Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,18 +32,12 @@ * SUCH DAMAGE. */ -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: tty.c,v 1.16 2002/03/18 16:01:01 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ +#include <config.h> /* * tty.c: tty interface stuff */ +#include <assert.h> #include "tty.h" #include "el.h" @@ -124,11 +114,11 @@ private const ttychar_t ttychar = { private const ttymap_t tty_map[] = { #ifdef VERASE {C_ERASE, VERASE, - {ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}}, + {EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}}, #endif /* VERASE */ #ifdef VERASE2 {C_ERASE2, VERASE2, - {ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}}, + {EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}}, #endif /* VERASE2 */ #ifdef VKILL {C_KILL, VKILL, @@ -455,6 +445,7 @@ private const ttymodes_t ttymodes[] = { #define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8) #define tty__cooked_mode(td) ((td)->c_lflag & ICANON) +private int tty__getcharindex(int); private void tty__getchar(struct termios *, unsigned char *); private void tty__setchar(struct termios *, unsigned char *); private speed_t tty__getspeed(struct termios *); @@ -568,7 +559,7 @@ tty_init(EditLine *el) */ protected void /*ARGSUSED*/ -tty_end(EditLine *el __attribute__((unused))) +tty_end(EditLine *el __attribute__((__unused__))) { /* XXX: Maybe reset to an initial state? */ @@ -588,6 +579,113 @@ tty__getspeed(struct termios *td) return (spd); } +/* tty__getspeed(): + * Return the index of the asked char in the c_cc array + */ +private int +tty__getcharindex(int i) +{ + switch (i) { +#ifdef VINTR + case C_INTR: + return VINTR; +#endif /* VINTR */ +#ifdef VQUIT + case C_QUIT: + return VQUIT; +#endif /* VQUIT */ +#ifdef VERASE + case C_ERASE: + return VERASE; +#endif /* VERASE */ +#ifdef VKILL + case C_KILL: + return VKILL; +#endif /* VKILL */ +#ifdef VEOF + case C_EOF: + return VEOF; +#endif /* VEOF */ +#ifdef VEOL + case C_EOL: + return VEOL; +#endif /* VEOL */ +#ifdef VEOL2 + case C_EOL2: + return VEOL2; +#endif /* VEOL2 */ +#ifdef VSWTCH + case C_SWTCH: + return VSWTCH; +#endif /* VSWTCH */ +#ifdef VDSWTCH + case C_DSWTCH: + return VDSWTCH; +#endif /* VDSWTCH */ +#ifdef VERASE2 + case C_ERASE2: + return VERASE2; +#endif /* VERASE2 */ +#ifdef VSTART + case C_START: + return VSTART; +#endif /* VSTART */ +#ifdef VSTOP + case C_STOP: + return VSTOP; +#endif /* VSTOP */ +#ifdef VWERASE + case C_WERASE: + return VWERASE; +#endif /* VWERASE */ +#ifdef VSUSP + case C_SUSP: + return VSUSP; +#endif /* VSUSP */ +#ifdef VDSUSP + case C_DSUSP: + return VDSUSP; +#endif /* VDSUSP */ +#ifdef VREPRINT + case C_REPRINT: + return VREPRINT; +#endif /* VREPRINT */ +#ifdef VDISCARD + case C_DISCARD: + return VDISCARD; +#endif /* VDISCARD */ +#ifdef VLNEXT + case C_LNEXT: + return VLNEXT; +#endif /* VLNEXT */ +#ifdef VSTATUS + case C_STATUS: + return VSTATUS; +#endif /* VSTATUS */ +#ifdef VPAGE + case C_PAGE: + return VPAGE; +#endif /* VPAGE */ +#ifdef VPGOFF + case C_PGOFF: + return VPGOFF; +#endif /* VPGOFF */ +#ifdef VKILL2 + case C_KILL2: + return VKILL2; +#endif /* KILL2 */ +#ifdef VMIN + case C_MIN: + return VMIN; +#endif /* VMIN */ +#ifdef VTIME + case C_TIME: + return VTIME; +#endif /* VTIME */ + default: + return -1; + } +} /* tty__getchar(): * Get the tty characters @@ -784,15 +882,15 @@ tty_bind_char(EditLine *el, int force) if (new[0] == old[0] && !force) continue; /* Put the old default binding back, and set the new binding */ - el_key_clear(el, map, (char *)old); + key_clear(el, map, (char *)old); map[old[0]] = dmap[old[0]]; - el_key_clear(el, map, (char *)new); + key_clear(el, map, (char *)new); /* MAP_VI == 1, MAP_EMACS == 0... */ map[new[0]] = tp->bind[el->el_map.type]; if (dalt) { - el_key_clear(el, alt, (char *)old); + key_clear(el, alt, (char *)old); alt[old[0]] = dalt[old[0]]; - el_key_clear(el, alt, (char *)new); + key_clear(el, alt, (char *)new); alt[new[0]] = tp->bind[el->el_map.type + 1]; } } @@ -1041,13 +1139,14 @@ tty_noquotemode(EditLine *el) */ protected int /*ARGSUSED*/ -tty_stty(EditLine *el, int argc __attribute__((unused)), const char **argv) +tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv) { const ttymodes_t *m; char x; int aflag = 0; const char *s, *d; const char *name; + struct termios *tios = &el->el_tty.t_ex; int z = EX_IO; if (argv == NULL) @@ -1062,14 +1161,17 @@ tty_stty(EditLine *el, int argc __attribute__((unused)), const char **argv) break; case 'd': argv++; + tios = &el->el_tty.t_ed; z = ED_IO; break; case 'x': argv++; + tios = &el->el_tty.t_ex; z = EX_IO; break; case 'q': argv++; + tios = &el->el_tty.t_ts; z = QU_IO; break; default: @@ -1119,6 +1221,7 @@ tty_stty(EditLine *el, int argc __attribute__((unused)), const char **argv) return (0); } while (argv && (s = *argv++)) { + char *p; switch (*s) { case '+': case '-': @@ -1129,8 +1232,11 @@ tty_stty(EditLine *el, int argc __attribute__((unused)), const char **argv) break; } d = s; + if ((p = strchr(s, '=')) != NULL) + *p++ = '\0'; for (m = ttymodes; m->m_name; m++) - if (strcmp(m->m_name, d) == 0) + if (strcmp(m->m_name, d) == 0 && + (p == NULL || m->m_type == MD_CHAR)) break; if (!m->m_name) { @@ -1138,6 +1244,16 @@ tty_stty(EditLine *el, int argc __attribute__((unused)), const char **argv) "%s: Invalid argument `%s'.\n", name, d); return (-1); } + if (p) { + int c = ffs((int)m->m_value); + int v = *p ? parse__escape((const char **const) &p) : + el->el_tty.t_vdisable; + assert(c-- != 0); + c = tty__getcharindex(c); + assert(c != -1); + tios->c_cc[c] = v; + continue; + } switch (x) { case '+': el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value; diff --git a/cmd-line-utils/libedit/tty.h b/cmd-line-utils/libedit/tty.h index e9597fceb2b..cc7c4ad8c66 100644 --- a/cmd-line-utils/libedit/tty.h +++ b/cmd-line-utils/libedit/tty.h @@ -1,4 +1,4 @@ -/* $NetBSD: tty.h,v 1.9 2002/03/18 16:01:01 christos Exp $ */ +/* $NetBSD: tty.h,v 1.10 2003/08/07 16:44:34 agc Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/cmd-line-utils/libedit/unvis.c b/cmd-line-utils/libedit/unvis.c new file mode 100644 index 00000000000..ffa8ac4251c --- /dev/null +++ b/cmd-line-utils/libedit/unvis.c @@ -0,0 +1,311 @@ +/* $NetBSD: unvis.c,v 1.24 2003/08/07 16:42:59 agc Exp $ */ + +/*- + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <config.h> + +#define __LIBC12_SOURCE__ + +#include <sys/types.h> + +#include <assert.h> +#include <ctype.h> +#include <stdio.h> +#include <vis.h> + +#ifdef __weak_alias +__weak_alias(strunvis,_strunvis) +__weak_alias(unvis,_unvis) +#endif + +#ifdef __warn_references +__warn_references(unvis, + "warning: reference to compatibility unvis(); include <vis.h> for correct reference") +#endif + +#if !HAVE_VIS +/* + * decode driven by state machine + */ +#define S_GROUND 0 /* haven't seen escape char */ +#define S_START 1 /* start decoding special sequence */ +#define S_META 2 /* metachar started (M) */ +#define S_META1 3 /* metachar more, regular char (-) */ +#define S_CTRL 4 /* control char started (^) */ +#define S_OCTAL2 5 /* octal digit 2 */ +#define S_OCTAL3 6 /* octal digit 3 */ +#define S_HEX1 7 /* hex digit */ +#define S_HEX2 8 /* hex digit 2 */ + +#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') +#define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10)) + +int +unvis(cp, c, astate, flag) + char *cp; + int c; + int *astate, flag; +{ + return __unvis13(cp, (int)c, astate, flag); +} + +/* + * unvis - decode characters previously encoded by vis + */ +int +__unvis13(cp, c, astate, flag) + char *cp; + int c; + int *astate, flag; +{ + + _DIAGASSERT(cp != NULL); + _DIAGASSERT(astate != NULL); + + if (flag & UNVIS_END) { + if (*astate == S_OCTAL2 || *astate == S_OCTAL3 + || *astate == S_HEX2) { + *astate = S_GROUND; + return (UNVIS_VALID); + } + return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD); + } + + switch (*astate) { + + case S_GROUND: + *cp = 0; + if (c == '\\') { + *astate = S_START; + return (0); + } + if ((flag & VIS_HTTPSTYLE) && c == '%') { + *astate = S_HEX1; + return (0); + } + *cp = c; + return (UNVIS_VALID); + + case S_START: + switch(c) { + case '\\': + *cp = c; + *astate = S_GROUND; + return (UNVIS_VALID); + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + *cp = (c - '0'); + *astate = S_OCTAL2; + return (0); + case 'M': + *cp = (char)0200; + *astate = S_META; + return (0); + case '^': + *astate = S_CTRL; + return (0); + case 'n': + *cp = '\n'; + *astate = S_GROUND; + return (UNVIS_VALID); + case 'r': + *cp = '\r'; + *astate = S_GROUND; + return (UNVIS_VALID); + case 'b': + *cp = '\b'; + *astate = S_GROUND; + return (UNVIS_VALID); + case 'a': + *cp = '\007'; + *astate = S_GROUND; + return (UNVIS_VALID); + case 'v': + *cp = '\v'; + *astate = S_GROUND; + return (UNVIS_VALID); + case 't': + *cp = '\t'; + *astate = S_GROUND; + return (UNVIS_VALID); + case 'f': + *cp = '\f'; + *astate = S_GROUND; + return (UNVIS_VALID); + case 's': + *cp = ' '; + *astate = S_GROUND; + return (UNVIS_VALID); + case 'E': + *cp = '\033'; + *astate = S_GROUND; + return (UNVIS_VALID); + case '\n': + /* + * hidden newline + */ + *astate = S_GROUND; + return (UNVIS_NOCHAR); + case '$': + /* + * hidden marker + */ + *astate = S_GROUND; + return (UNVIS_NOCHAR); + } + *astate = S_GROUND; + return (UNVIS_SYNBAD); + + case S_META: + if (c == '-') + *astate = S_META1; + else if (c == '^') + *astate = S_CTRL; + else { + *astate = S_GROUND; + return (UNVIS_SYNBAD); + } + return (0); + + case S_META1: + *astate = S_GROUND; + *cp |= c; + return (UNVIS_VALID); + + case S_CTRL: + if (c == '?') + *cp |= 0177; + else + *cp |= c & 037; + *astate = S_GROUND; + return (UNVIS_VALID); + + case S_OCTAL2: /* second possible octal digit */ + if (isoctal(c)) { + /* + * yes - and maybe a third + */ + *cp = (*cp << 3) + (c - '0'); + *astate = S_OCTAL3; + return (0); + } + /* + * no - done with current sequence, push back passed char + */ + *astate = S_GROUND; + return (UNVIS_VALIDPUSH); + + case S_OCTAL3: /* third possible octal digit */ + *astate = S_GROUND; + if (isoctal(c)) { + *cp = (*cp << 3) + (c - '0'); + return (UNVIS_VALID); + } + /* + * we were done, push back passed char + */ + return (UNVIS_VALIDPUSH); + case S_HEX1: + if (isxdigit(c)) { + *cp = xtod(c); + *astate = S_HEX2; + return (0); + } + /* + * no - done with current sequence, push back passed char + */ + *astate = S_GROUND; + return (UNVIS_VALIDPUSH); + case S_HEX2: + *astate = S_GROUND; + if (isxdigit(c)) { + *cp = xtod(c) | (*cp << 4); + return (UNVIS_VALID); + } + return (UNVIS_VALIDPUSH); + default: + /* + * decoder in unknown state - (probably uninitialized) + */ + *astate = S_GROUND; + return (UNVIS_SYNBAD); + } +} + +/* + * strunvis - decode src into dst + * + * Number of chars decoded into dst is returned, -1 on error. + * Dst is null terminated. + */ + +int +strunvisx(dst, src, flag) + char *dst; + const char *src; + int flag; +{ + char c; + char *start = dst; + int state = 0; + + _DIAGASSERT(src != NULL); + _DIAGASSERT(dst != NULL); + + while ((c = *src++) != '\0') { + again: + switch (__unvis13(dst, c, &state, flag)) { + case UNVIS_VALID: + dst++; + break; + case UNVIS_VALIDPUSH: + dst++; + goto again; + case 0: + case UNVIS_NOCHAR: + break; + default: + return (-1); + } + } + if (__unvis13(dst, c, &state, UNVIS_END) == UNVIS_VALID) + dst++; + *dst = '\0'; + return (dst - start); +} + +int +strunvis(dst, src) + char *dst; + const char *src; +{ + return strunvisx(dst, src, 0); +} +#endif diff --git a/cmd-line-utils/libedit/vi.c b/cmd-line-utils/libedit/vi.c index 5380872cf65..4a0352859dd 100644 --- a/cmd-line-utils/libedit/vi.c +++ b/cmd-line-utils/libedit/vi.c @@ -1,4 +1,4 @@ -/* $NetBSD: vi.c,v 1.16 2003/03/10 11:09:25 dsl Exp $ */ +/* $NetBSD: vi.c,v 1.20 2004/08/13 12:10:39 mycroft Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,18 +32,11 @@ * SUCH DAMAGE. */ -#include "config.h" +#include <config.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: vi.c,v 1.16 2003/03/10 11:09:25 dsl Exp $"); -#endif -#endif /* not lint && not SCCSID */ /* * vi.c: Vi mode commands. @@ -123,7 +112,7 @@ cv_paste(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_paste_next(EditLine *el, int c __attribute__((unused))) +vi_paste_next(EditLine *el, int c __attribute__((__unused__))) { return (cv_paste(el, 0)); @@ -136,7 +125,7 @@ vi_paste_next(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_paste_prev(EditLine *el, int c __attribute__((unused))) +vi_paste_prev(EditLine *el, int c __attribute__((__unused__))) { return (cv_paste(el, 1)); @@ -149,7 +138,7 @@ vi_paste_prev(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_prev_big_word(EditLine *el, int c __attribute__((unused))) +vi_prev_big_word(EditLine *el, int c) { if (el->el_line.cursor == el->el_line.buffer) @@ -174,7 +163,7 @@ vi_prev_big_word(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_prev_word(EditLine *el, int c __attribute__((unused))) +vi_prev_word(EditLine *el, int c __attribute__((__unused__))) { if (el->el_line.cursor == el->el_line.buffer) @@ -199,7 +188,7 @@ vi_prev_word(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_next_big_word(EditLine *el, int c __attribute__((unused))) +vi_next_big_word(EditLine *el, int c) { if (el->el_line.cursor >= el->el_line.lastchar - 1) @@ -223,7 +212,7 @@ vi_next_big_word(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_next_word(EditLine *el, int c __attribute__((unused))) +vi_next_word(EditLine *el, int c __attribute__((__unused__))) { if (el->el_line.cursor >= el->el_line.lastchar - 1) @@ -278,7 +267,7 @@ vi_change_case(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_change_meta(EditLine *el, int c __attribute__((unused))) +vi_change_meta(EditLine *el, int c __attribute__((__unused__))) { /* @@ -295,7 +284,7 @@ vi_change_meta(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_insert_at_bol(EditLine *el, int c __attribute__((unused))) +vi_insert_at_bol(EditLine *el, int c __attribute__((__unused__))) { el->el_line.cursor = el->el_line.buffer; @@ -311,7 +300,7 @@ vi_insert_at_bol(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_replace_char(EditLine *el, int c __attribute__((unused))) +vi_replace_char(EditLine *el, int c __attribute__((__unused__))) { if (el->el_line.cursor >= el->el_line.lastchar) @@ -330,7 +319,7 @@ vi_replace_char(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_replace_mode(EditLine *el, int c __attribute__((unused))) +vi_replace_mode(EditLine *el, int c __attribute__((__unused__))) { el->el_map.current = el->el_map.key; @@ -346,7 +335,7 @@ vi_replace_mode(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_substitute_char(EditLine *el, int c __attribute__((unused))) +vi_substitute_char(EditLine *el, int c __attribute__((__unused__))) { c_delafter(el, el->el_state.argument); @@ -361,7 +350,7 @@ vi_substitute_char(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_substitute_line(EditLine *el, int c __attribute__((unused))) +vi_substitute_line(EditLine *el, int c __attribute__((__unused__))) { cv_undo(el); @@ -379,7 +368,7 @@ vi_substitute_line(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_change_to_eol(EditLine *el, int c __attribute__((unused))) +vi_change_to_eol(EditLine *el, int c __attribute__((__unused__))) { cv_undo(el); @@ -397,7 +386,7 @@ vi_change_to_eol(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_insert(EditLine *el, int c __attribute__((unused))) +vi_insert(EditLine *el, int c __attribute__((__unused__))) { el->el_map.current = el->el_map.key; @@ -412,7 +401,7 @@ vi_insert(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_add(EditLine *el, int c __attribute__((unused))) +vi_add(EditLine *el, int c __attribute__((__unused__))) { int ret; @@ -437,7 +426,7 @@ vi_add(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_add_at_eol(EditLine *el, int c __attribute__((unused))) +vi_add_at_eol(EditLine *el, int c __attribute__((__unused__))) { el->el_map.current = el->el_map.key; @@ -453,7 +442,7 @@ vi_add_at_eol(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_delete_meta(EditLine *el, int c __attribute__((unused))) +vi_delete_meta(EditLine *el, int c __attribute__((__unused__))) { return (cv_action(el, DELETE)); @@ -466,7 +455,7 @@ vi_delete_meta(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_end_big_word(EditLine *el, int c __attribute__((unused))) +vi_end_big_word(EditLine *el, int c) { if (el->el_line.cursor == el->el_line.lastchar) @@ -490,7 +479,7 @@ vi_end_big_word(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_end_word(EditLine *el, int c __attribute__((unused))) +vi_end_word(EditLine *el, int c __attribute__((__unused__))) { if (el->el_line.cursor == el->el_line.lastchar) @@ -514,7 +503,7 @@ vi_end_word(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_undo(EditLine *el, int c __attribute__((unused))) +vi_undo(EditLine *el, int c __attribute__((__unused__))) { c_undo_t un = el->el_chared.c_undo; @@ -540,7 +529,7 @@ vi_undo(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_command_mode(EditLine *el, int c __attribute__((unused))) +vi_command_mode(EditLine *el, int c __attribute__((__unused__))) { /* [Esc] cancels pending action */ @@ -585,20 +574,14 @@ vi_zero(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_delete_prev_char(EditLine *el, int c __attribute__((unused))) +vi_delete_prev_char(EditLine *el, int c __attribute__((__unused__))) { - char *cp; - cp = el->el_line.cursor; - if (cp <= el->el_line.buffer) + if (el->el_line.cursor <= el->el_line.buffer) return (CC_ERROR); - /* do the delete here so we dont mess up the undo and paste buffers */ - el->el_line.cursor = --cp; - for (; cp < el->el_line.lastchar; cp++) - cp[0] = cp[1]; - el->el_line.lastchar = cp - 1; - + c_delbefore1(el); + el->el_line.cursor--; return (CC_REFRESH); } @@ -609,23 +592,35 @@ vi_delete_prev_char(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_list_or_eof(EditLine *el, int c __attribute__((unused))) +vi_list_or_eof(EditLine *el, int c __attribute__((__unused__))) { -#ifdef notyet - if (el->el_line.cursor == el->el_line.lastchar && - el->el_line.cursor == el->el_line.buffer) { -#endif - term_overwrite(el, STReof, 4); /* then do a EOF */ - term__flush(); - return (CC_EOF); -#ifdef notyet + if (el->el_line.cursor == el->el_line.lastchar) { + if (el->el_line.cursor == el->el_line.buffer) { + term_overwrite(el, STReof, 4); /* then do a EOF */ + term__flush(); + return (CC_EOF); + } else { + /* + * Here we could list completions, but it is an + * error right now + */ + term_beep(el); + return (CC_ERROR); + } } else { +#ifdef notyet re_goto_bottom(el); *el->el_line.lastchar = '\0'; /* just in case */ return (CC_LIST_CHOICES); - } +#else + /* + * Just complain for now. + */ + term_beep(el); + return (CC_ERROR); #endif + } } @@ -635,7 +630,7 @@ vi_list_or_eof(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_kill_line_prev(EditLine *el, int c __attribute__((unused))) +vi_kill_line_prev(EditLine *el, int c __attribute__((__unused__))) { char *kp, *cp; @@ -656,7 +651,7 @@ vi_kill_line_prev(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_search_prev(EditLine *el, int c __attribute__((unused))) +vi_search_prev(EditLine *el, int c __attribute__((__unused__))) { return (cv_search(el, ED_SEARCH_PREV_HISTORY)); @@ -669,7 +664,7 @@ vi_search_prev(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_search_next(EditLine *el, int c __attribute__((unused))) +vi_search_next(EditLine *el, int c __attribute__((__unused__))) { return (cv_search(el, ED_SEARCH_NEXT_HISTORY)); @@ -682,7 +677,7 @@ vi_search_next(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_repeat_search_next(EditLine *el, int c __attribute__((unused))) +vi_repeat_search_next(EditLine *el, int c __attribute__((__unused__))) { if (el->el_search.patlen == 0) @@ -698,7 +693,7 @@ vi_repeat_search_next(EditLine *el, int c __attribute__((unused))) */ /*ARGSUSED*/ protected el_action_t -vi_repeat_search_prev(EditLine *el, int c __attribute__((unused))) +vi_repeat_search_prev(EditLine *el, int c __attribute__((__unused__))) { if (el->el_search.patlen == 0) @@ -716,7 +711,7 @@ vi_repeat_search_prev(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_next_char(EditLine *el, int c __attribute__((unused))) +vi_next_char(EditLine *el, int c __attribute__((__unused__))) { return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 0); } @@ -728,7 +723,7 @@ vi_next_char(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_prev_char(EditLine *el, int c __attribute__((unused))) +vi_prev_char(EditLine *el, int c __attribute__((__unused__))) { return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 0); } @@ -740,7 +735,7 @@ vi_prev_char(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_to_next_char(EditLine *el, int c __attribute__((unused))) +vi_to_next_char(EditLine *el, int c __attribute__((__unused__))) { return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 1); } @@ -752,7 +747,7 @@ vi_to_next_char(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_to_prev_char(EditLine *el, int c __attribute__((unused))) +vi_to_prev_char(EditLine *el, int c __attribute__((__unused__))) { return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 1); } @@ -764,7 +759,7 @@ vi_to_prev_char(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_repeat_next_char(EditLine *el, int c __attribute__((unused))) +vi_repeat_next_char(EditLine *el, int c __attribute__((__unused__))) { return cv_csearch(el, el->el_search.chadir, el->el_search.chacha, @@ -778,7 +773,7 @@ vi_repeat_next_char(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_repeat_prev_char(EditLine *el, int c __attribute__((unused))) +vi_repeat_prev_char(EditLine *el, int c __attribute__((__unused__))) { el_action_t r; int dir = el->el_search.chadir; @@ -796,7 +791,7 @@ vi_repeat_prev_char(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_match(EditLine *el, int c __attribute__((unused))) +vi_match(EditLine *el, int c) { const char match_chars[] = "()[]{}"; char *cp; @@ -843,7 +838,7 @@ vi_match(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_undo_line(EditLine *el, int c __attribute__((unused))) +vi_undo_line(EditLine *el, int c) { cv_undo(el); @@ -857,7 +852,7 @@ vi_undo_line(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_to_column(EditLine *el, int c __attribute__((unused))) +vi_to_column(EditLine *el, int c) { el->el_line.cursor = el->el_line.buffer; @@ -871,7 +866,7 @@ vi_to_column(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_yank_end(EditLine *el, int c __attribute__((unused))) +vi_yank_end(EditLine *el, int c) { cv_yank(el, el->el_line.cursor, @@ -885,7 +880,7 @@ vi_yank_end(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_yank(EditLine *el, int c __attribute__((unused))) +vi_yank(EditLine *el, int c) { return cv_action(el, YANK); @@ -897,7 +892,7 @@ vi_yank(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_comment_out(EditLine *el, int c __attribute__((unused))) +vi_comment_out(EditLine *el, int c) { el->el_line.cursor = el->el_line.buffer; @@ -915,7 +910,7 @@ vi_comment_out(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_alias(EditLine *el __attribute__((unused)), int c __attribute__((unused))) +vi_alias(EditLine *el, int c) { #ifdef __weak_extern char alias_name[3]; @@ -947,7 +942,7 @@ vi_alias(EditLine *el __attribute__((unused)), int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_to_history_line(EditLine *el, int c __attribute__((unused))) +vi_to_history_line(EditLine *el, int c) { int sv_event_no = el->el_history.eventno; el_action_t rval; @@ -992,7 +987,7 @@ vi_to_history_line(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_histedit(EditLine *el, int c __attribute__((unused))) +vi_histedit(EditLine *el, int c) { int fd; pid_t pid; @@ -1048,7 +1043,7 @@ vi_histedit(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_history_word(EditLine *el, int c __attribute__((unused))) +vi_history_word(EditLine *el, int c) { const char *wp = HIST_FIRST(el); const char *wep, *wsp; @@ -1097,7 +1092,7 @@ vi_history_word(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -vi_redo(EditLine *el, int c __attribute__((unused))) +vi_redo(EditLine *el, int c) { c_redo_t *r = &el->el_chared.c_redo; diff --git a/cmd-line-utils/libedit/vis.c b/cmd-line-utils/libedit/vis.c new file mode 100644 index 00000000000..127d28733a8 --- /dev/null +++ b/cmd-line-utils/libedit/vis.c @@ -0,0 +1,392 @@ +/* $NetBSD: vis.c,v 1.27 2004/02/26 23:01:15 enami Exp $ */ + +/*- + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* AIX requires this to be the first thing in the file. */ +#if defined (_AIX) && !defined (__GNUC__) + #pragma alloca +#endif + +#include <config.h> + +#ifdef __GNUC__ +# undef alloca +# define alloca(n) __builtin_alloca (n) +#else +# ifdef HAVE_ALLOCA_H +# include <alloca.h> +# else +# ifndef _AIX +extern char *alloca (); +# endif +# endif +#endif + +#include <sys/types.h> + +#include <assert.h> +#include <vis.h> +#include <stdlib.h> + +#ifdef __weak_alias +__weak_alias(strsvis,_strsvis) +__weak_alias(strsvisx,_strsvisx) +__weak_alias(strvis,_strvis) +__weak_alias(strvisx,_strvisx) +__weak_alias(svis,_svis) +__weak_alias(vis,_vis) +#endif + +#if !HAVE_VIS || !HAVE_SVIS +#include <ctype.h> +#include <limits.h> +#include <stdio.h> +#include <string.h> + +#undef BELL +#define BELL '\a' + +#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') +#define iswhite(c) (c == ' ' || c == '\t' || c == '\n') +#define issafe(c) (c == '\b' || c == BELL || c == '\r') +#define xtoa(c) "0123456789abcdef"[c] + +#define MAXEXTRAS 5 + + +#define MAKEEXTRALIST(flag, extra, orig) \ +do { \ + const char *o = orig; \ + char *e; \ + while (*o++) \ + continue; \ + extra = alloca((size_t)((o - orig) + MAXEXTRAS)); \ + for (o = orig, e = extra; (*e++ = *o++) != '\0';) \ + continue; \ + e--; \ + if (flag & VIS_SP) *e++ = ' '; \ + if (flag & VIS_TAB) *e++ = '\t'; \ + if (flag & VIS_NL) *e++ = '\n'; \ + if ((flag & VIS_NOSLASH) == 0) *e++ = '\\'; \ + *e = '\0'; \ +} while (/*CONSTCOND*/0) + + +/* + * This is HVIS, the macro of vis used to HTTP style (RFC 1808) + */ +#define HVIS(dst, c, flag, nextc, extra) \ +do \ + if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) { \ + *dst++ = '%'; \ + *dst++ = xtoa(((unsigned int)c >> 4) & 0xf); \ + *dst++ = xtoa((unsigned int)c & 0xf); \ + } else { \ + SVIS(dst, c, flag, nextc, extra); \ + } \ +while (/*CONSTCOND*/0) + +/* + * This is SVIS, the central macro of vis. + * dst: Pointer to the destination buffer + * c: Character to encode + * flag: Flag word + * nextc: The character following 'c' + * extra: Pointer to the list of extra characters to be + * backslash-protected. + */ +#define SVIS(dst, c, flag, nextc, extra) \ +do { \ + int isextra; \ + isextra = strchr(extra, c) != NULL; \ + if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) || \ + ((flag & VIS_SAFE) && issafe(c)))) { \ + *dst++ = c; \ + break; \ + } \ + if (flag & VIS_CSTYLE) { \ + switch (c) { \ + case '\n': \ + *dst++ = '\\'; *dst++ = 'n'; \ + continue; \ + case '\r': \ + *dst++ = '\\'; *dst++ = 'r'; \ + continue; \ + case '\b': \ + *dst++ = '\\'; *dst++ = 'b'; \ + continue; \ + case BELL: \ + *dst++ = '\\'; *dst++ = 'a'; \ + continue; \ + case '\v': \ + *dst++ = '\\'; *dst++ = 'v'; \ + continue; \ + case '\t': \ + *dst++ = '\\'; *dst++ = 't'; \ + continue; \ + case '\f': \ + *dst++ = '\\'; *dst++ = 'f'; \ + continue; \ + case ' ': \ + *dst++ = '\\'; *dst++ = 's'; \ + continue; \ + case '\0': \ + *dst++ = '\\'; *dst++ = '0'; \ + if (isoctal(nextc)) { \ + *dst++ = '0'; \ + *dst++ = '0'; \ + } \ + continue; \ + default: \ + if (isgraph(c)) { \ + *dst++ = '\\'; *dst++ = c; \ + continue; \ + } \ + } \ + } \ + if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) { \ + *dst++ = '\\'; \ + *dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0'; \ + *dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0'; \ + *dst++ = (c & 07) + '0'; \ + } else { \ + if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\'; \ + if (c & 0200) { \ + c &= 0177; *dst++ = 'M'; \ + } \ + if (iscntrl(c)) { \ + *dst++ = '^'; \ + if (c == 0177) \ + *dst++ = '?'; \ + else \ + *dst++ = c + '@'; \ + } else { \ + *dst++ = '-'; *dst++ = c; \ + } \ + } \ +} while (/*CONSTCOND*/0) + + +/* + * svis - visually encode characters, also encoding the characters + * pointed to by `extra' + */ +char * +svis(dst, c, flag, nextc, extra) + char *dst; + int c, flag, nextc; + const char *extra; +{ + char *nextra; + _DIAGASSERT(dst != NULL); + _DIAGASSERT(extra != NULL); + MAKEEXTRALIST(flag, nextra, extra); + if (flag & VIS_HTTPSTYLE) + HVIS(dst, c, flag, nextc, nextra); + else + SVIS(dst, c, flag, nextc, nextra); + *dst = '\0'; + return(dst); +} + + +/* + * strsvis, strsvisx - visually encode characters from src into dst + * + * Extra is a pointer to a \0-terminated list of characters to + * be encoded, too. These functions are useful e. g. to + * encode strings in such a way so that they are not interpreted + * by a shell. + * + * Dst must be 4 times the size of src to account for possible + * expansion. The length of dst, not including the trailing NULL, + * is returned. + * + * Strsvisx encodes exactly len bytes from src into dst. + * This is useful for encoding a block of data. + */ +int +strsvis(dst, csrc, flag, extra) + char *dst; + const char *csrc; + int flag; + const char *extra; +{ + int c; + char *start; + char *nextra; + const unsigned char *src = (const unsigned char *)csrc; + + _DIAGASSERT(dst != NULL); + _DIAGASSERT(src != NULL); + _DIAGASSERT(extra != NULL); + MAKEEXTRALIST(flag, nextra, extra); + if (flag & VIS_HTTPSTYLE) { + for (start = dst; (c = *src++) != '\0'; /* empty */) + HVIS(dst, c, flag, *src, nextra); + } else { + for (start = dst; (c = *src++) != '\0'; /* empty */) + SVIS(dst, c, flag, *src, nextra); + } + *dst = '\0'; + return (dst - start); +} + + +int +strsvisx(dst, csrc, len, flag, extra) + char *dst; + const char *csrc; + size_t len; + int flag; + const char *extra; +{ + int c; + char *start; + char *nextra; + const unsigned char *src = (const unsigned char *)csrc; + + _DIAGASSERT(dst != NULL); + _DIAGASSERT(src != NULL); + _DIAGASSERT(extra != NULL); + MAKEEXTRALIST(flag, nextra, extra); + + if (flag & VIS_HTTPSTYLE) { + for (start = dst; len > 0; len--) { + c = *src++; + HVIS(dst, c, flag, len ? *src : '\0', nextra); + } + } else { + for (start = dst; len > 0; len--) { + c = *src++; + SVIS(dst, c, flag, len ? *src : '\0', nextra); + } + } + *dst = '\0'; + return (dst - start); +} +#endif + +#if !HAVE_VIS +/* + * vis - visually encode characters + */ +char * +vis(dst, c, flag, nextc) + char *dst; + int c, flag, nextc; + +{ + char *extra; + + _DIAGASSERT(dst != NULL); + + MAKEEXTRALIST(flag, extra, ""); + if (flag & VIS_HTTPSTYLE) + HVIS(dst, c, flag, nextc, extra); + else + SVIS(dst, c, flag, nextc, extra); + *dst = '\0'; + return (dst); +} + + +/* + * strvis, strvisx - visually encode characters from src into dst + * + * Dst must be 4 times the size of src to account for possible + * expansion. The length of dst, not including the trailing NULL, + * is returned. + * + * Strvisx encodes exactly len bytes from src into dst. + * This is useful for encoding a block of data. + */ +int +strvis(dst, src, flag) + char *dst; + const char *src; + int flag; +{ + char *extra; + + MAKEEXTRALIST(flag, extra, ""); + return (strsvis(dst, src, flag, extra)); +} + + +int +strvisx(dst, src, len, flag) + char *dst; + const char *src; + size_t len; + int flag; +{ + char *extra; + + MAKEEXTRALIST(flag, extra, ""); + return (strsvisx(dst, src, len, flag, extra)); +} +#endif diff --git a/cmd-line-utils/libedit/vis.h b/cmd-line-utils/libedit/vis.h new file mode 100644 index 00000000000..44f6fc7d785 --- /dev/null +++ b/cmd-line-utils/libedit/vis.h @@ -0,0 +1,92 @@ +/* $NetBSD: vis.h,v 1.15 2005/02/03 04:39:32 perry Exp $ */ + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)vis.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _VIS_H_ +#define _VIS_H_ + +#include <config.h> + +/* + * to select alternate encoding format + */ +#define VIS_OCTAL 0x01 /* use octal \ddd format */ +#define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropiate */ + +/* + * to alter set of characters encoded (default is to encode all + * non-graphic except space, tab, and newline). + */ +#define VIS_SP 0x04 /* also encode space */ +#define VIS_TAB 0x08 /* also encode tab */ +#define VIS_NL 0x10 /* also encode newline */ +#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL) +#define VIS_SAFE 0x20 /* only encode "unsafe" characters */ + +/* + * other + */ +#define VIS_NOSLASH 0x40 /* inhibit printing '\' */ +#define VIS_HTTPSTYLE 0x80 /* http-style escape % HEX HEX */ + +/* + * unvis return codes + */ +#define UNVIS_VALID 1 /* character valid */ +#define UNVIS_VALIDPUSH 2 /* character valid, push back passed char */ +#define UNVIS_NOCHAR 3 /* valid sequence, no character produced */ +#define UNVIS_SYNBAD -1 /* unrecognized escape sequence */ +#define UNVIS_ERROR -2 /* decoder in unknown state (unrecoverable) */ + +/* + * unvis flags + */ +#define UNVIS_END 1 /* no more characters */ + +__BEGIN_DECLS +char *vis(char *, int, int, int); +char *svis(char *, int, int, int, const char *); +int strvis(char *, const char *, int); +int strsvis(char *, const char *, int, const char *); +int strvisx(char *, const char *, size_t, int); +int strsvisx(char *, const char *, size_t, int, const char *); +int strunvis(char *, const char *); +int strunvisx(char *, const char *, int); +#ifdef __LIBC12_SOURCE__ +int unvis(char *, int, int *, int); +int __unvis13(char *, int, int *, int); +#else +int unvis(char *, int, int *, int); +#endif +__END_DECLS + +#endif /* !_VIS_H_ */ |