From: pfalstad@phoenix.Princeton.EDU (Paul John Falstad) Newsgroups: alt.sources Subject: zsh - ksh/tcsh-like shell (part 8 of 8) Message-ID: <4750@idunno.Princeton.EDU> Date: 14 Dec 90 23:34:18 GMT ---cut here---cut here---cut here--- -/* The last key bindings file read. */ -static char *last_readline_init_file = "~/.inputrc"; - -/* Re-read the current keybindings file. */ -rl_re_read_init_file (count, ignore) -int count, ignore; -{ - rl_read_init_file (last_readline_init_file); -} - -/* Do key bindings from a file. If FILENAME is NULL it defaults - to `~/.inputrc'. If the file existed and could be opened and - read, 0 is returned, otherwise errno is returned. */ -int -rl_read_init_file (filename) -char *filename; -{ - extern int errno; - int line_size, line_index; - char *line = (char *)xmalloc (line_size = 100); - char *openname; - FILE *file; - - int c; - - /* Default the filename. */ - if (!filename) - filename = "~/.inputrc"; - - openname = tilde_expand (filename); - - /* Open the file. */ - file = fopen (openname, "r"); - free (openname); - - if (!file) - return (errno); - - last_readline_init_file = filename; - - /* Loop reading lines from the file. Lines that start with `#' are - comments, all other lines are commands for readline initialization. */ - while ((c = rl_getc (file)) != EOF) - { - /* If comment, flush to EOL. */ - if (c == '#') - { - while ((c = rl_getc (file)) != EOF && c != '\n'); - if (c == EOF) - goto function_exit; - continue; - } - - /* Otherwise, this is the start of a line. Read the - line from the file. */ - line_index = 0; - while (c != EOF && c != '\n') - { - line[line_index++] = c; - if (line_index == line_size) - line = (char *)xrealloc (line, line_size += 100); - c = rl_getc (file); - } - line[line_index] = '\0'; - - /* Parse the line. */ - rl_parse_and_bind (line); - } - -function_exit: - - free (line); - /* Close up the file and exit. */ - fclose (file); - return (0); -} - - -/* **************************************************************** */ -/* */ -/* Parser Directives */ -/* */ -/* **************************************************************** */ - -/* Conditionals. */ - -/* Calling programs set this to have their argv[0]. */ -char *rl_readline_name = "other"; - -/* Stack of previous values of parsing_conditionalized_out. */ -static unsigned char *if_stack = (unsigned char *)NULL; -static int if_stack_depth = 0; -static int if_stack_size = 0; - -/* Push parsing_conditionalized_out, and set parser state based on ARGS. */ -parser_if (args) -char *args; -{ - register int i; - - /* Push parser state. */ - if (if_stack_depth + 1 >= if_stack_size) - { - if (!if_stack) - if_stack = (unsigned char *)xmalloc (if_stack_size = 20); - else - if_stack = (unsigned char *)xrealloc (if_stack, if_stack_size += 20); - } - if_stack[if_stack_depth++] = parsing_conditionalized_out; - - /* We only check to see if the first word in ARGS is the same as the - value stored in rl_readline_name. */ - - /* Isolate first argument. */ - for (i = 0; args[i] && !whitespace (args[i]); i++); - - if (args[i]) - args[i++] = '\0'; - - if (stricmp (args, rl_readline_name) == 0) - parsing_conditionalized_out = 0; - else - parsing_conditionalized_out = 1; -} - -/* Invert the current parser state if there is anything on the stack. */ -parser_else (args) -char *args; -{ - if (if_stack_depth) - parsing_conditionalized_out = !parsing_conditionalized_out; - else - { - /* *** What, no error message? *** */ - } -} - -/* Terminate a conditional, popping the value of - parsing_conditionalized_out from the stack. */ -parser_endif (args) -char *args; -{ - if (if_stack_depth) - parsing_conditionalized_out = if_stack[--if_stack_depth]; - else - { - /* *** What, no error message? *** */ - } -} - -/* Associate textual names with actual functions. */ -static struct { - char *name; - Function *function; -} parser_directives [] = { - { "if", parser_if }, - { "endif", parser_endif }, - { "else", parser_else }, - { (char *)0x0, (Function *)0x0 } -}; - - -/* Handle a parser directive. STATEMENT is the line of the directive - without any leading `$'. */ -static int -handle_parser_directive (statement) -char *statement; -{ - register int i; - char *directive, *args; - - /* Isolate the actual directive. */ - - /* Skip whitespace. */ - for (i = 0; whitespace (statement[i]); i++); - - directive = &statement[i]; - - for (; statement[i] && !whitespace (statement[i]); i++); - - if (statement[i]) - statement[i++] = '\0'; - - for (; statement[i] && whitespace (statement[i]); i++); - - args = &statement[i]; - - /* Lookup the command, and act on it. */ - for (i = 0; parser_directives[i].name; i++) - if (stricmp (directive, parser_directives[i].name) == 0) - { - (*parser_directives[i].function) (args); - return (0); - } - - /* *** Should an error message be output? */ - return (1); -} - -/* Read the binding command from STRING and perform it. - A key binding command looks like: Keyname: function-name\0, - a variable binding command looks like: set variable value. - A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */ -rl_parse_and_bind (string) -char *string; -{ - extern char *possible_control_prefixes[], *possible_meta_prefixes[]; - char *rindex (), *funname, *kname; - static int substring_member_of_array (); - register int c; - int key, i; - - if (!string || !*string || *string == '#') - return; - - /* If this is a parser directive, act on it. */ - if (*string == '$') - { - handle_parser_directive (&string[1]); - return; - } - - /* If we are supposed to be skipping parsing right now, then do it. */ - if (parsing_conditionalized_out) - return; - - i = 0; - /* If this keyname is a complex key expression surrounded by quotes, - advance to after the matching close quote. */ - if (*string == '"') - { - for (i = 1; c = string[i]; i++) - { - if (c == '"' && string[i - 1] != '\\') - break; - } - } - - /* Advance to the colon (:) or whitespace which separates the two objects. */ - for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ ); - - /* Mark the end of the command (or keyname). */ - if (string[i]) - string[i++] = '\0'; - - /* If this is a command to set a variable, then do that. */ - if (stricmp (string, "set") == 0) - { - char *var = string + i; - char *value; - - /* Make VAR point to start of variable name. */ - while (*var && whitespace (*var)) var++; - - /* Make value point to start of value string. */ - value = var; - while (*value && !whitespace (*value)) value++; - if (*value) - *value++ = '\0'; - while (*value && whitespace (*value)) value++; - - rl_variable_bind (var, value); - return; - } - - /* Skip any whitespace between keyname and funname. */ - for (; string[i] && whitespace (string[i]); i++); - funname = &string[i]; - - /* Now isolate funname. - For straight function names just look for whitespace, since - that will signify the end of the string. But this could be a - macro definition. In that case, the string is quoted, so skip - to the matching delimiter. */ - if (*funname == '\'' || *funname == '"') - { - int delimiter = string[i++]; - - for (; c = string[i]; i++) - { - if (c == delimiter && string[i - 1] != '\\') - break; - } - if (c) - i++; - } - - /* Advance to the end of the string. */ - for (; string[i] && !whitespace (string[i]); i++); - - /* No extra whitespace at the end of the string. */ - string[i] = '\0'; - - /* If this is a new-style key-binding, then do the binding with - rl_set_key (). Otherwise, let the older code deal with it. */ - if (*string == '"') - { - char *seq = (char *)alloca (1 + strlen (string)); - register int j, k = 0; - - for (j = 1; string[j]; j++) - { - if (string[j] == '"' && string[j - 1] != '\\') - break; - - seq[k++] = string[j]; - } - seq[k] = '\0'; - - /* Binding macro? */ - if (*funname == '\'' || *funname == '"') - { - j = strlen (funname); - - if (j && funname[j - 1] == *funname) - funname[j - 1] = '\0'; - - rl_macro_bind (seq, &funname[1], keymap); - } - else - rl_set_key (seq, rl_named_function (funname), keymap); - - return; - } - - /* Get the actual character we want to deal with. */ - kname = rindex (string, '-'); - if (!kname) - kname = string; - else - kname++; - - key = glean_key_from_name (kname); - - /* Add in control and meta bits. */ - if (substring_member_of_array (string, possible_control_prefixes)) - key = CTRL (to_upper (key)); - - if (substring_member_of_array (string, possible_meta_prefixes)) - key = META (key); - - /* Temporary. Handle old-style keyname with macro-binding. */ - if (*funname == '\'' || *funname == '"') - { - char seq[2]; - int fl = strlen (funname); - - seq[0] = key; - seq[1] = '\0'; - if (fl && funname[fl - 1] == *funname) - funname[fl - 1] = '\0'; - - rl_macro_bind (seq, &funname[1], keymap); - } - else - rl_bind_key (key, rl_named_function (funname)); -} - -rl_variable_bind (name, value) -char *name, *value; -{ - if (stricmp (name, "editing-mode") == 0) - { - if (strnicmp (value, "vi", 2) == 0) - { -#ifdef VI_MODE - keymap = vi_insertion_keymap; - rl_editing_mode = vi_mode; -#endif /* VI_MODE */ - } - else if (strnicmp (value, "emacs", 5) == 0) - { - keymap = emacs_standard_keymap; - rl_editing_mode = emacs_mode; - } - } - else if (stricmp (name, "horizontal-scroll-mode") == 0) - { - if (!*value || stricmp (value, "On") == 0) - horizontal_scroll_mode = 1; - else - horizontal_scroll_mode = 0; - } -} - -/* Return the character which matches NAME. - For example, `Space' returns ' '. */ - -typedef struct { - char *name; - int value; -} assoc_list; - -assoc_list name_key_alist[] = { - { "Space", ' ' }, - { "SPC", ' ' }, - { "Rubout", 0x7f }, - { "DEL", 0x7f }, - { "Tab", 0x09 }, - { "Newline", '\n' }, - { "Return", '\r' }, - { "RET", '\r' }, - { "LFD", '\n' }, - { "Escape", '\033' }, - { "ESC", '\033' }, - { (char *)0x0, 0 } -}; - - -int -glean_key_from_name (name) -char *name; -{ - register int i; - - for (i = 0; name_key_alist[i].name; i++) - if (stricmp (name, name_key_alist[i].name) == 0) - return (name_key_alist[i].value); - - return (*name); -} - - -/* **************************************************************** */ -/* */ -/* String Utility Functions */ -/* */ -/* **************************************************************** */ - -/* Return non-zero if any members of ARRAY are a substring in STRING. */ -static int -substring_member_of_array (string, array) -char *string, **array; -{ - static char *strindex (); - - while (*array) - { - if (strindex (string, *array)) - return (1); - array++; - } - return (0); -} - -/* Whoops, Unix doesn't have strnicmp. */ - -/* Compare at most COUNT characters from string1 to string2. Case - doesn't matter. */ -static int -strnicmp (string1, string2, count) -char *string1, *string2; -{ - register char ch1, ch2; - - while (count) - { - ch1 = *string1++; - ch2 = *string2++; - if (to_upper(ch1) == to_upper(ch2)) - count--; - else break; - } - return (count); -} - -/* strcmp (), but caseless. */ -static int -stricmp (string1, string2) -char *string1, *string2; -{ - register char ch1, ch2; - - while (*string1 && *string2) - { - ch1 = *string1++; - ch2 = *string2++; - if (to_upper(ch1) != to_upper(ch2)) - return (1); - } - return (*string1 | *string2); -} - -/* Determine if s2 occurs in s1. If so, return a pointer to the - match in s1. The compare is case insensitive. */ -static char * -strindex (s1, s2) -register char *s1, *s2; -{ - register int i, l = strlen (s2); - register int len = strlen (s1); - - for (i = 0; (len - i) >= l; i++) - if (strnicmp (&s1[i], s2, l) == 0) - return (s1 + i); - return ((char *)NULL); -} - - -/* **************************************************************** */ -/* */ -/* SYSV Support */ -/* */ -/* **************************************************************** */ - -/* Since system V reads input differently than we do, I have to - make a special version of getc for that. */ - -#include - -int -rl_getc (stream) -FILE *stream; -{ - int result; - unsigned char c; - - rl_waiting = 1; - result = read (fileno (stream), &c, sizeof (char)); - rl_waiting = 0; - if (result == sizeof (char)) - return (c); - - if (errno != EINTR) - return EOF; - rl_done = rl_end = errflag = 1; - return EOF; -} - -#ifdef STATIC_MALLOC - -/* **************************************************************** */ -/* */ -/* xmalloc and xrealloc () */ -/* */ -/* **************************************************************** */ - -static void memory_error_and_abort (); - -static char * -xmalloc (bytes) -int bytes; -{ - char *temp = (char *)malloc (bytes); - - if (!temp) - memory_error_and_abort (); - return (temp); -} - -static char * -xrealloc (pointer, bytes) -char *pointer; -int bytes; -{ - char *temp = (char *)realloc (pointer, bytes); - - if (!temp) - memory_error_and_abort (); - return (temp); -} - -static void -memory_error_and_abort () -{ - fprintf (stderr, "readline: Out of virtual memory!\n"); - abort (); -} -#endif /* STATIC_MALLOC */ -/* - * Local variables: - * compile-command: "gcc -g -traditional -I. -I.. -DTEST -o readline readline.c keymaps.o funmap.o history.o -ltermcap" - * end: - */ - -rl_function_key(count) /* pjf */ -{ - switch(rl_getc(rl_instream)) - { - case 'A': - rl_get_previous_history(count); - break; - case 'B': - rl_get_next_history(count); - break; - case 'C': - rl_forward(count); - break; - case 'D': - rl_backward(count); - break; - default: - ding(); - break; - } -} - -static char *spname(); - -rl_check_spelling() -{ - char *match; - int start, end, delimiter = 0; - char *text; - - /* We now look backwards for the start of a filename/variable word. */ - end = rl_point; - if (rl_point) - { - while (--rl_point && - !rindex (rl_completer_word_break_characters, the_line[rl_point])); - - /* If we are at a word break, then advance past it. */ - if (rindex (rl_completer_word_break_characters, (the_line[rl_point]))) - { - /* If the character that caused the word break was a quoting - character, then remember it as the delimiter. */ - if (rindex ("\"'", the_line[rl_point]) && (end - rl_point) > 1) - delimiter = the_line[rl_point]; - - /* If the character isn't needed to determine something special - about what kind of completion to perform, then advance past it. */ - - if (!rl_special_prefixes || - !rindex (rl_special_prefixes, the_line[rl_point])) - rl_point++; - } - } - - start = rl_point; - rl_point = end; - text = rl_copy (start, end); - - match = spname(text); - - free (text); - - if (!match) - ding (); - else - { - rl_delete_text (start, rl_point); - rl_point = start; - rl_insert_text (match); - } -} - -/* next 3 functions stolen from Kernighan & Pike */ -/* "The UNIX Programming Environment" (w/o permission) */ - -static char *spname (oldname) char *oldname; -{ - char *p,guess[MAXPATHLEN+1],best[MAXPATHLEN+1]; - char newname[MAXPATHLEN+1]; - char *new = newname, *old = oldname; - - for (;;) - { - while (*old == '/') - *new++ = *old++; - *new = '\0'; - if (*old == '\0') - return newname; - p = guess; - for (; *old != '/' && *old != '\0'; old++) - if (p < guess+MAXPATHLEN) - *p++ = *old; - *p = '\0'; - if (mindist(newname,guess,best) >= 3) - return oldname; - for (p = best; *new = *p++; ) - new++; - } -} - -mindist(dir,guess,best) char *dir,*guess,*best; -{ - int d,nd; - DIR *dd; - struct direct *de; - - if (dir[0] == '\0') - dir = "."; - d = 3; - if (!(dd = opendir(dir))) - return d; - while (de = readdir(dd)) - { - nd = spdist(de->d_name,guess); - if (nd <= d && nd != 3) { - strcpy(best,de->d_name); - d = nd; - if (d == 0) - break; - } - } - closedir(dd); - return d; -} - -#define EQ(s,t) (strcmp(s,t) == 0) - -spdist(s,t) char *s, *t; -{ - while (*s++ == *t) - if (*t++ == '\0') - return 0; - if (*--s) - { - if (*t) - { - if (s[1] && t[1] && *s == t[1] && *t == s[1] && - EQ(s+2,t+2)) - return 1; - if (EQ(s+1,t+1)) - return 2; - } - if (EQ(s+1,t)) - return 2; - } - if (*t && EQ(s,t+1)) - return 2; - return 3; -} - -char *strpbrk(s,t) char *s,*t; -{ - char *u = t; - - while (*s) - { - for (t = u; *t; t++) - if (*s == *t) - return s; - s++; - } - return NULL; -} - -void rl_safe_insert_text(s) char *s; -{ - char *bad = " \\!#$^*()|=[]{}`\'\";?><"; - char *t; - - for(;;) - if (t = strpbrk(s,bad)) - { - char a = *t; - - *t = '\0'; - rl_insert_text(s); - rl_insert_text("\\"); - *t = a; - a = t[1]; - t[1] = '\0'; - rl_insert_text(t); - t[1] = a; - s = t+1; - } - else - { - rl_insert_text(s); - return; - } -} - -#define HERR -125 - -extern int magic; -char *strdup(); -int hgetc(); - -rl_magic_space () -{ - int c,pt = 0; - char *str; - - the_line[rl_end] = '\0'; /* necessary? */ - str = strdup(the_line); - strinbeg(); - magic = 1; - hungets(strdup("\n")); - hungets(strdup(the_line)); - while ((c = hgetc()) != EOF) - { - if (c == HERR) - { - strcpy(the_line,str); - free(str); - hflush(); - magic = 0; - strinend(); - rl_on_new_line(); - rl_redisplay(); - return 0; - } - if (c == '!') - the_line[pt++] = '\\'; - the_line[pt++] = c; - } - if (!pt) - fprintf(stderr,"Whoops.\n"); - the_line[rl_end = rl_point = pt-1] = '\0'; - magic = 0; - strinend(); - free(str); -} End of readline/readline.c echo readline/readline.h 1>&2 sed 's/^-//' >readline/readline.h <<'End of readline/readline.h' -/* Readline.h -- the names of functions callable from within readline. */ - -#ifndef _READLINE_H_ -#define _READLINE_H_ - -#include - -#ifndef __FUNCTION_DEF -typedef int Function (); -#define __FUNCTION_DEF -#endif - -/* The functions for manipulating the text of the line within readline. -Most of these functions are bound to keys by default. */ -extern int -rl_beg_of_line (), rl_backward (), rl_delete (), rl_end_of_line (), -rl_forward (), ding (), rl_backward (), rl_newline (), rl_kill_line (), -rl_clear_screen (), rl_get_next_history (), rl_get_previous_history (), -rl_quoted_insert (), rl_transpose_chars -(), rl_unix_line_discard (), rl_quoted_insert (), rl_unix_word_rubout -(), rl_yank (), rl_rubout (), rl_backward_word (), rl_kill_word (), -rl_forward_word (), rl_tab_insert (), rl_yank_pop (), rl_yank_nth_arg (), -rl_backward_kill_word (), rl_backward_kill_line (), rl_transpose_words -(), rl_complete (), rl_possible_completions (), rl_do_lowercase_version -(), rl_digit_argument (), rl_universal_argument (), rl_abort (), -rl_undo_command (), rl_revert_line (), rl_beginning_of_history (), -rl_end_of_history (), rl_insert (), -rl_upcase_word (), rl_downcase_word (), rl_capitalize_word (), -rl_restart_output (), rl_re_read_init_file (); - -extern int rl_function_key(); /* pjf */ -extern int rl_check_spelling(),rl_magic_space(); -extern int rl_break_c(); - -/* These are *both* defined even when VI_MODE is not. */ -extern int rl_vi_editing_mode (), rl_emacs_editing_mode (); - -#ifdef VI_MODE -/* Things for vi mode. */ -extern int rl_vi_movement_mode (), rl_vi_insertion_mode (), rl_vi_arg_digit (), -rl_vi_prev_word (), rl_vi_next_word (), rl_vi_char_search (), -rl_vi_eof_maybe (), rl_vi_append_mode (), rl_vi_put (), -rl_vi_append_eol (), rl_vi_insert_beg (), rl_vi_delete (), rl_vi_comment (), -rl_vi_first_print (), rl_vi_fword (), rl_vi_fWord (), rl_vi_bword (), -rl_vi_bWord (), rl_vi_eword (), rl_vi_eWord (), rl_vi_end_word (), -rl_vi_change_case (), rl_vi_match (), rl_vi_bracktype (), rl_vi_change_char (), -rl_vi_yank_arg (), rl_vi_search (), rl_vi_search_again (), -rl_vi_dosearch (), rl_vi_subst (), rl_vi_overstrike (), -rl_vi_overstrike_delete (), rl_vi_replace(), rl_vi_column (), -rl_vi_delete_to (), rl_vi_change_to (), rl_vi_yank_to (), rl_vi_complete (); -#endif /* VI_MODE */ - -/* Keyboard macro commands. */ -extern int -rl_start_kbd_macro (), rl_end_kbd_macro (), rl_call_last_kbd_macro (); - -/* Maintaining the state of undo. We remember individual deletes and inserts - on a chain of things to do. */ - -/* The actions that undo knows how to undo. Notice that UNDO_DELETE means - to insert some text, and UNDO_INSERT means to delete some text. I.e., - the code tells undo what to undo, not how to undo it. */ -enum undo_code { UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END }; - -/* What an element of THE_UNDO_LIST looks like. */ -typedef struct undo_list { - struct undo_list *next; - int start, end; /* Where the change took place. */ - char *text; /* The text to insert, if undoing a delete. */ - enum undo_code what; /* Delete, Insert, Begin, End. */ -} UNDO_LIST; - -/* The current undo list for RL_LINE_BUFFER. */ -extern UNDO_LIST *rl_undo_list; - -/* The data structure for mapping textual names to code addresses. */ -typedef struct { - char *name; - Function *function; -} FUNMAP; - -extern FUNMAP **funmap; - -/* **************************************************************** */ -/* */ -/* Well Published Variables */ -/* */ -/* **************************************************************** */ - -/* The name of the calling program. You should initialize this to - whatever was in argv[0]. It is used when parsing conditionals. */ -extern char *rl_readline_name; - -/* The line buffer that is in use. */ -extern char *rl_line_buffer; - -/* The location of point, and end. */ -extern int rl_point, rl_end; - -/* The name of the terminal to use. */ -extern char *rl_terminal_name; - -/* The input and output streams. */ -extern FILE *rl_instream, *rl_outstream; - -/* The basic list of characters that signal a break between words for the - completer routine. The contents of this variable is what breaks words - in the shell, i.e. "n\"\\'`@$>". */ -extern char *rl_basic_word_break_characters; - -/* The list of characters that signal a break between words for - rl_complete_internal. The default list is the contents of - rl_basic_word_break_characters. */ -extern char *rl_completer_word_break_characters; - -/* List of characters that are word break characters, but should be left - in TEXT when it is passed to the completion function. The shell uses - this to help determine what kind of completing to do. */ -extern char *rl_special_prefixes; - -/* Pointer to the generator function for completion_matches (). - NULL means to use filename_entry_function (), the default filename - completer. */ -extern Function *rl_completion_entry_function; - -/* Pointer to alternative function to create matches. - Function is called with TEXT, START, and END. - START and END are indices in RL_LINE_BUFFER saying what the boundaries - of TEXT are. - If this function exists and returns NULL then call the value of - rl_completion_entry_function to try to match, otherwise use the - array of strings returned. */ -extern Function *rl_attempted_completion_function; - -/* If non-null, this contains the address of a function to call if the - standard meaning for expanding a tilde fails. The function is called - with the text (sans tilde, as in "foo"), and returns a malloc()'ed string - which is the expansion, or a NULL pointer if there is no expansion. */ -extern Function *rl_tilde_expander; - -/* If non-zero, then this is the address of a function to call just - before readline_internal () prints the first prompt. */ -extern Function *rl_startup_hook; - -/* If non-zero, then this is the address of a function to call when - completing on a directory name. The function is called with - the address of a string (the current directory name) as an arg. */ -extern Function *rl_symbolic_link_hook; - -/* Non-zero means that modified history lines are preceded - with an asterisk. */ -extern int rl_show_star; - -/* **************************************************************** */ -/* */ -/* Well Published Functions */ -/* */ -/* **************************************************************** */ - -/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means none. */ -extern char *readline (); - -/* Return an array of strings which are the result of repeatadly calling - FUNC with TEXT. */ -extern char **completion_matches (); - -/* rl_add_defun (char *name, Function *function, int key) - Add NAME to the list of named functions. Make FUNCTION - be the function that gets called. - If KEY is not -1, then bind it. */ -extern int rl_add_defun (); - - -#endif /* _READLINE_H_ */ - End of readline/readline.h echo readline/vi_keymap.c 1>&2 sed 's/^-//' >readline/vi_keymap.c <<'End of readline/vi_keymap.c' -/* vi_keymap.c -- the keymap for vi_mode in readline (). */ - -/* Copyright (C) 1988,1989 Free Software Foundation, Inc. - - This file is part of GNU Readline, a library for reading lines - of text with interactive input and history editing. - - Readline is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 1, or (at your option) any - later version. - - Readline is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Readline; see the file COPYING. If not, write to the Free - Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef FILE -#include -#endif /* FILE */ - -#include "readline.h" - -extern KEYMAP_ENTRY_ARRAY vi_escape_keymap; - -/* The keymap arrays for handling vi mode. */ -KEYMAP_ENTRY_ARRAY vi_movement_keymap = { - - /* The regular control keys come first. */ - { ISFUNC, (Function *)0x0 }, /* Control-@ */ - { ISFUNC, (Function *)0x0 }, /* Control-a */ - { ISFUNC, (Function *)0x0 }, /* Control-b */ - { ISFUNC, (Function *)0x0 }, /* Control-c */ - { ISFUNC, rl_vi_eof_maybe }, /* Control-d */ - { ISFUNC, rl_emacs_editing_mode }, /* Control-e */ - { ISFUNC, (Function *)0x0 }, /* Control-f */ - { ISFUNC, rl_abort }, /* Control-g */ - { ISFUNC, rl_rubout }, /* Control-h */ /* pjf */ - { ISFUNC, (Function *)0x0 }, /* Control-i */ - { ISFUNC, rl_newline }, /* Control-j */ - { ISFUNC, rl_kill_line }, /* Control-k */ - { ISFUNC, rl_clear_screen }, /* Control-l */ - { ISFUNC, rl_newline }, /* Control-m */ - { ISFUNC, rl_get_next_history }, /* Control-n */ - { ISFUNC, (Function *)0x0 }, /* Control-o */ - { ISFUNC, rl_get_previous_history }, /* Control-p */ - { ISFUNC, rl_quoted_insert }, /* Control-q */ - { ISFUNC, (Function *)0x0 }, /* Control-r */ - { ISFUNC, (Function *)0x0 }, /* Control-s */ - { ISFUNC, rl_transpose_chars }, /* Control-t */ - { ISFUNC, rl_unix_line_discard }, /* Control-u */ - { ISFUNC, rl_quoted_insert }, /* Control-v */ - { ISFUNC, rl_unix_word_rubout }, /* Control-w */ - { ISFUNC, (Function *)0x0 }, /* Control-x */ - { ISFUNC, rl_yank }, /* Control-y */ - { ISFUNC, (Function *)0x0 }, /* Control-z */ - - { ISKMAP, (Function *)vi_escape_keymap }, /* Control-[ */ - { ISFUNC, (Function *)0x0 }, /* Control-\ */ - { ISFUNC, (Function *)0x0 }, /* Control-] */ - { ISFUNC, (Function *)0x0 }, /* Control-^ */ - { ISFUNC, rl_undo_command }, /* Control-_ */ - - /* The start of printing characters. */ - { ISFUNC, rl_forward }, /* SPACE */ - { ISFUNC, (Function *)0x0 }, /* ! */ - { ISFUNC, (Function *)0x0 }, /* " */ - { ISFUNC, rl_vi_comment }, /* # */ - { ISFUNC, rl_end_of_line }, /* $ */ - { ISFUNC, rl_vi_match }, /* % */ - { ISFUNC, (Function *)0x0 }, /* & */ - { ISFUNC, (Function *)0x0 }, /* ' */ - { ISFUNC, (Function *)0x0 }, /* ( */ - { ISFUNC, (Function *)0x0 }, /* ) */ - { ISFUNC, rl_vi_complete }, /* * */ - { ISFUNC, rl_get_next_history}, /* + */ - { ISFUNC, rl_vi_char_search }, /* , */ - { ISFUNC, rl_get_previous_history }, /* - */ - { ISFUNC, (Function *)0x0 }, /* . */ - { ISFUNC, rl_vi_search }, /* / */ - - /* Regular digits. */ - { ISFUNC, rl_vi_arg_digit }, /* 0 */ - { ISFUNC, rl_vi_arg_digit }, /* 1 */ - { ISFUNC, rl_vi_arg_digit }, /* 2 */ - { ISFUNC, rl_vi_arg_digit }, /* 3 */ - { ISFUNC, rl_vi_arg_digit }, /* 4 */ - { ISFUNC, rl_vi_arg_digit }, /* 5 */ - { ISFUNC, rl_vi_arg_digit }, /* 6 */ - { ISFUNC, rl_vi_arg_digit }, /* 7 */ - { ISFUNC, rl_vi_arg_digit }, /* 8 */ - { ISFUNC, rl_vi_arg_digit }, /* 9 */ - - /* A little more punctuation. */ - { ISFUNC, (Function *)0x0 }, /* : */ - { ISFUNC, rl_vi_char_search }, /* ; */ - { ISFUNC, (Function *)0x0 }, /* < */ - { ISFUNC, (Function *)0x0 }, /* = */ - { ISFUNC, (Function *)0x0 }, /* > */ - { ISFUNC, rl_vi_search }, /* ? */ - { ISFUNC, (Function *)0x0 }, /* @ */ - - /* Uppercase alphabet. */ - { ISFUNC, rl_vi_append_eol }, /* A */ - { ISFUNC, rl_vi_prev_word}, /* B */ - { ISFUNC, rl_vi_change_to }, /* C */ - { ISFUNC, rl_vi_delete_to }, /* D */ - { ISFUNC, rl_vi_end_word }, /* E */ - { ISFUNC, rl_vi_char_search }, /* F */ - { ISFUNC, (Function *)0x0 }, /* G */ - { ISFUNC, (Function *)0x0 }, /* H */ - { ISFUNC, rl_vi_insert_beg }, /* I */ - { ISFUNC, (Function *)0x0 }, /* J */ - { ISFUNC, (Function *)0x0 }, /* K */ - { ISFUNC, (Function *)0x0 }, /* L */ - { ISFUNC, (Function *)0x0 }, /* M */ - { ISFUNC, rl_vi_search_again }, /* N */ - { ISFUNC, (Function *)0x0 }, /* O */ - { ISFUNC, rl_vi_put }, /* P */ - { ISFUNC, (Function *)0x0 }, /* Q */ - { ISFUNC, rl_vi_replace }, /* R */ - { ISFUNC, rl_vi_subst }, /* S */ - { ISFUNC, rl_vi_char_search }, /* T */ - { ISFUNC, rl_revert_line }, /* U */ - { ISFUNC, (Function *)0x0 }, /* V */ - { ISFUNC, rl_vi_next_word }, /* W */ - { ISFUNC, rl_rubout }, /* X */ - { ISFUNC, rl_vi_yank_to }, /* Y */ - { ISFUNC, (Function *)0x0 }, /* Z */ - - /* Some more punctuation. */ - { ISFUNC, (Function *)0x0 }, /* [ */ - { ISFUNC, (Function *)0x0 }, /* \ */ - { ISFUNC, (Function *)0x0 }, /* ] */ - { ISFUNC, rl_vi_first_print }, /* ^ */ - { ISFUNC, rl_vi_yank_arg }, /* _ */ - { ISFUNC, (Function *)0x0 }, /* ` */ - - /* Lowercase alphabet. */ - { ISFUNC, rl_vi_append_mode }, /* a */ - { ISFUNC, rl_vi_prev_word }, /* b */ - { ISFUNC, rl_vi_change_to }, /* c */ - { ISFUNC, rl_vi_delete_to }, /* d */ - { ISFUNC, rl_vi_end_word }, /* e */ - { ISFUNC, rl_vi_char_search }, /* f */ - { ISFUNC, (Function *)0x0 }, /* g */ - { ISFUNC, rl_backward }, /* h */ - { ISFUNC, rl_vi_insertion_mode }, /* i */ - { ISFUNC, rl_get_next_history }, /* j */ - { ISFUNC, rl_get_previous_history }, /* k */ - { ISFUNC, rl_forward }, /* l */ - { ISFUNC, (Function *)0x0 }, /* m */ - { ISFUNC, rl_vi_search_again }, /* n */ - { ISFUNC, (Function *)0x0 }, /* o */ - { ISFUNC, rl_vi_put }, /* p */ - { ISFUNC, (Function *)0x0 }, /* q */ - { ISFUNC, rl_vi_change_char }, /* r */ - { ISFUNC, rl_vi_subst }, /* s */ - { ISFUNC, rl_vi_char_search }, /* t */ - { ISFUNC, rl_undo_command }, /* u */ - { ISFUNC, (Function *)0x0 }, /* v */ - { ISFUNC, rl_vi_next_word }, /* w */ - { ISFUNC, rl_vi_delete }, /* x */ - { ISFUNC, rl_vi_yank_to }, /* y */ - { ISFUNC, (Function *)0x0 }, /* z */ - - /* Final punctuation. */ - { ISFUNC, (Function *)0x0 }, /* { */ - { ISFUNC, rl_vi_column }, /* | */ - { ISFUNC, (Function *)0x0 }, /* } */ - { ISFUNC, rl_vi_change_case }, /* ~ */ - { ISFUNC, rl_backward } /* RUBOUT */ -}; - - -KEYMAP_ENTRY_ARRAY vi_insertion_keymap = { - - /* The regular control keys come first. */ - { ISFUNC, (Function *)0x0 }, /* Control-@ */ - { ISFUNC, rl_insert }, /* Control-a */ - { ISFUNC, rl_insert }, /* Control-b */ - { ISFUNC, rl_insert }, /* Control-c */ - { ISFUNC, rl_vi_eof_maybe }, /* Control-d */ - { ISFUNC, rl_insert }, /* Control-e */ - { ISFUNC, rl_insert }, /* Control-f */ - { ISFUNC, rl_insert }, /* Control-g */ - { ISFUNC, rl_rubout }, /* Control-h */ - { ISFUNC, rl_complete }, /* Control-i */ - { ISFUNC, rl_newline }, /* Control-j */ - { ISFUNC, rl_insert }, /* Control-k */ - { ISFUNC, rl_insert }, /* Control-l */ - { ISFUNC, rl_newline }, /* Control-m */ - { ISFUNC, rl_insert }, /* Control-n */ - { ISFUNC, rl_insert }, /* Control-o */ - { ISFUNC, rl_insert }, /* Control-p */ - { ISFUNC, rl_insert }, /* Control-q */ - { ISFUNC, (Function *)0x0 }, - { ISFUNC, (Function *)0x0 }, - { ISFUNC, rl_transpose_chars }, /* Control-t */ - { ISFUNC, rl_unix_line_discard }, /* Control-u */ - { ISFUNC, rl_quoted_insert }, /* Control-v */ - { ISFUNC, rl_unix_word_rubout }, /* Control-w */ - { ISFUNC, rl_insert }, /* Control-x */ - { ISFUNC, rl_yank }, /* Control-y */ - { ISFUNC, rl_insert }, /* Control-z */ - - { ISFUNC, rl_vi_movement_mode }, /* Control-[ */ - { ISFUNC, rl_insert }, /* Control-\ */ - { ISFUNC, rl_insert }, /* Control-] */ - { ISFUNC, rl_insert }, /* Control-^ */ - { ISFUNC, rl_undo_command }, /* Control-_ */ - - /* The start of printing characters. */ - { ISFUNC, rl_insert }, /* SPACE */ - { ISFUNC, rl_insert }, /* ! */ - { ISFUNC, rl_insert }, /* " */ - { ISFUNC, rl_insert }, /* # */ - { ISFUNC, rl_insert }, /* $ */ - { ISFUNC, rl_insert }, /* % */ - { ISFUNC, rl_insert }, /* & */ - { ISFUNC, rl_insert }, /* ' */ - { ISFUNC, rl_insert }, /* ( */ - { ISFUNC, rl_insert }, /* ) */ - { ISFUNC, rl_insert }, /* * */ - { ISFUNC, rl_insert }, /* + */ - { ISFUNC, rl_insert }, /* , */ - { ISFUNC, rl_insert }, /* - */ - { ISFUNC, rl_insert }, /* . */ - { ISFUNC, rl_insert }, /* / */ - - /* Regular digits. */ - { ISFUNC, rl_insert }, /* 0 */ - { ISFUNC, rl_insert }, /* 1 */ - { ISFUNC, rl_insert }, /* 2 */ - { ISFUNC, rl_insert }, /* 3 */ - { ISFUNC, rl_insert }, /* 4 */ - { ISFUNC, rl_insert }, /* 5 */ - { ISFUNC, rl_insert }, /* 6 */ - { ISFUNC, rl_insert }, /* 7 */ - { ISFUNC, rl_insert }, /* 8 */ - { ISFUNC, rl_insert }, /* 9 */ - - /* A little more punctuation. */ - { ISFUNC, rl_insert }, /* : */ - { ISFUNC, rl_insert }, /* ; */ - { ISFUNC, rl_insert }, /* < */ - { ISFUNC, rl_insert }, /* = */ - { ISFUNC, rl_insert }, /* > */ - { ISFUNC, rl_insert }, /* ? */ - { ISFUNC, rl_insert }, /* @ */ - - /* Uppercase alphabet. */ - { ISFUNC, rl_insert }, /* A */ - { ISFUNC, rl_insert }, /* B */ - { ISFUNC, rl_insert }, /* C */ - { ISFUNC, rl_insert }, /* D */ - { ISFUNC, rl_insert }, /* E */ - { ISFUNC, rl_insert }, /* F */ - { ISFUNC, rl_insert }, /* G */ - { ISFUNC, rl_insert }, /* H */ - { ISFUNC, rl_insert }, /* I */ - { ISFUNC, rl_insert }, /* J */ - { ISFUNC, rl_insert }, /* K */ - { ISFUNC, rl_insert }, /* L */ - { ISFUNC, rl_insert }, /* M */ - { ISFUNC, rl_insert }, /* N */ - { ISFUNC, rl_insert }, /* O */ - { ISFUNC, rl_insert }, /* P */ - { ISFUNC, rl_insert }, /* Q */ - { ISFUNC, rl_insert }, /* R */ - { ISFUNC, rl_insert }, /* S */ - { ISFUNC, rl_insert }, /* T */ - { ISFUNC, rl_insert }, /* U */ - { ISFUNC, rl_insert }, /* V */ - { ISFUNC, rl_insert }, /* W */ - { ISFUNC, rl_insert }, /* X */ - { ISFUNC, rl_insert }, /* Y */ - { ISFUNC, rl_insert }, /* Z */ - - /* Some more punctuation. */ - { ISFUNC, rl_insert }, /* [ */ - { ISFUNC, rl_insert }, /* \ */ - { ISFUNC, rl_insert }, /* ] */ - { ISFUNC, rl_insert }, /* ^ */ - { ISFUNC, rl_insert }, /* _ */ - { ISFUNC, rl_insert }, /* ` */ - - /* Lowercase alphabet. */ - { ISFUNC, rl_insert }, /* a */ - { ISFUNC, rl_insert }, /* b */ - { ISFUNC, rl_insert }, /* c */ - { ISFUNC, rl_insert }, /* d */ - { ISFUNC, rl_insert }, /* e */ - { ISFUNC, rl_insert }, /* f */ - { ISFUNC, rl_insert }, /* g */ - { ISFUNC, rl_insert }, /* h */ - { ISFUNC, rl_insert }, /* i */ - { ISFUNC, rl_insert }, /* j */ - { ISFUNC, rl_insert }, /* k */ - { ISFUNC, rl_insert }, /* l */ - { ISFUNC, rl_insert }, /* m */ - { ISFUNC, rl_insert }, /* n */ - { ISFUNC, rl_insert }, /* o */ - { ISFUNC, rl_insert }, /* p */ - { ISFUNC, rl_insert }, /* q */ - { ISFUNC, rl_insert }, /* r */ - { ISFUNC, rl_insert }, /* s */ - { ISFUNC, rl_insert }, /* t */ - { ISFUNC, rl_insert }, /* u */ - { ISFUNC, rl_insert }, /* v */ - { ISFUNC, rl_insert }, /* w */ - { ISFUNC, rl_insert }, /* x */ - { ISFUNC, rl_insert }, /* y */ - { ISFUNC, rl_insert }, /* z */ - - /* Final punctuation. */ - { ISFUNC, rl_insert }, /* { */ - { ISFUNC, rl_insert }, /* | */ - { ISFUNC, rl_insert }, /* } */ - { ISFUNC, rl_insert }, /* ~ */ - { ISFUNC, rl_rubout } /* RUBOUT */ -}; - -KEYMAP_ENTRY_ARRAY vi_escape_keymap = { - - /* The regular control keys come first. */ - { ISFUNC, (Function *)0x0 }, /* Control-@ */ - { ISFUNC, (Function *)0x0 }, /* Control-a */ - { ISFUNC, (Function *)0x0 }, /* Control-b */ - { ISFUNC, (Function *)0x0 }, /* Control-c */ - { ISFUNC, (Function *)0x0 }, /* Control-d */ - { ISFUNC, (Function *)0x0 }, /* Control-e */ - { ISFUNC, (Function *)0x0 }, /* Control-f */ - { ISFUNC, (Function *)0x0 }, /* Control-g */ - { ISFUNC, (Function *)0x0 }, /* Control-h */ - { ISFUNC, rl_tab_insert}, /* Control-i */ - { ISFUNC, rl_emacs_editing_mode}, /* Control-j */ - { ISFUNC, rl_kill_line }, /* Control-k */ - { ISFUNC, (Function *)0x0 }, /* Control-l */ - { ISFUNC, rl_emacs_editing_mode}, /* Control-m */ - { ISFUNC, (Function *)0x0 }, /* Control-n */ - { ISFUNC, (Function *)0x0 }, /* Control-o */ - { ISFUNC, (Function *)0x0 }, /* Control-p */ - { ISFUNC, (Function *)0x0 }, /* Control-q */ - { ISFUNC, (Function *)0x0 }, /* Control-r */ - { ISFUNC, (Function *)0x0 }, /* Control-s */ - { ISFUNC, (Function *)0x0 }, /* Control-t */ - { ISFUNC, (Function *)0x0 }, /* Control-u */ - { ISFUNC, (Function *)0x0 }, /* Control-v */ - { ISFUNC, (Function *)0x0 }, /* Control-w */ - { ISFUNC, (Function *)0x0 }, /* Control-x */ - { ISFUNC, (Function *)0x0 }, /* Control-y */ - { ISFUNC, (Function *)0x0 }, /* Control-z */ - - { ISFUNC, rl_vi_movement_mode }, /* Control-[ */ - { ISFUNC, (Function *)0x0 }, /* Control-\ */ - { ISFUNC, (Function *)0x0 }, /* Control-] */ - { ISFUNC, (Function *)0x0 }, /* Control-^ */ - { ISFUNC, rl_undo_command }, /* Control-_ */ - - /* The start of printing characters. */ - { ISFUNC, (Function *)0x0 }, /* SPACE */ - { ISFUNC, (Function *)0x0 }, /* ! */ - { ISFUNC, (Function *)0x0 }, /* " */ - { ISFUNC, (Function *)0x0 }, /* # */ - { ISFUNC, (Function *)0x0 }, /* $ */ - { ISFUNC, (Function *)0x0 }, /* % */ - { ISFUNC, (Function *)0x0 }, /* & */ - { ISFUNC, (Function *)0x0 }, /* ' */ - { ISFUNC, (Function *)0x0 }, /* ( */ - { ISFUNC, (Function *)0x0 }, /* ) */ - { ISFUNC, (Function *)0x0 }, /* * */ - { ISFUNC, (Function *)0x0 }, /* + */ - { ISFUNC, (Function *)0x0 }, /* , */ - { ISFUNC, (Function *)0x0 }, /* - */ - { ISFUNC, (Function *)0x0 }, /* . */ - { ISFUNC, (Function *)0x0 }, /* / */ - - /* Regular digits. */ - { ISFUNC, rl_vi_arg_digit }, /* 0 */ - { ISFUNC, rl_vi_arg_digit }, /* 1 */ - { ISFUNC, rl_vi_arg_digit }, /* 2 */ - { ISFUNC, rl_vi_arg_digit }, /* 3 */ - { ISFUNC, rl_vi_arg_digit }, /* 4 */ - { ISFUNC, rl_vi_arg_digit }, /* 5 */ - { ISFUNC, rl_vi_arg_digit }, /* 6 */ - { ISFUNC, rl_vi_arg_digit }, /* 7 */ - { ISFUNC, rl_vi_arg_digit }, /* 8 */ - { ISFUNC, rl_vi_arg_digit }, /* 9 */ - - /* A little more punctuation. */ - { ISFUNC, (Function *)0x0 }, /* : */ - { ISFUNC, (Function *)0x0 }, /* ; */ - { ISFUNC, (Function *)0x0 }, /* < */ - { ISFUNC, (Function *)0x0 }, /* = */ - { ISFUNC, (Function *)0x0 }, /* > */ - { ISFUNC, (Function *)0x0 }, /* ? */ - { ISFUNC, (Function *)0x0 }, /* @ */ - - /* Uppercase alphabet. */ - { ISFUNC, rl_do_lowercase_version }, /* A */ - { ISFUNC, rl_do_lowercase_version }, /* B */ - { ISFUNC, rl_do_lowercase_version }, /* C */ - { ISFUNC, rl_do_lowercase_version }, /* D */ - { ISFUNC, rl_do_lowercase_version }, /* E */ - { ISFUNC, rl_do_lowercase_version }, /* F */ - { ISFUNC, rl_do_lowercase_version }, /* G */ - { ISFUNC, rl_do_lowercase_version }, /* H */ - { ISFUNC, rl_do_lowercase_version }, /* I */ - { ISFUNC, rl_do_lowercase_version }, /* J */ - { ISFUNC, rl_do_lowercase_version }, /* K */ - { ISFUNC, rl_do_lowercase_version }, /* L */ - { ISFUNC, rl_do_lowercase_version }, /* M */ - { ISFUNC, rl_do_lowercase_version }, /* N */ - { ISFUNC, rl_do_lowercase_version }, /* O */ - { ISFUNC, rl_do_lowercase_version }, /* P */ - { ISFUNC, rl_do_lowercase_version }, /* Q */ - { ISFUNC, rl_do_lowercase_version }, /* R */ - { ISFUNC, rl_do_lowercase_version }, /* S */ - { ISFUNC, rl_do_lowercase_version }, /* T */ - { ISFUNC, rl_do_lowercase_version }, /* U */ - { ISFUNC, rl_do_lowercase_version }, /* V */ - { ISFUNC, rl_do_lowercase_version }, /* W */ - { ISFUNC, rl_do_lowercase_version }, /* X */ - { ISFUNC, rl_do_lowercase_version }, /* Y */ - { ISFUNC, rl_do_lowercase_version }, /* Z */ - - /* Some more punctuation. */ - { ISFUNC, (Function *)0x0 }, /* [ */ - { ISFUNC, (Function *)0x0 }, /* \ */ - { ISFUNC, (Function *)0x0 }, /* ] */ - { ISFUNC, (Function *)0x0 }, /* ^ */ - { ISFUNC, (Function *)0x0 }, /* _ */ - { ISFUNC, (Function *)0x0 }, /* ` */ - - /* Lowercase alphabet. */ - { ISFUNC, (Function *)0x0 }, /* a */ - { ISFUNC, (Function *)0x0 }, /* b */ - { ISFUNC, (Function *)0x0 }, /* c */ - { ISFUNC, (Function *)0x0 }, /* d */ - { ISFUNC, (Function *)0x0 }, /* e */ - { ISFUNC, (Function *)0x0 }, /* f */ - { ISFUNC, (Function *)0x0 }, /* g */ - { ISFUNC, (Function *)0x0 }, /* h */ - { ISFUNC, (Function *)0x0 }, /* i */ - { ISFUNC, (Function *)0x0 }, /* j */ - { ISFUNC, (Function *)0x0 }, /* k */ - { ISFUNC, (Function *)0x0 }, /* l */ - { ISFUNC, (Function *)0x0 }, /* m */ - { ISFUNC, (Function *)0x0 }, /* n */ - { ISFUNC, (Function *)0x0 }, /* o */ - { ISFUNC, (Function *)0x0 }, /* p */ - { ISFUNC, (Function *)0x0 }, /* q */ - { ISFUNC, (Function *)0x0 }, /* r */ - { ISFUNC, (Function *)0x0 }, /* s */ - { ISFUNC, (Function *)0x0 }, /* t */ - { ISFUNC, (Function *)0x0 }, /* u */ - { ISFUNC, (Function *)0x0 }, /* v */ - { ISFUNC, (Function *)0x0 }, /* w */ - { ISFUNC, (Function *)0x0 }, /* x */ - { ISFUNC, (Function *)0x0 }, /* y */ - { ISFUNC, (Function *)0x0 }, /* z */ - - /* Final punctuation. */ - { ISFUNC, (Function *)0x0 }, /* { */ - { ISFUNC, (Function *)0x0 }, /* | */ - { ISFUNC, (Function *)0x0 }, /* } */ - { ISFUNC, (Function *)0x0 }, /* ~ */ - { ISFUNC, rl_backward_kill_word } /* RUBOUT */ -}; End of readline/vi_keymap.c echo readline/vi_mode.c 1>&2 sed 's/^-//' >readline/vi_mode.c <<'End of readline/vi_mode.c' -/* vi_mode.c -- A vi emulation mode for Bash. - - Derived from code written by Jeff Sparkes (jeff1@????). - */ - - -/* **************************************************************** */ -/* */ -/* VI Emulation Mode */ -/* */ -/* **************************************************************** */ - -/* Last string searched for from `/' or `?'. */ -static char *vi_last_search = (char *)NULL; -static int vi_histpos; - -/* Non-zero means enter insertion mode. */ -int vi_doing_insert = 0; - -/* *** UNCLEAN *** */ -/* Command keys which do movement for xxx_to commands. */ -static char *vi_motion = " hl^$0ftFt;,%wbeWBE|"; - -/* Keymap used for vi replace characters. Created dynamically since - rarely used. */ -static Keymap vi_replace_map = (Keymap)NULL; - -/* The number of characters inserted in the last replace operation. */ -static vi_replace_count = 0; - -/* Yank the nth arg from the previous line into this line at point. */ -rl_vi_yank_arg (count) - int count; -{ - rl_yank_nth_arg (count, 0); -} - -/* Search again for the last thing searched for. */ -rl_vi_search_again (ignore, key) - int ignore, key; -{ - switch (key) - { - case 'n': - rl_vi_dosearch (vi_last_search, -1); - break; - - case 'N': - rl_vi_dosearch (vi_last_search, 1); - break; - } -} - -/* Do a vi style search. */ -rl_vi_search (count, key) - int count, key; -{ - int dir, c, save_pos; - char *p; - - switch (key) - { - case '?': - dir = 1; - break; - - case '/': - dir = -1; - break; - - default: - ding (); - return; - } - - vi_histpos = where_history (); - maybe_save_line (); - save_pos = rl_point; - - /* Reuse the line input buffer to read the search string. */ - the_line[0] = 0; - rl_end = rl_point = 0; - p = (char *)alloca (2 + (rl_prompt ? strlen (rl_prompt) : 0)); - - sprintf (p, "%s%c", rl_prompt ? rl_prompt : "", key); - - rl_message (p, 0, 0); - - while (c = rl_read_key ()) - { - switch (c) - { - case CTRL('H'): - case RUBOUT: - if (rl_point == 0) - { - maybe_unsave_line (); - rl_clear_message (); - rl_point = save_pos; - return; - } - - case CTRL('W'): - case CTRL('U'): - rl_dispatch (c, keymap); - break; - - case ESC: - case RETURN: - case NEWLINE: - goto dosearch; - break; - - case CTRL('C'): - maybe_unsave_line (); - rl_clear_message (); - rl_point = 0; - ding (); - return; - - default: - rl_insert (1, c); - break; - } - rl_redisplay (); - } - dosearch: - if (vi_last_search) - free (vi_last_search); - - vi_last_search = savestring (the_line); - rl_vi_dosearch (the_line, dir); -} - -rl_vi_dosearch (string, dir) - char *string; - int dir; -{ -#ifdef 0 - int old, save = vi_histpos; - HIST_ENTRY *h; - - if (string == 0 || *string == 0 || vi_histpos < 0) - { - ding (); - return; - } - - if ((save = history_search_pos (string, dir, vi_histpos + dir)) == -1) - { - maybe_unsave_line (); - rl_clear_message (); - rl_point = 0; - ding (); - return; - } - - vi_histpos = save; - - old = where_history (); - history_set_pos (vi_histpos); - h = current_history (); - history_set_pos (old); - - strcpy (the_line, h->line); - rl_undo_list = (UNDO_LIST *)h->data; - rl_end = strlen (the_line); - rl_point = 0; - rl_clear_message (); -#endif -} - -/* Completion, from vi's point of view. */ -rl_vi_complete (ignore, key) - int ignore, key; -{ - if (!whitespace (the_line[rl_point])) - { - if (!whitespace (the_line[rl_point + 1])) - rl_vi_end_word (1, 'E'); - rl_point++; - } - - if (key == '*') - rl_complete_internal ('*'); - else - rl_complete (0, key); - - rl_vi_insertion_mode (); -} - -/* Previous word in vi mode. */ -rl_vi_prev_word (count, key) - int count, key; -{ - if (count < 0) - { - rl_vi_next_word (-count, key); - return; - } - - if (uppercase_p (key)) - rl_vi_bWord (count); - else - rl_vi_bword (count); -} - -/* Next word in vi mode. */ -rl_vi_next_word (count, key) - int count; -{ - if (count < 0) - { - rl_vi_prev_word (-count, key); - return; - } - - if (uppercase_p (key)) - rl_vi_fWord (count); - else - rl_vi_fword (count); -} - -/* Move to the end of the ?next? word. */ -rl_vi_end_word (count, key) - int count, key; -{ - if (count < 0) - { - ding (); - return; - } - - if (uppercase_p (key)) - rl_vi_eWord (count); - else - rl_vi_eword (count); -} - -/* Move forward a word the way that 'W' does. */ -rl_vi_fWord (count) - int count; -{ - while (count-- && rl_point < (rl_end - 1)) - { - /* Skip until whitespace. */ - while (!whitespace (the_line[rl_point]) && rl_point < rl_end) - rl_point++; - - /* Now skip whitespace. */ - while (whitespace (the_line[rl_point]) && rl_point < rl_end) - rl_point++; - } -} - -rl_vi_bWord (count) - int count; -{ - while (count-- && rl_point > 0) - { - while (rl_point-- >= 0 && whitespace (the_line[rl_point])); - while (rl_point >= 0 && !whitespace (the_line[rl_point])) - rl_point--; - rl_point++; - } -} - -rl_vi_eWord (count) - int count; -{ - while (count -- && rl_point < (rl_end - 1)) - { - while (rl_point++ < rl_end && whitespace (the_line[rl_point])); - while (rl_point++ < rl_end && !whitespace (the_line[rl_point])); - rl_point--; - } -} - -rl_vi_fword (count) - int count; -{ - while (count -- && rl_point < (rl_end - 1)) - { - if (isident (the_line[rl_point])) - { - while (isident (the_line[rl_point]) && rl_point < rl_end) - rl_point += 1; - } - else if (!whitespace (the_line[rl_point])) - { - while (!isident (the_line[rl_point]) && - !whitespace (the_line[rl_point]) && rl_point < rl_end) - rl_point += 1; - } - - while (whitespace (the_line[rl_point]) && rl_point < rl_end) - rl_point++; - } -} - -rl_vi_bword (count) - int count; -{ - while (count -- && rl_point > 0) - { - while (--rl_point > 0 && whitespace (the_line[rl_point])); - if (rl_point > 0) - { - if (isident (the_line[rl_point])) - while (--rl_point >= 0 && isident (the_line[rl_point])); - else - while (--rl_point >= 0 && !isident (the_line[rl_point]) && - !whitespace (the_line[rl_point])); - rl_point++; - } - } -} - -rl_vi_eword (count) - int count; -{ - while (count -- && rl_point < rl_end - 1) - { - while (++rl_point < rl_end && whitespace (the_line[rl_point])); - - if (rl_point < rl_end) - { - if (isident (the_line[rl_point])) - while (++rl_point < rl_end && isident (the_line[rl_point])); - else - while (++rl_point < rl_end && !isident (the_line[rl_point]) - && !whitespace (the_line[rl_point])); - rl_point--; - } - } -} - -rl_vi_insert_beg () -{ - rl_beg_of_line (); - rl_vi_insertion_mode (); - return 0; -} - -rl_vi_append_mode () -{ - if (rl_point < rl_end) - rl_point += 1; - rl_vi_insertion_mode (); - return 0; -} - -rl_vi_append_eol () -{ - rl_end_of_line (); - rl_vi_append_mode (); - return 0; -} - -/* What to do in the case of C-d. */ -rl_vi_eof_maybe (count, c) - int count, c; -{ - rl_newline (1, '\n'); -} - -/* Insertion mode stuff. */ - -/* Switching from one mode to the other really just involves - switching keymaps. */ -rl_vi_insertion_mode () -{ - keymap = vi_insertion_keymap; -} - -rl_vi_movement_mode () -{ - if (rl_point > 0) - rl_backward (1); - - keymap = vi_movement_keymap; - vi_done_inserting (); -} - -vi_done_inserting () -{ - if (vi_doing_insert) - { - rl_end_undo_group (); - vi_doing_insert = 0; - } -} - -rl_vi_arg_digit (count, c) - int count, c; -{ - if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg) - rl_beg_of_line (); - else - rl_digit_argument (count, c); -} - -/* Doesn't take an arg count in vi */ -rl_vi_change_case (ignore1, ignore2) - int ignore1, ignore2; -{ - char c = 0; - - if (uppercase_p (the_line[rl_point])) - c = to_lower (the_line[rl_point]); - else if (lowercase_p (the_line[rl_point])) - c = to_upper (the_line[rl_point]); - - /* Vi is kind of strange here. */ - if (c) - { - rl_begin_undo_group (); - rl_delete (1, c); - rl_insert (1, c); - rl_end_undo_group (); - rl_vi_check (); - } - else - rl_forward (1); -} - -rl_vi_put (count, key) - int count, key; -{ - if (!uppercase_p (key)) - rl_forward (1); - - rl_yank (); - rl_backward (1); -} - -rl_vi_check () -{ - if (rl_point && rl_point == rl_end) - rl_point--; -} - -rl_vi_column (count) -{ - if (count > rl_end) - rl_end_of_line (); - else - rl_point = count - 1; -} - -int -rl_vi_domove (key, nextkey) - int key, *nextkey; -{ - int c, save; - - rl_mark = rl_point; - c = rl_read_key (); - *nextkey = c; - - if (!member (c, vi_motion)) - { - if (digit (c)) - { - save = rl_numeric_arg; - rl_digit_loop1 (); - rl_numeric_arg *= save; - } - else if ((key == 'd' && c == 'd') || - (key == 'c' && c == 'c')) - { - rl_mark = rl_end; - rl_beg_of_line (); - return (0); - } - else - return (-1); - } - - rl_dispatch (c, keymap); - - /* No change in position means the command failed. */ - if (rl_mark == rl_point) - return (-1); - - if ((c == 'w' || c == 'W') && rl_point < rl_end) - rl_point--; - - if (rl_mark < rl_point) - exchange (rl_point, rl_mark); - - return (0); -} - -/* A simplified loop for vi. Don't dispatch key at end. - Don't recognize minus sign? */ -rl_digit_loop1 () -{ - int key, c; - - while (1) - { - rl_message ("(arg: %d) ", arg_sign * rl_numeric_arg, 0); - key = c = rl_read_key (); - - if (keymap[c].type == ISFUNC && - keymap[c].function == rl_universal_argument) - { - rl_numeric_arg *= 4; - continue; - } - c = UNMETA (c); - if (numeric (c)) - { - if (rl_explicit_arg) - rl_numeric_arg = (rl_numeric_arg * 10) + (c - '0'); - else - rl_numeric_arg = (c - '0'); - rl_explicit_arg = 1; - } - else - { - rl_clear_message (); - rl_stuff_char (key); - } - } -} - -rl_vi_delete_to (count, key) - int count, key; -{ - int c; - - if (uppercase_p (key)) - rl_stuff_char ('$'); - - if (rl_vi_domove (key, &c)) - { - ding (); - return; - } - - if ((c != '|') && (c != 'h') && rl_mark < rl_end) - rl_mark++; - - rl_kill_text (rl_point, rl_mark); -} - -rl_vi_change_to (count, key) - int count, key; -{ - int c; - - if (uppercase_p (key)) - rl_stuff_char ('$'); - - if (rl_vi_domove (key, &c)) - { - ding (); - return; - } - - if ((c != '|') && (c != 'h') && rl_mark < rl_end) - rl_mark++; - - rl_begin_undo_group (); - vi_doing_insert = 1; - rl_kill_text (rl_point, rl_mark); - rl_vi_insertion_mode (); -} - -rl_vi_yank_to (count, key) - int count, key; -{ - int c, save = rl_point; - - if (uppercase_p (key)) - rl_stuff_char ('$'); - - if (rl_vi_domove (key, &c)) - { - ding (); - return; - } - - rl_begin_undo_group (); - rl_kill_text (rl_point, rl_mark); - rl_end_undo_group (); - rl_do_undo (); - rl_point = save; -} - -rl_vi_delete (count) -{ - if (rl_point >= rl_end - 1) - { - rl_delete (count, 0); - if (rl_point > 0) - rl_backward (1); - } - else - rl_delete (count, 0); -} - -/* Turn the current line into a comment in shell history. A ksh function */ -rl_vi_comment () -{ - rl_beg_of_line (); - rl_insert_text (": "); /* # doesn't work in interactive mode */ - rl_redisplay (); - rl_newline (1, '\010'); -} - -rl_vi_first_print () -{ - rl_back_to_indent (); -} - -rl_back_to_indent (ignore1, ignore2) - int ignore1, ignore2; -{ - rl_beg_of_line (); - while (rl_point < rl_end && whitespace (the_line[rl_point])) - rl_point++; -} - -/* NOTE: it is necessary that opposite directions are inverses */ -#define FTO 1 /* forward to */ -#define BTO -1 /* backward to */ -#define FFIND 2 /* forward find */ -#define BFIND -2 /* backward find */ - -rl_vi_char_search (count, key) - int count, key; -{ - static char target; - static int orig_dir, dir; - int pos; - - if (key == ';' || key == ',') - dir = (key == ';' ? orig_dir : -orig_dir); - else - { - target = rl_getc (in_stream); - - switch (key) - { - case 't': - orig_dir = dir = FTO; - break; - - case 'T': - orig_dir = dir = BTO; - break; - - case 'f': - orig_dir = dir = FFIND; - break; - - case 'F': - orig_dir = dir = BFIND; - break; - } - } - - pos = rl_point; - - if (dir < 0) - { - pos--; - do - { - if (the_line[pos] == target) - { - if (dir == BTO) - rl_point = pos + 1; - else - rl_point = pos; - return; - } - } - while (pos--); - - if (pos < 0) - { - ding (); - return; - } - } - else - { /* dir > 0 */ - pos++; - do - { - if (the_line[pos] == target) - { - if (dir == FTO) - rl_point = pos - 1; - else - rl_point = pos; - return; - } - } - while (++pos < rl_end); - - if (pos >= (rl_end - 1)) - ding (); - } -} - -/* Match brackets */ -rl_vi_match () -{ - int count = 1, brack, pos; - - pos = rl_point; - if ((brack = rl_vi_bracktype (the_line[rl_point])) == 0) - { - while ((brack = rl_vi_bracktype (the_line[rl_point])) == 0 && - rl_point < rl_end - 1) - rl_forward (1); - - if (brack <= 0) - { - rl_point = pos; - ding (); - return; - } - } - - pos = rl_point; - - if (brack < 0) - { - while (count) - { - if (--pos >= 0) - { - int b = rl_vi_bracktype (the_line[pos]); - if (b == -brack) - count--; - else if (b == brack) - count++; - } - else - { - ding (); - return; - } - } - } - else - { /* brack > 0 */ - while (count) - { - if (++pos < rl_end) - { - int b = rl_vi_bracktype (the_line[pos]); - if (b == -brack) - count--; - else if (b == brack) - count++; - } - else - { - ding (); - return; - } - } - } - rl_point = pos; -} - -int -rl_vi_bracktype (c) - int c; -{ - switch (c) - { - case '(': return 1; - case ')': return -1; - case '[': return 2; - case ']': return -2; - case '{': return 3; - case '}': return -3; - default: return 0; - } -} - -rl_vi_change_char () -{ - int c; - - c = rl_getc (in_stream); - - switch (c) - { - case '\033': - case CTRL('C'): - return; - - default: - rl_begin_undo_group (); - rl_delete (1, c); - rl_insert (1, c); - rl_end_undo_group (); - break; - } -} - -rl_vi_subst (count, key) - int count, key; -{ - rl_begin_undo_group (); - vi_doing_insert = 1; - - if (uppercase_p (key)) - { - rl_beg_of_line (); - rl_kill_line (1); - } - else - rl_delete (1, key); - - rl_vi_insertion_mode (); -} - -rl_vi_overstrike (count, key) - int count, key; -{ - int i; - - if (vi_doing_insert == 0) - { - vi_doing_insert = 1; - rl_begin_undo_group (); - } - - for (i = 0; i < count; i++) - { - vi_replace_count++; - rl_begin_undo_group (); - - if (rl_point < rl_end) - { - rl_delete (1, key); - rl_insert (1, key); - } - else - rl_insert (1, key); - - rl_end_undo_group (); - } -} - -rl_vi_overstrike_delete (count) - int count; -{ - int i, s; - - for (i = 0; i < count; i++) - { - if (vi_replace_count == 0) - { - ding (); - break; - } - s = rl_point; - - if (rl_do_undo ()) - vi_replace_count--; - - if (rl_point == s) - rl_backward (1); - } - - if (vi_replace_count == 0 && vi_doing_insert) - { - rl_end_undo_group (); - rl_do_undo (); - vi_doing_insert = 0; - } -} - -rl_vi_replace () -{ - int i; - - vi_replace_count = 0; - - vi_replace_map = rl_make_bare_keymap (); - - for (i = ' '; i < 127; i++) - vi_replace_map[i].function = rl_vi_overstrike; - - vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete; - vi_replace_map[ESC].function = rl_vi_movement_mode; - vi_replace_map[RETURN].function = rl_newline; - vi_replace_map[NEWLINE].function = rl_newline; - keymap = vi_replace_map; -} - -/* - * Try to complete the word we are standing on or the word that ends with - * the previous character. A space matches everything. - * Word delimiters are space and ;. - */ -rl_vi_possible_completions() -{ - int save_pos = rl_point; - - if (!index (" ;", the_line[rl_point])) - { - while (!index(" ;", the_line[++rl_point])) - ; - } - else if (the_line[rl_point-1] == ';') - { - ding (); - return (0); - } - - rl_possible_completions (); - rl_point = save_pos; - - return (0); -} End of readline/vi_mode.c echo readline/Makefile 1>&2 sed 's/^-//' >readline/Makefile <<'End of readline/Makefile' -## -*- text -*- #################################################### -# # -# Makefile for readline and history libraries. # -# # -#################################################################### - -# Here is a rule for making .o files from .c files that doesn't force -# the type of the machine (like -sun3) into the flags. -.c.o: - $(CC) -c $(CFLAGS) $(LOCAL_INCLUDES) $(CPPFLAGS) $*.c - -# Destination installation directory. The libraries are copied to DESTDIR -# when you do a `make install', and the header files to INCDIR/readline/*.h. -DESTDIR = /usr/gnu/lib -INCDIR = /usr/gnu/include - -# Define TYPES as -DVOID_SIGHANDLER if your operating system uses -# a return type of "void" for signal handlers. -TYPES = -DVOID_SIGHANDLER - -# Define SYSV as -DSYSV if you are using a System V operating system. -#SYSV = -DSYSV - -# HP-UX compilation requires the BSD library. -#LOCAL_LIBS = -lBSD - -# Xenix compilation requires -ldir -lx -#LOCAL_LIBS = -ldir -lx - -# Comment this out if you don't think that anyone will ever desire -# the vi line editing mode and features. -READLINE_DEFINES = -DVI_MODE - -DEBUG_FLAGS = -LDFLAGS = $(DEBUG_FLAGS) -CFLAGS = $(DEBUG_FLAGS) $(TYPE) $(SYSV) -I. - -# A good alternative is gcc -traditional. -CC = gcc -traditional -RANLIB = /usr/bin/ranlib -AR = ar -RM = rm -CP = cp - -LOCAL_INCLUDES = -I../ - -CSOURCES = readline.c history.c funmap.c keymaps.c vi_mode.c \ - emacs_keymap.c vi_keymap.c keymaps.c - -HSOURCES = readline.h chardefs.h history.h keymaps.h -SOURCES = $(CSOURCES) $(HSOURCES) - -DOCUMENTATION = readline.texinfo inc-readline.texinfo \ - history.texinfo inc-history.texinfo - -SUPPORT = COPYING Makefile $(DOCUMENTATION) ChangeLog - -THINGS_TO_TAR = $(SOURCES) $(SUPPORT) - -########################################################################## - -all: readline.o funmap.o keymaps.o -# all: libreadline.a - -libreadline.a: readline.o history.o funmap.o keymaps.o - $(RM) -f libreadline.a - $(AR) clq libreadline.a readline.o history.o funmap.o keymaps.o - -if [ -f $(RANLIB) ]; then $(RANLIB) libreadline.a; fi - -readline.o: readline.h chardefs.h keymaps.h history.h readline.c vi_mode.c - $(CC) -c $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \ - $(LOCAL_INCLUDES) $*.c - -history.o: history.c history.h - $(CC) -c $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \ - $(LOCAL_INCLUDES) $*.c - -funmap.o: readline.h - $(CC) -c $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \ - $(LOCAL_INCLUDES) $*.c - -keymaps.o: emacs_keymap.c vi_keymap.c keymaps.h chardefs.h keymaps.c - $(CC) -c $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \ - $(LOCAL_INCLUDES) $*.c - -libtest: libreadline.a libtest.c - $(CC) -o libtest $(CFLAGS) $(CPPFLAGS) -L. libtest.c -lreadline -ltermcap - -readline: readline.c history.o keymaps.o funmap.o readline.h chardefs.h - $(CC) $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \ - $(LOCAL_INCLUDES) -DTEST -o readline readline.c funmap.o \ - keymaps.o history.o -L. -ltermcap - -readline.tar: $(THINGS_TO_TAR) - tar -cf readline.tar $(THINGS_TO_TAR) - -readline.tar.Z: readline.tar - compress -f readline.tar - -install: $(DESTDIR)/libreadline.a includes - -includes: - if [ ! -r $(INCDIR)/readline ]; then\ - mkdir $(INCDIR)/readline;\ - chmod a+r $(INCDIR)/readline;\ - fi - $(CP) readline.h keymaps.h chardefs.h $(INCDIR)/readline/ -clean: - rm -f *.o *.a *.log *.cp *.tp *.vr *.fn *.aux *.pg *.toc - -$(DESTDIR)/libreadline.a: libreadline.a - -mv $(DESTDIR)/libreadline.a $(DESTDIR)/libreadline.old - cp libreadline.a $(DESTDIR)/libreadline.a - $(RANLIB) -t $(DESTDIR)/libreadline.a End of readline/Makefile echo zsh.h 1>&2 sed 's/^-//' >zsh.h <<'End of zsh.h' -/* - - zsh.h - the header file, basically - - This file is part of zsh, the Z shell. - - zsh is free software; no one can prevent you from reading the source - code, or giving it to someone else. - This file is copyrighted under the GNU General Public License, which - can be found in the file called COPYING. - - Copyright (C) 1990 Paul Falstad - - zsh is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY. No author or distributor accepts - responsibility to anyone for the consequences of using it or for - whether it serves any particular purpose or works at all, unless he - says so in writing. Refer to the GNU General Public License - for full details. - - Everyone is granted permission to copy, modify and redistribute - zsh, but only under the conditions described in the GNU General Public - License. A copy of this license is supposed to have been given to you - along with zsh so you can know your rights and responsibilities. - It should be in a file named COPYING. - - Among other things, the copyright notice and this notice must be - preserved on all copies. - -*/ - -#include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef TERMIOS -#include -#else -#include -#endif -#include -#include - -#define VERSIONSTR "zsh v1.0" - -#define FOREVER for(;;) - -/* size of job table */ - -#define MAXJOB 16 - -void *realloc(void *,int),*malloc(int),*calloc(int,int); - -char *getenv(char *); - -/* the tokens */ - -enum xfubar { - HQUOT = -127, /* quote char used for history */ - ALPOP, /* marker, causes parser to pop alias stack */ - HERR, /* history error indicator */ - Pound, /* # */ - String, /* $ */ - Hat, /* ^ */ - Star, /* * */ - Inpar, /* ( */ - Outpar, /* ) */ - Qstring, /* $, in quotes */ - Equals, /* = (initial) */ - Bar, /* |, except when used as a pipe char */ - Inbrace, /* {, except when used for current shells */ - Outbrace, /* }, except when used for current shells */ - Inbrack, /* [ */ - Outbrack, /* ] */ - Tick, /* ` */ - Inang, /* <, except when used for redirection */ - Outang, /* >, except when used for redirection */ - Quest, /* ? */ - Tilde, /* ~ (initial) */ - Qtick, /* `, in quotes */ - Comma, /* , */ - Nularg /* marker, keeps explicit null arguments around, - does some other stuff */ - }; - -/* HQUOT separately defined in readline.c */ - -/* returns true if X is a token */ - -#define istok(X) (((char) (X)) <= Nularg) - -/* HQUOT in the form of a string */ - -#define HQUOTS "\x81" - -/* ALPOP in the form of a string */ - -#define ALPOPS " \x82" - -extern char **environ; - -/* list of tokens */ - -extern char *tokens; - -/* tokens used in peek variable with gettok/matchit */ -/* do not confuse with above tokens; above tokens appear in strings, - following tokens possible values of 'peek' variable */ - -enum xpeek { - EMPTY, /* nothing gotten yet */ - SEMI, /* ; */ - DSEMI, /* ;; */ - AMPER, /* & */ - DAMPER, /* && */ - NEWLIN, /* \n */ - INPAR, /* ( */ - INBRACE, /* { */ - OUTPAR, /* ) */ - OUTBRACE, /* } */ - OUTANG, /* > */ - OUTANGBANG, /* >! */ - DOUTANG, /* >> */ - DOUTANGBANG, /* >>! */ - INANG, /* < */ - DINANG, /* << */ - INANGAMP, /* <& */ - OUTANGAMP, /* >& */ - OUTANGAMPBANG, /* >&! */ - DOUTANGAMP, /* >>& */ - DOUTANGAMPBANG, /* >>&! */ - BAR, /* | */ - DBAR, /* || */ - BARAMP, /* |& */ - BANG, /* ! */ - STRING, /* string of chars and tokens */ - ENVSTRING, /* string of chars and tokens with a = in it */ - /* the below are all reserved words */ - DO, - DONE, - ESAC, - THEN, - ELIF, - ELSE, - FI, - FOR, - CASE, - IF, - WHILE, - FUNC, - REPEAT, - TIME, - UNTIL, - EXEC, - COMMAND, - SELECT, - COPROC - }; - -/* linked list data type */ - -typedef struct xlist *table; -typedef struct xnode *Node; - -struct xnode { - Node next,last; - void *dat; - }; -struct xlist { - Node first,last; - }; - - -typedef struct pnode *pline; -typedef struct lnode *list; -typedef struct l2node *list2; -typedef struct cnode *comm; -typedef struct jobnode *job; - -/* tree element for lists */ - -struct lnode { - struct l2node *left; - struct lnode *right; - int type; - }; - -enum ltype { - SYNC, /* ; */ - ASYNC /* & */ - }; - -/* tree element for sublists */ - -struct l2node { - struct pnode *left; - struct l2node *right; - int type; - int flags; /* one of PFLAGS below; applies to pnode *left */ - }; - -enum l2type { - ORNEXT = 10, /* || */ - ANDNEXT /* && */ - }; - -#define PFLAG_TIMED 4 /* time ... */ -#define PFLAG_NOT 1 /* ! ... */ -#define PFLAG_COPROC 32 /* coproc ... */ - -/* tree element for pipes */ - -struct pnode { - struct cnode *left; - struct pnode *right; - int type; - }; - -enum ptype { - END, /* pnode *right is null */ - PIPE /* pnode *right is the rest of the pipeline */ - }; - -/* tree element for commands */ - -struct cnode { - struct lnode *left; /* for SUBSH/CURSH/SHFUNC */ - char *cmd; /* command name */ - table args; /* argmument list (char *'s) */ - table redir; /* i/o redirections (struct fnode *'s) */ - table vars; /* parameter list (char *'s), can be null; - two entries in table for each parameter - assignment; "name" and "value" */ - int type; - int flags; - void *info; /* pointer to appropriate control structure, - if this is a CFOR, CWHILE, etc. */ - }; - -enum ctype { - SIMPLE, /* simple command */ - SUBSH, /* ( left ) */ - CURSH, /* { left } */ - SHFUNC, /* converted to { left } in execcomm */ - CFOR, - CWHILE, - CREPEAT, - CIF, - CCASE, - CSELECT - }; -#define CFLAG_EXEC 1 /* exec ... */ -#define CFLAG_COMMAND 2 /* command ... */ - -struct fnode { - union { - char *name; /* source/dest filename */ - int fd2; /* source/dest file descriptor */ - } u; - int type; - int fd1; /* affected file descriptor */ - }; - -enum ftype { - WRITE, /* #> name */ - WRITENOW, /* #>! name */ - APP, /* #>> name */ - APPNOW, /* #>>! name */ - READ, /* #< name */ - HEREDOC, /* #<< fd2 */ - MERGE, /* #<& fd2 */ - MERGEOUT, /* #>& fd2 */ - CLOSE, /* #>&-, #<&- */ - INPIPE, /* #< name, where name is <(...) */ - OUTPIPE, /* #> name, where name is >(...) */ - NONE - }; - -struct fornode { /* for/select */ - char *name; /* parameter to assign values to */ - list list; /* list of names to loop through */ - int inflag; /* != 0 if 'in ...' was specified */ - }; -struct casenode { /* arg list of cnode struct contains word to test */ - struct casenode *next; /* next pattern */ - char *pat; - list list; /* list to execute */ - }; -struct ifnode { - struct ifnode *next; - list ifl; /* if/elif test list (can be null in case of else) */ - list thenl; /* then list */ - }; -struct whilenode { - list cont; /* condition */ - list loop; /* list to execute until condition met */ - int cond; /* 0 for while, 1 for until */ - }; -struct repeatnode { - int count; /* # of iterations */ - list list; - }; - - -/* structure used for multiple i/o redirection */ -/* one for each fd open */ - -struct mnode { - int ct; /* # of redirections on this fd */ - int rflag; /* 0 if open for reading, 1 if open for writing */ - int pipe; /* fd of pipe if ct > 1 */ - int fds[NOFILE]; - }; - -/* node used in command hash table */ - -struct chnode -{ - int type; - int globstat; /* status of filename gen for this command */ - union { - char *nam; /* full pathname if type != BUILTIN */ - int (*func)(); /* func to exec if type == BUILTIN */ - } u; - }; - -enum chtype { - EXCMD_PREDOT, /* external command in PATH before . */ - EXCMD_POSTDOT, /* external command in PATH after . */ - BUILTIN - }; - -/* value for globstat field in chnode - - sample command: foo -xyz -pdq bar ble boz */ - -enum globx { - GLOB, /* all args globbed */ - MOSTGLOB, /* ble, boz globbed */ - NOGLOB /* no args globbed */ - }; - -/* node used in parameter hash table */ - -struct pmnode { - union { - char *str; /* value */ - long val; /* value if declared integer */ - } u; - int isint; /* != 0 if declared integer */ - }; - -/* tty state structure */ - -struct ttyinfo { -#ifdef TERMIOS - struct termios termios; -#else - struct sgttyb sgttyb; - struct tchars tchars; - struct ltchars ltchars; -#endif - struct winsize winsize; - }; - -extern struct ttyinfo shttyinfo; - -/* entry in job table */ - -struct jobnode { - long gleader; /* process group leader of this job */ - int stat; - char *cwd; /* current working dir of shell when - this job was spawned */ - struct procnode *procs; /* list of processes */ - table filelist; /* list of files to delete when done */ - struct ttyinfo ttyinfo; /* saved tty state */ - }; - -#define STAT_CHANGED 1 /* status changed and not reported */ -#define STAT_STOPPED 2 /* all procs stopped or exited */ -#define STAT_TIMED 4 /* job is being timed */ -#define STAT_DONE 8 -#define STAT_LOCKED 16 /* shell is finished creating this job, - may be deleted from job table */ -#define STAT_INUSE 64 /* this job entry is in use */ - -#define SP_RUNNING -1 /* fake statusp for running jobs */ - -/* node in job process lists */ - -struct procnode { - struct procnode *next; - long pid; - char *text; /* text to print when 'jobs' is run */ - int statusp; /* return code from wait3() */ - int lastfg; /* set if this procnode represents a - fragment of a pipeline run in a subshell - for commands like: - - foo | bar | ble - - where foo is a current shell function - or control structure. The command - actually executed is: - - foo | (bar | ble) - - That's two procnodes in the parent - shell, the latter having this flag set. */ - struct timeval ru_utime; - struct timeval ru_stime; - time_t bgtime; /* time job was spawned */ - time_t endtime; /* time job exited */ - }; - -/* node in alias hash table */ - -struct anode { - char *text; /* expansion of alias */ - int cmd; /* one for regular aliases, - zero for -a aliases, - negative for reserved words */ - int inuse; /* alias is being expanded */ - }; - -/* node in sched list */ - -struct schnode { - struct schnode *next; - char *cmd; /* command to run */ - time_t time; /* when to run it */ - }; - -#define MAXAL 20 /* maximum number of aliases expanded at once */ - -typedef struct xhtab *htable; - -/* node in hash table */ - -struct hnode { - struct hnode *hchain; - char *nam; - void *dat; - }; - -/* hash table structure */ - -struct xhtab { - int hsize,ct; - struct hnode **nodes; /* array of size hsize */ - }; - -typedef struct xpath *qath; /* used in globbing - see glob.c */ -typedef struct xcomp *comp; /* "" */ - -extern char *sys_errlist[]; -extern int errno; - -#define pushnode(X,Y) insnode(X,(Node) X,Y) - -#define OPT_INVALID 1 /* opt is invalid, like -$ */ -#define OPT_UNSET 0 -#define OPT_SET 2 - -#define CLOBBER '1' -#define NOBADPATTERN '2' -#define NONOMATCH '3' -#define GLOBDOTS '4' -#define NOTIFY '5' -#define ALLEXPORT 'a' -#define ERREXIT 'e' -#define BGNICE '6' -#define IGNOREEOF '7' -#define KEYWORD 'k' -#define MARKDIRS '8' -#define MONITOR 'm' -#define NOEXEC 'n' -#define NOGLOBOPT 'F' -#define NORCS 'f' -#define SHINSTDIN 's' -#define NOUNSET 'u' -#define VERBOSE 'v' -#define XTRACE 'x' -#define INTERACTIVE 'i' -#define AUTOLIST '9' -#define CORRECT '0' -#define DEXTRACT 'A' -#define NOBEEP 'B' -#define PRINTEXITVALUE 'C' -#define PUSHDTOHOME 'D' -#define PUSHDSILENT 'E' -#define NULLGLOB 'G' -#define RMSTARSILENT 'H' -#define IGNOREBRACES 'I' -#define CDABLEVARS 'J' -#define NOBANGHIST 'K' - -#define ALSTAT_MORE 1 /* last alias ended with ' ' */ -#define ALSTAT_JUNK 2 /* don't put word in history list */ - -#undef isset -#define isset(X) (opts[X]) -#define unset(X) (!opts[X]) -#define interact (isset(INTERACTIVE)) -#define jobbing (isset(MONITOR)) -#define nointr() signal(SIGINT,SIG_IGN) - -#define SIGCOUNT (SIGUSR2+1) -#define SIGERR (SIGUSR2+1) -#define SIGDEBUG (SIGUSR2+2) -#define SIGEXIT 0 - -#define SP(x) (*((union wait *) &(x))) - -#ifndef WEXITSTATUS -#define WEXITSTATUS(x) (((union wait*)&(x))->w_retcode) -#define WTERMSIG(x) (((union wait*)&(x))->w_termsig) -#define WSTOPSIG(x) (((union wait*)&(x))->w_stopsig) -#endif - -#ifndef S_ISBLK -#define _IFMT 0170000 -#define _IFDIR 0040000 -#define _IFCHR 0020000 -#define _IFBLK 0060000 -#define _IFREG 0100000 -#define _IFLNK 0120000 -#define _IFSOCK 0140000 -#define _IFIFO 0010000 -#define S_ISBLK(m) (((m)&_IFMT) == _IFBLK) -#define S_ISCHR(m) (((m)&_IFMT) == _IFCHR) -#define S_ISDIR(m) (((m)&_IFMT) == _IFDIR) -#define S_ISFIFO(m) (((m)&_IFMT) == _IFIFO) -#define S_ISREG(m) (((m)&_IFMT) == _IFREG) -#define S_ISLNK(m) (((m)&_IFMT) == _IFLNK) -#define S_ISSOCK(m) (((m)&_IFMT) == _IFSOCK) -#endif - -/* buffered shell input for non-interactive shells */ - -extern FILE *bshin; - -/* null-terminated array of pointers to strings containing elements - of PATH and CDPATH */ - -extern char **path,**cdpath; - -/* number of elements in aforementioned array */ - -extern int pathct,cdpathct; - -/* error/break flag */ - -extern int errflag; - -/* current history event number */ - -extern int cev; - -/* if != 0, this is the first line of the command */ - -extern int firstln; - -/* if != 0, this is the first char of the command (not including - white space */ - -extern int firstch; - -/* first event number in the history table */ - -extern int tfev; - -/* capacity of history table */ - -extern int tevs; - -/* if = 1, we have performed history substitution on the current line - if = 2, we have used the 'p' modifier */ - -extern int hflag; - -/* default event (usually cev-1, that is, "!!") */ - -extern int dev; - -/* != 0 if we are in the middle of parsing a command (== 0 if we - have not yet parsed the command word */ - -extern int incmd; - -/* the list of history events */ - -extern table histlist; - -/* the current history event (can be NULL) */ - -extern table curtab; - -/* the directory stack */ - -extern table dirstack; - -/* a string containing all the ungot characters (hungetch()) */ - -extern char *ungots; - -/* the pointer to the next character to read from ungots */ - -extern char *ungotptr; - -/* the contents of the IFS parameter */ - -extern char *ifs; - -/* != 0 if this is a subshell */ - -extern int subsh; - -/* # of break levels (break builtin) */ - -extern int breaks; - -/* != 0 if we have a return pending (return builtin) */ - -extern int retflag; - -/* # of nested loops we are in */ - -extern int loops; - -/* # of continue levels */ - -extern int contflag; - -/* the job currently being created/waited for (not current job in the sense - of '+' and '-', that's topjob */ - -extern int curjob; - -/* the current job (+) */ - -extern int topjob; - -/* the previous job (-) */ - -extern int prevjob; - -/* hash table containing the aliases and reserved words */ - -extern htable alhtab; - -/* hash table containing the parameters */ - -extern htable parmhtab; - -/* hash table containing the builtins/hashed commands */ - -extern htable chtab; - -/* hash table containing the shell functions */ - -extern htable shfunchtab; - -/* the job table */ - -extern struct jobnode jobtab[MAXJOB]; - -/* the list of sched jobs pending */ - -extern struct schnode *scheds; - -/* the last l for s/l/r/ history substitution */ - -extern char *last; - -/* the last r for s/l/r/ history substitution */ - -extern char *rast; - -/* if peek == STRING or ENVSTRING, the next token */ - -extern char *tstr; - -/* who am i */ - -extern char *username; - -/* the return code of the last command */ - -extern int lastval; - -/* != 0 if this is a login shell */ - -extern int islogin; - -/* the next token (enum xtok) */ - -extern int peek; - -/* the file descriptor associated with the next token, if it - is something like '<' or '>>', etc. */ - -extern int peekfd; - -/* input fd from the coprocess */ - -extern int spin; - -/* output fd from the coprocess */ - -extern int spout; - -/* the last time we checked mail */ - -extern time_t lastmailcheck; - -/* the last modified date on the mail file last time we checked */ - -extern time_t lastmailval; - -/* the last time we checked the people in the WATCH variable */ - -extern time_t lastwatch; - -/* the last time we did the periodic() shell function */ - -extern time_t lastperiod; - -/* $SECONDS = time(NULL) - shtimer */ - -extern time_t shtimer; - -/* the size of the mail file last time we checked */ - -extern off_t lastmailsize; - -/* $$ */ - -extern long procnum; - -/* $! (the pid of the last background command invoked */ - -extern long proclast; - -/* the process group of the shell */ - -extern long shpgrp; - -/* the current working directory */ - -extern char *cwd; - -/* the hostname, truncated after the '.' */ - -extern char *hostM; - -/* the hostname */ - -extern char *hostm; - -/* the home directory */ - -extern char *home; - -/* the positional parameters */ - -extern table pparms; - -/* the list of local variables we have to destroy */ - -extern table locallist; - -/* the shell input fd */ - -extern int SHIN; - -/* the shell tty fd */ - -extern int SHTTY; - -/* the stack of aliases we are expanding */ - -extern struct anode *alstack[MAXAL]; - -/* the alias stack pointer; also, the number of aliases currently - being expanded */ - -extern int alix; - -/* != 0 means we are reading input from a string */ - -extern int strin; - -/* == 1 means we are doing TAB expansion - == 2 means expansion has occurred during TAB expansion */ - -extern int magic; - -/* period between periodic() commands, in seconds */ - -extern int period; - -/* != 0 means history is turned off (through !" or setopt nobanghist) */ - -extern int stophist; - -/* != 0 means we have removed the current event from the history list */ - -extern int histremmed; - -/* the options; e.g. if opts['a'] is nonzero, -a is turned on */ - -extern int opts[128]; - -/* LINENO */ - -extern int lineno; - -/* != 0 means we have called execlist() and then intend to exit(), - so don't fork if not necessary */ - -extern int exiting; - -/* the limits for child processes */ - -extern struct rlimit limits[RLIM_NLIMITS]; - -/* the tokens */ - -extern char *tokens; - -/* the current word in the history list */ - -extern char *hlastw; - -/* the pointer to the current character in the current word - in the history list */ - -extern char *hlastp; - -/* the size of the current word in the history list */ - -extern int hlastsz; - -/* the alias expansion status - if == ALSTAT_MORE, we just finished -extern expanding an alias ending with a space */ - -extern int alstat; - -/* we have printed a 'you have stopped (running) jobs.' message */ - -extern int stopmsg; - -/* the default tty state */ - -extern struct ttyinfo shttyinfo; - -/* signal names */ - -extern char *sigs[]; - -/* signals that are trapped = 1, signals ignored =2 */ - -extern int sigtrapped[]; - End of zsh.h echo proto 1>&2 sed 's/^-//' >proto <<'End of proto' -#! /bin/sh -# -# proto - prototype generating script -# -# This file is part of zsh, the Z shell. -# -# zsh is free software etc etc. -# -for i -do - rm $i.pro - grep -v '[{};:#]' $i.c | grep '^[A-Za-z]' | - grep -v '^[ ]' | - grep -v static | sed 's/$/;/' >$i.pro -done - End of proto ---cut here---cut here---cut here---