Bash-4.3 distribution sources and documentation
This commit is contained in:
		
					parent
					
						
							
								4539d736f1
							
						
					
				
			
			
				commit
				
					
						ac50fbac37
					
				
			
		
					 497 changed files with 129395 additions and 87598 deletions
				
			
		|  | @ -4,7 +4,7 @@ | |||
| #								            #
 | ||||
| #############################################################################
 | ||||
| 
 | ||||
| # Copyright (C) 1994-2009 Free Software Foundation, Inc.
 | ||||
| # Copyright (C) 1994-2012 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
| #   This program is free software: you can redistribute it and/or modify
 | ||||
| #   it under the terms of the GNU General Public License as published by
 | ||||
|  | @ -83,21 +83,24 @@ CSOURCES = $(srcdir)/readline.c $(srcdir)/funmap.c $(srcdir)/keymaps.c \ | |||
| 	   $(srcdir)/histfile.c $(srcdir)/nls.c $(srcdir)/search.c \
 | ||||
| 	   $(srcdir)/shell.c $(srcdir)/tilde.c $(srcdir)/savestring.c \
 | ||||
| 	   $(srcdir)/text.c $(srcdir)/misc.c $(srcdir)/compat.c \
 | ||||
| 	   $(srcdir)/colors.c $(srcdir)/parse-colors.c \
 | ||||
| 	   $(srcdir)/mbutil.c $(srcdir)/xfree.c | ||||
| 
 | ||||
| # The header files for this library.
 | ||||
| HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h histlib.h \
 | ||||
| 	   posixstat.h posixdir.h posixjmp.h tilde.h rlconf.h rltty.h \
 | ||||
| 	   ansi_stdlib.h rlstdc.h tcap.h xmalloc.h rlprivate.h rlshell.h \
 | ||||
| 	   rltypedefs.h rlmbutil.h | ||||
| 	   rltypedefs.h rlmbutil.h colors.h parse-colors.h | ||||
| 
 | ||||
| HISTOBJ = history.o histexpand.o histfile.o histsearch.o shell.o savestring.o \
 | ||||
| 	  mbutil.o | ||||
| TILDEOBJ = tilde.o | ||||
| COLORSOBJ = colors.o parse-colors.o | ||||
| OBJECTS = readline.o vi_mode.o funmap.o keymaps.o parens.o search.o \
 | ||||
| 	  rltty.o complete.o bind.o isearch.o display.o signals.o \
 | ||||
| 	  util.o kill.o undo.o macro.o input.o callback.o terminal.o \
 | ||||
| 	  text.o nls.o misc.o $(HISTOBJ) $(TILDEOBJ) xmalloc.o xfree.o compat.o  | ||||
| 	  text.o nls.o misc.o $(HISTOBJ) $(TILDEOBJ) $(COLORSOBJ) \
 | ||||
| 	  xmalloc.o xfree.o compat.o  | ||||
| 
 | ||||
| # The texinfo files which document this library.
 | ||||
| DOCSOURCE = doc/rlman.texinfo doc/rltech.texinfo doc/rluser.texinfo | ||||
|  | @ -176,6 +179,7 @@ compat.o: rlstdc.h | |||
| complete.o: ansi_stdlib.h posixdir.h posixstat.h | ||||
| complete.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h | ||||
| complete.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h | ||||
| complete.o: colors.h | ||||
| display.o: ansi_stdlib.h posixstat.h | ||||
| display.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h | ||||
| display.o: tcap.h | ||||
|  | @ -264,6 +268,14 @@ vi_mode.o: history.h ansi_stdlib.h rlstdc.h | |||
| xmalloc.o: ${BUILD_DIR}/config.h ansi_stdlib.h | ||||
| xfree.o: ${BUILD_DIR}/config.h ansi_stdlib.h | ||||
| 
 | ||||
| colors.o: ${BUILD_DIR}/config.h colors.h | ||||
| colors.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h | ||||
| colors.o: rlconf.h | ||||
| colors.o: ansi_stdlib.h posixstat.h | ||||
| parse-colors.o: ${BUILD_DIR}/config.h colors.h parse-colors.h | ||||
| parse-colors.o: rldefs.h rlconf.h | ||||
| parse-colors.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h | ||||
| 
 | ||||
| bind.o: rlshell.h | ||||
| histfile.o: rlshell.h | ||||
| nls.o: rlshell.h | ||||
|  | @ -293,6 +305,8 @@ text.o: rlprivate.h | |||
| undo.o: rlprivate.h | ||||
| util.o: rlprivate.h | ||||
| vi_mode.o: rlprivate.h | ||||
| colors.o: rlprivate.h | ||||
| parse-colors.o: rlprivate.h | ||||
| 
 | ||||
| bind.o: xmalloc.h | ||||
| complete.o: xmalloc.h   | ||||
|  | @ -320,6 +334,8 @@ util.o: xmalloc.h | |||
| vi_mode.o: xmalloc.h  | ||||
| xfree.o: xmalloc.h | ||||
| xmalloc.o: xmalloc.h | ||||
| colors.o: xmalloc.h | ||||
| parse-colors.o: xmalloc.h | ||||
| 
 | ||||
| complete.o: rlmbutil.h | ||||
| display.o: rlmbutil.h | ||||
|  | @ -332,6 +348,8 @@ readline.o: rlmbutil.h | |||
| search.o: rlmbutil.h | ||||
| text.o: rlmbutil.h | ||||
| vi_mode.o: rlmbutil.h | ||||
| colors.o: rlmbutil.h | ||||
| parse-colors.o: rlmbutil.h | ||||
| 
 | ||||
| # Rules for deficient makes, like SunOS and Solaris
 | ||||
| bind.o: bind.c | ||||
|  | @ -364,6 +382,9 @@ vi_mode.o: vi_mode.c | |||
| xfree.o: xfree.c | ||||
| xmalloc.o: xmalloc.c | ||||
| 
 | ||||
| colors.o: colors.c | ||||
| parse-colors.o: parse-colors.c | ||||
| 
 | ||||
| histexpand.o: histexpand.c | ||||
| histfile.o: histfile.c | ||||
| history.o: history.c | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| /* bind.c -- key binding and startup file support for the readline library. */ | ||||
| 
 | ||||
| /* Copyright (C) 1987-2010 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 1987-2012 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file is part of the GNU Readline Library (Readline), a library | ||||
|    for reading lines of text with interactive input and history editing. | ||||
|  | @ -72,11 +72,15 @@ extern char *strchr (), *strrchr (); | |||
| /* Variables exported by this file. */ | ||||
| Keymap rl_binding_keymap; | ||||
| 
 | ||||
| static int _rl_skip_to_delim PARAMS((char *, int, int)); | ||||
| 
 | ||||
| static char *_rl_read_file PARAMS((char *, size_t *)); | ||||
| static void _rl_init_file_error PARAMS((const char *)); | ||||
| static int _rl_read_init_file PARAMS((const char *, int)); | ||||
| static int glean_key_from_name PARAMS((char *)); | ||||
| 
 | ||||
| static int find_boolean_var PARAMS((const char *)); | ||||
| static int find_string_var PARAMS((const char *)); | ||||
| 
 | ||||
| static char *_rl_get_string_variable_value PARAMS((const char *)); | ||||
| static int substring_member_of_array PARAMS((const char *, const char * const *)); | ||||
|  | @ -567,6 +571,40 @@ rl_translate_keyseq (seq, array, len) | |||
|   return (0); | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| _rl_isescape (c) | ||||
|      int c; | ||||
| { | ||||
|   switch (c) | ||||
|     { | ||||
|     case '\007': | ||||
|     case '\b': | ||||
|     case '\f': | ||||
|     case '\n': | ||||
|     case '\r': | ||||
|     case TAB: | ||||
|     case 0x0b:  return (1); | ||||
|     default: return (0); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| _rl_escchar (c) | ||||
|      int c; | ||||
| { | ||||
|   switch (c) | ||||
|     { | ||||
|     case '\007':  return ('a'); | ||||
|     case '\b':  return ('b'); | ||||
|     case '\f':  return ('f'); | ||||
|     case '\n':  return ('n'); | ||||
|     case '\r':  return ('r'); | ||||
|     case TAB:  return ('t'); | ||||
|     case 0x0b:  return ('v'); | ||||
|     default: return (c); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| char * | ||||
| rl_untranslate_keyseq (seq) | ||||
|      int seq; | ||||
|  | @ -618,9 +656,10 @@ rl_untranslate_keyseq (seq) | |||
|   return kseq; | ||||
| } | ||||
| 
 | ||||
| static char * | ||||
| _rl_untranslate_macro_value (seq) | ||||
| char * | ||||
| _rl_untranslate_macro_value (seq, use_escapes) | ||||
|      char *seq; | ||||
|      int use_escapes; | ||||
| { | ||||
|   char *ret, *r, *s; | ||||
|   int c; | ||||
|  | @ -644,9 +683,14 @@ _rl_untranslate_macro_value (seq) | |||
|       else if (CTRL_CHAR (c)) | ||||
| 	{ | ||||
| 	  *r++ = '\\'; | ||||
| 	  *r++ = 'C'; | ||||
| 	  *r++ = '-'; | ||||
| 	  c = _rl_to_lower (UNCTRL (c)); | ||||
| 	  if (use_escapes && _rl_isescape (c)) | ||||
| 	    c = _rl_escchar (c); | ||||
| 	  else | ||||
| 	    { | ||||
| 	      *r++ = 'C'; | ||||
| 	      *r++ = '-'; | ||||
| 	      c = _rl_to_lower (UNCTRL (c)); | ||||
| 	    } | ||||
| 	} | ||||
|       else if (c == RUBOUT) | ||||
|  	{ | ||||
|  | @ -1157,6 +1201,38 @@ handle_parser_directive (statement) | |||
|   return (1); | ||||
| } | ||||
| 
 | ||||
| /* Start at STRING[START] and look for DELIM.  Return I where STRING[I] ==
 | ||||
|    DELIM or STRING[I] == 0.  DELIM is usually a double quote. */ | ||||
| static int | ||||
| _rl_skip_to_delim (string, start, delim) | ||||
|      char *string; | ||||
|      int start, delim; | ||||
| { | ||||
|   int i, c, passc; | ||||
| 
 | ||||
|   for (i = start,passc = 0; c = string[i]; i++) | ||||
|     { | ||||
|       if (passc) | ||||
| 	{ | ||||
| 	  passc = 0; | ||||
| 	  if (c == 0) | ||||
| 	    break; | ||||
| 	  continue; | ||||
| 	} | ||||
| 
 | ||||
|       if (c == '\\') | ||||
| 	{ | ||||
| 	  passc = 1; | ||||
| 	  continue; | ||||
| 	} | ||||
| 
 | ||||
|       if (c == delim) | ||||
| 	break; | ||||
|     } | ||||
| 
 | ||||
|   return i; | ||||
| } | ||||
| 
 | ||||
| /* 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. | ||||
|  | @ -1172,7 +1248,7 @@ rl_parse_and_bind (string) | |||
|   while (string && whitespace (*string)) | ||||
|     string++; | ||||
| 
 | ||||
|   if (!string || !*string || *string == '#') | ||||
|   if (string == 0 || *string == 0 || *string == '#') | ||||
|     return 0; | ||||
| 
 | ||||
|   /* If this is a parser directive, act on it. */ | ||||
|  | @ -1192,31 +1268,16 @@ rl_parse_and_bind (string) | |||
|      backslash to quote characters in the key expression. */ | ||||
|   if (*string == '"') | ||||
|     { | ||||
|       int passc = 0; | ||||
|       i = _rl_skip_to_delim (string, 1, '"'); | ||||
| 
 | ||||
|       for (i = 1; c = string[i]; i++) | ||||
| 	{ | ||||
| 	  if (passc) | ||||
| 	    { | ||||
| 	      passc = 0; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 
 | ||||
| 	  if (c == '\\') | ||||
| 	    { | ||||
| 	      passc++; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 
 | ||||
| 	  if (c == '"') | ||||
| 	    break; | ||||
| 	} | ||||
|       /* If we didn't find a closing quote, abort the line. */ | ||||
|       if (string[i] == '\0') | ||||
|         { | ||||
|           _rl_init_file_error ("no closing `\"' in key binding"); | ||||
|           return 1; | ||||
|         } | ||||
|       else | ||||
|         i++;	/* skip past closing double quote */ | ||||
|     } | ||||
| 
 | ||||
|   /* Advance to the colon (:) or whitespace which separates the two objects. */ | ||||
|  | @ -1236,6 +1297,7 @@ rl_parse_and_bind (string) | |||
|   if (_rl_stricmp (string, "set") == 0) | ||||
|     { | ||||
|       char *var, *value, *e; | ||||
|       int s; | ||||
| 
 | ||||
|       var = string + i; | ||||
|       /* Make VAR point to start of variable name. */ | ||||
|  | @ -1243,25 +1305,37 @@ rl_parse_and_bind (string) | |||
| 
 | ||||
|       /* Make VALUE point to start of value string. */ | ||||
|       value = var; | ||||
|       while (*value && !whitespace (*value)) value++; | ||||
|       while (*value && whitespace (*value) == 0) value++; | ||||
|       if (*value) | ||||
| 	*value++ = '\0'; | ||||
|       while (*value && whitespace (*value)) value++; | ||||
| 
 | ||||
|       /* Strip trailing whitespace from values to boolean variables.  Temp
 | ||||
| 	 fix until I get a real quoted-string parser here. */ | ||||
|       i = find_boolean_var (var); | ||||
|       if (i >= 0) | ||||
|       /* Strip trailing whitespace from values of boolean variables. */ | ||||
|       if (find_boolean_var (var) >= 0) | ||||
| 	{ | ||||
| 	  /* remove trailing whitespace */ | ||||
| remove_trailing: | ||||
| 	  e = value + strlen (value) - 1; | ||||
| 	  while (e >= value && whitespace (*e)) | ||||
| 	    e--; | ||||
| 	  e++;		/* skip back to whitespace or EOS */ | ||||
| 	   | ||||
| 	  if (*e && e >= value) | ||||
| 	    *e = '\0'; | ||||
| 	} | ||||
| 
 | ||||
|       else if ((i = find_string_var (var)) >= 0) | ||||
| 	{ | ||||
| 	  /* Allow quoted strings in variable values */ | ||||
| 	  if (*value == '"') | ||||
| 	    { | ||||
| 	      i = _rl_skip_to_delim (value, 1, *value); | ||||
| 	      value[i] = '\0'; | ||||
| 	      value++;	/* skip past the quote */ | ||||
| 	    } | ||||
| 	  else | ||||
| 	    goto remove_trailing; | ||||
| 	} | ||||
| 	 | ||||
|       rl_variable_bind (var, value); | ||||
|       return 0; | ||||
|     } | ||||
|  | @ -1282,32 +1356,13 @@ rl_parse_and_bind (string) | |||
|      the quoted string delimiter, like the shell. */ | ||||
|   if (*funname == '\'' || *funname == '"') | ||||
|     { | ||||
|       int delimiter, passc; | ||||
| 
 | ||||
|       delimiter = string[i++]; | ||||
|       for (passc = 0; c = string[i]; i++) | ||||
| 	{ | ||||
| 	  if (passc) | ||||
| 	    { | ||||
| 	      passc = 0; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 
 | ||||
| 	  if (c == '\\') | ||||
| 	    { | ||||
| 	      passc = 1; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 
 | ||||
| 	  if (c == delimiter) | ||||
| 	    break; | ||||
| 	} | ||||
|       if (c) | ||||
|       i = _rl_skip_to_delim (string, i+1, *funname); | ||||
|       if (string[i]) | ||||
| 	i++; | ||||
|     } | ||||
| 
 | ||||
|   /* Advance to the end of the string.  */ | ||||
|   for (; string[i] && !whitespace (string[i]); i++); | ||||
|   for (; string[i] && whitespace (string[i]) == 0; i++); | ||||
| 
 | ||||
|   /* No extra whitespace at the end of the string. */ | ||||
|   string[i] = '\0'; | ||||
|  | @ -1367,7 +1422,7 @@ rl_parse_and_bind (string) | |||
| 
 | ||||
|   /* Get the actual character we want to deal with. */ | ||||
|   kname = strrchr (string, '-'); | ||||
|   if (!kname) | ||||
|   if (kname == 0) | ||||
|     kname = string; | ||||
|   else | ||||
|     kname++; | ||||
|  | @ -1423,6 +1478,9 @@ static const struct { | |||
|   { "bind-tty-special-chars",	&_rl_bind_stty_chars,		0 }, | ||||
|   { "blink-matching-paren",	&rl_blink_matching_paren,	V_SPECIAL }, | ||||
|   { "byte-oriented",		&rl_byte_oriented,		0 }, | ||||
| #if defined (COLOR_SUPPORT) | ||||
|   { "colored-stats",		&_rl_colored_stats,		0 }, | ||||
| #endif | ||||
|   { "completion-ignore-case",	&_rl_completion_case_fold,	0 }, | ||||
|   { "completion-map-case",	&_rl_completion_case_map,	0 }, | ||||
|   { "convert-meta",		&_rl_convert_meta_chars_to_ascii, 0 }, | ||||
|  | @ -1447,6 +1505,7 @@ static const struct { | |||
|   { "revert-all-at-newline",	&_rl_revert_all_at_newline,	0 }, | ||||
|   { "show-all-if-ambiguous",	&_rl_complete_show_all,		0 }, | ||||
|   { "show-all-if-unmodified",	&_rl_complete_show_unmodified,	0 }, | ||||
|   { "show-mode-in-prompt",	&_rl_show_mode_in_prompt,	0 }, | ||||
|   { "skip-completed-text",	&_rl_skip_completed_text,	0 }, | ||||
| #if defined (VISIBLE_STATS) | ||||
|   { "visible-stats",		&rl_visible_stats,		0 }, | ||||
|  | @ -1486,6 +1545,8 @@ hack_special_boolean_var (i) | |||
|       else | ||||
| 	_rl_bell_preference = AUDIBLE_BELL; | ||||
|     } | ||||
|   else if (_rl_stricmp (name, "show-mode-in-prompt") == 0) | ||||
|     _rl_reset_prompt (); | ||||
| } | ||||
| 
 | ||||
| typedef int _rl_sv_func_t PARAMS((const char *)); | ||||
|  | @ -1511,6 +1572,7 @@ static int sv_editmode PARAMS((const char *)); | |||
| static int sv_histsize PARAMS((const char *)); | ||||
| static int sv_isrchterm PARAMS((const char *)); | ||||
| static int sv_keymap PARAMS((const char *)); | ||||
| static int sv_seqtimeout PARAMS((const char *)); | ||||
| 
 | ||||
| static const struct { | ||||
|   const char * const name; | ||||
|  | @ -1526,6 +1588,7 @@ static const struct { | |||
|   { "history-size",	V_INT,		sv_histsize }, | ||||
|   { "isearch-terminators", V_STRING,	sv_isrchterm }, | ||||
|   { "keymap",		V_STRING,	sv_keymap }, | ||||
|   { "keyseq-timeout",	V_INT,		sv_seqtimeout }, | ||||
|   { (char *)NULL,	0, (_rl_sv_func_t *)0 } | ||||
| }; | ||||
| 
 | ||||
|  | @ -1683,13 +1746,17 @@ static int | |||
| sv_histsize (value) | ||||
|      const char *value; | ||||
| { | ||||
|   int nval = 500; | ||||
|   int nval; | ||||
| 
 | ||||
|   nval = 500; | ||||
|   if (value && *value) | ||||
|     { | ||||
|       nval = atoi (value); | ||||
|       if (nval < 0) | ||||
| 	return 1; | ||||
| 	{ | ||||
| 	  unstifle_history (); | ||||
| 	  return 0; | ||||
| 	} | ||||
|     } | ||||
|   stifle_history (nval); | ||||
|   return 0; | ||||
|  | @ -1710,6 +1777,23 @@ sv_keymap (value) | |||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| sv_seqtimeout (value) | ||||
|      const char *value; | ||||
| { | ||||
|   int nval; | ||||
| 
 | ||||
|   nval = 0; | ||||
|   if (value && *value) | ||||
|     { | ||||
|       nval = atoi (value); | ||||
|       if (nval < 0) | ||||
| 	nval = 0; | ||||
|     } | ||||
|   _rl_keyseq_timeout = nval; | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| sv_bell_style (value) | ||||
|      const char *value; | ||||
|  | @ -2167,6 +2251,8 @@ rl_function_dumper (print_readably) | |||
| 	    } | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
|   xfree (names); | ||||
| } | ||||
| 
 | ||||
| /* Print all of the current functions and their bindings to
 | ||||
|  | @ -2199,7 +2285,7 @@ _rl_macro_dumper_internal (print_readably, map, prefix) | |||
| 	{ | ||||
| 	case ISMACR: | ||||
| 	  keyname = _rl_get_keyname (key); | ||||
| 	  out = _rl_untranslate_macro_value ((char *)map[key].function); | ||||
| 	  out = _rl_untranslate_macro_value ((char *)map[key].function, 0); | ||||
| 
 | ||||
| 	  if (print_readably) | ||||
| 	    fprintf (rl_outstream, "\"%s%s\": \"%s\"\n", prefix ? prefix : "", | ||||
|  | @ -2311,7 +2397,7 @@ _rl_get_string_variable_value (name) | |||
|     { | ||||
|       if (_rl_isearch_terminators == 0) | ||||
| 	return 0; | ||||
|       ret = _rl_untranslate_macro_value (_rl_isearch_terminators); | ||||
|       ret = _rl_untranslate_macro_value (_rl_isearch_terminators, 0); | ||||
|       if (ret) | ||||
| 	{ | ||||
| 	  strncpy (numbuf, ret, sizeof (numbuf) - 1); | ||||
|  | @ -2329,6 +2415,11 @@ _rl_get_string_variable_value (name) | |||
| 	ret = rl_get_keymap_name_from_edit_mode (); | ||||
|       return (ret ? ret : "none"); | ||||
|     } | ||||
|   else if (_rl_stricmp (name, "keyseq-timeout") == 0) | ||||
|     { | ||||
|       sprintf (numbuf, "%d", _rl_keyseq_timeout);     | ||||
|       return (numbuf); | ||||
|     } | ||||
|   else | ||||
|     return (0); | ||||
| } | ||||
|  |  | |||
|  | @ -62,8 +62,10 @@ _rl_callback_generic_arg *_rl_callback_data = 0; | |||
|    whenever a complete line of input is ready.  The user must then | ||||
|    call rl_callback_read_char() every time some input is available, and  | ||||
|    rl_callback_read_char() will call the user's function with the complete | ||||
|    text read in at each end of line.  The terminal is kept prepped and | ||||
|    signals handled all the time, except during calls to the user's function. */ | ||||
|    text read in at each end of line.  The terminal is kept prepped | ||||
|    all the time, except during calls to the user's function.  Signal | ||||
|    handlers are only installed when the application calls back into | ||||
|    readline, so readline doesn't `steal' signals from the application.  */ | ||||
| 
 | ||||
| rl_vcpfunc_t *rl_linefunc;		/* user callback function */ | ||||
| static int in_handler;		/* terminal_prepped and signals set? */ | ||||
|  | @ -80,10 +82,6 @@ _rl_callback_newline () | |||
| 
 | ||||
|       if (rl_prep_term_function) | ||||
| 	(*rl_prep_term_function) (_rl_meta_flag); | ||||
| 
 | ||||
| #if defined (HANDLE_SIGNALS) | ||||
|       rl_set_signals (); | ||||
| #endif | ||||
|     } | ||||
| 
 | ||||
|   readline_internal_setup (); | ||||
|  | @ -102,6 +100,16 @@ rl_callback_handler_install (prompt, linefunc) | |||
|   _rl_callback_newline (); | ||||
| } | ||||
| 
 | ||||
| #if defined (HANDLE_SIGNALS) | ||||
| #define CALLBACK_READ_RETURN() \ | ||||
|   do { \ | ||||
|     rl_clear_signals (); \ | ||||
|     return; \ | ||||
|   } while (0) | ||||
| #else | ||||
| #define CALLBACK_READ_RETURN() return | ||||
| #endif | ||||
| 
 | ||||
| /* Read one character, and dispatch to the handler if it ends the line. */ | ||||
| void | ||||
| rl_callback_read_char () | ||||
|  | @ -117,15 +125,24 @@ rl_callback_read_char () | |||
|     } | ||||
| 
 | ||||
|   memcpy ((void *)olevel, (void *)_rl_top_level, sizeof (procenv_t)); | ||||
| #if defined (HAVE_POSIX_SIGSETJMP) | ||||
|   jcode = sigsetjmp (_rl_top_level, 0); | ||||
| #else | ||||
|   jcode = setjmp (_rl_top_level); | ||||
| #endif | ||||
|   if (jcode) | ||||
|     { | ||||
|       (*rl_redisplay_function) (); | ||||
|       _rl_want_redisplay = 0; | ||||
|       memcpy ((void *)_rl_top_level, (void *)olevel, sizeof (procenv_t)); | ||||
|       return; | ||||
|       CALLBACK_READ_RETURN (); | ||||
|     } | ||||
| 
 | ||||
| #if defined (HANDLE_SIGNALS) | ||||
|   /* Install signal handlers only when readline has control. */ | ||||
|   rl_set_signals (); | ||||
| #endif | ||||
| 
 | ||||
|   do | ||||
|     { | ||||
|       RL_CHECK_SIGNALS (); | ||||
|  | @ -135,12 +152,13 @@ rl_callback_read_char () | |||
| 	  if (eof == 0 && (RL_ISSTATE (RL_STATE_ISEARCH) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING)) | ||||
| 	    rl_callback_read_char (); | ||||
| 
 | ||||
| 	  return; | ||||
| 	  CALLBACK_READ_RETURN (); | ||||
| 	} | ||||
|       else if  (RL_ISSTATE (RL_STATE_NSEARCH)) | ||||
| 	{ | ||||
| 	  eof = _rl_nsearch_callback (_rl_nscxt); | ||||
| 	  return; | ||||
| 
 | ||||
| 	  CALLBACK_READ_RETURN (); | ||||
| 	} | ||||
| #if defined (VI_MODE) | ||||
|       else if (RL_ISSTATE (RL_STATE_VIMOTION)) | ||||
|  | @ -151,7 +169,7 @@ rl_callback_read_char () | |||
| 	  if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) | ||||
| 	    _rl_internal_char_cleanup (); | ||||
| 
 | ||||
| 	  return; | ||||
| 	  CALLBACK_READ_RETURN (); | ||||
| 	} | ||||
| #endif | ||||
|       else if (RL_ISSTATE (RL_STATE_NUMERICARG)) | ||||
|  | @ -163,7 +181,7 @@ rl_callback_read_char () | |||
| 	  else if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) | ||||
| 	    _rl_internal_char_cleanup (); | ||||
| 
 | ||||
| 	  return; | ||||
| 	  CALLBACK_READ_RETURN (); | ||||
| 	} | ||||
|       else if (RL_ISSTATE (RL_STATE_MULTIKEY)) | ||||
| 	{ | ||||
|  | @ -180,7 +198,7 @@ rl_callback_read_char () | |||
| 	{ | ||||
| 	  /* This allows functions that simply need to read an additional
 | ||||
| 	     character (like quoted-insert) to register a function to be | ||||
| 	     called when input is available.  _rl_callback_data is simply a | ||||
| 	     called when input is available.  _rl_callback_data is a | ||||
| 	     pointer to a struct that has the argument count originally | ||||
| 	     passed to the registering function and space for any additional | ||||
| 	     parameters.  */ | ||||
|  | @ -230,6 +248,8 @@ rl_callback_read_char () | |||
| 	} | ||||
|     } | ||||
|   while (rl_pending_input || _rl_pushed_input_available () || RL_ISSTATE (RL_STATE_MACROINPUT)); | ||||
| 
 | ||||
|   CALLBACK_READ_RETURN (); | ||||
| } | ||||
| 
 | ||||
| /* Remove the handler, and make sure the terminal is in its normal state. */ | ||||
|  |  | |||
|  | @ -72,7 +72,7 @@ | |||
| #  define IN_CTYPE_DOMAIN(c) isascii(c) | ||||
| #endif | ||||
| 
 | ||||
| #if !defined (isxdigit) && !defined (HAVE_ISXDIGIT) | ||||
| #if !defined (isxdigit) && !defined (HAVE_ISXDIGIT) && !defined (__cplusplus) | ||||
| #  define isxdigit(c)   (isdigit((c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) | ||||
| #endif | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										251
									
								
								lib/readline/colors.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										251
									
								
								lib/readline/colors.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,251 @@ | |||
| /* `dir', `vdir' and `ls' directory listing programs for GNU.
 | ||||
| 
 | ||||
|    Modified by Chet Ramey for Readline. | ||||
| 
 | ||||
|    Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012 Free Software Foundation, | ||||
|    Inc. | ||||
| 
 | ||||
|    This program 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 3 of the License, or | ||||
|    (at your option) any later version. | ||||
| 
 | ||||
|    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */
 | ||||
| 
 | ||||
| /* Written by Richard Stallman and David MacKenzie.  */ | ||||
| 
 | ||||
| /* Color support by Peter Anvin <Peter.Anvin@linux.org> and Dennis
 | ||||
|    Flaherty <dennisf@denix.elk.miles.com> based on original patches by | ||||
|    Greg Lee <lee@uhunix.uhcc.hawaii.edu>.  */ | ||||
| 
 | ||||
| #define READLINE_LIBRARY | ||||
| 
 | ||||
| #if defined (HAVE_CONFIG_H) | ||||
| #  include <config.h> | ||||
| #endif | ||||
| 
 | ||||
| #include "rlconf.h" | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| #include "posixstat.h" // stat related macros (S_ISREG, ...) | ||||
| #include <fcntl.h> // S_ISUID | ||||
| 
 | ||||
| // strlen()
 | ||||
| #if defined (HAVE_STRING_H) | ||||
| #  include <string.h> | ||||
| #else /* !HAVE_STRING_H */ | ||||
| #  include <strings.h> | ||||
| #endif /* !HAVE_STRING_H */ | ||||
| 
 | ||||
| // abort()
 | ||||
| #if defined (HAVE_STDLIB_H) | ||||
| #  include <stdlib.h> | ||||
| #else | ||||
| #  include "ansi_stdlib.h" | ||||
| #endif /* HAVE_STDLIB_H */ | ||||
| 
 | ||||
| #include "readline.h" | ||||
| #include "rldefs.h" | ||||
| 
 | ||||
| #ifdef COLOR_SUPPORT | ||||
| 
 | ||||
| #include "xmalloc.h" | ||||
| #include "colors.h" | ||||
| 
 | ||||
| static bool is_colored (enum indicator_no type); | ||||
| static void restore_default_color (void); | ||||
| 
 | ||||
| COLOR_EXT_TYPE *_rl_color_ext_list = 0; | ||||
| 
 | ||||
| /* Output a color indicator (which may contain nulls).  */ | ||||
| void | ||||
| _rl_put_indicator (const struct bin_str *ind) { | ||||
|   fwrite (ind->string, ind->len, 1, rl_outstream); | ||||
| } | ||||
| 
 | ||||
| static bool | ||||
| is_colored (enum indicator_no colored_filetype) | ||||
| { | ||||
|   size_t len = _rl_color_indicator[colored_filetype].len; | ||||
|   char const *s = _rl_color_indicator[colored_filetype].string; | ||||
|   return ! (len == 0 | ||||
|             || (len == 1 && strncmp (s, "0", 1) == 0) | ||||
|             || (len == 2 && strncmp (s, "00", 2) == 0)); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| restore_default_color (void) | ||||
| { | ||||
|   _rl_put_indicator (&_rl_color_indicator[C_LEFT]); | ||||
|   _rl_put_indicator (&_rl_color_indicator[C_RIGHT]); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| _rl_set_normal_color (void) | ||||
| { | ||||
|   if (is_colored (C_NORM)) | ||||
|     { | ||||
|       _rl_put_indicator (&_rl_color_indicator[C_LEFT]); | ||||
|       _rl_put_indicator (&_rl_color_indicator[C_NORM]); | ||||
|       _rl_put_indicator (&_rl_color_indicator[C_RIGHT]); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /* Returns whether any color sequence was printed. */ | ||||
| bool | ||||
| _rl_print_color_indicator (char *f) | ||||
| { | ||||
|   enum indicator_no colored_filetype; | ||||
|   COLOR_EXT_TYPE *ext;	/* Color extension */ | ||||
|   size_t len;		/* Length of name */ | ||||
| 
 | ||||
|   const char* name; | ||||
|   char *filename; | ||||
|   struct stat astat; | ||||
|   mode_t mode; | ||||
|   int linkok; | ||||
| 
 | ||||
|   int stat_ok; | ||||
| 
 | ||||
|   name = f; | ||||
| 
 | ||||
|   /* This should already have undergone tilde expansion */ | ||||
|   filename = 0; | ||||
|   if (rl_filename_stat_hook) | ||||
|     { | ||||
|       filename = savestring (f); | ||||
|       (*rl_filename_stat_hook) (&filename); | ||||
|       name = filename; | ||||
|     } | ||||
| 
 | ||||
| #if defined (HAVE_LSTAT) | ||||
|   stat_ok = lstat(name, &astat); | ||||
| #else | ||||
|   stat_ok = stat(name, &astat); | ||||
| #endif | ||||
|   if( stat_ok == 0 ) { | ||||
|     mode = astat.st_mode; | ||||
|     linkok = 1; //f->linkok;
 | ||||
|   } | ||||
|   else | ||||
|     linkok = -1; | ||||
| 
 | ||||
|   /* Is this a nonexistent file?  If so, linkok == -1.  */ | ||||
| 
 | ||||
|   if (linkok == -1 && _rl_color_indicator[C_MISSING].string != NULL) | ||||
|     colored_filetype = C_MISSING; | ||||
|   else if(stat_ok != 0) | ||||
|     { | ||||
|       static enum indicator_no filetype_indicator[] = FILETYPE_INDICATORS; | ||||
|       colored_filetype = filetype_indicator[normal]; //f->filetype];
 | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       if (S_ISREG (mode)) | ||||
|         { | ||||
|           colored_filetype = C_FILE; | ||||
| 
 | ||||
|           if ((mode & S_ISUID) != 0 && is_colored (C_SETUID)) | ||||
|             colored_filetype = C_SETUID; | ||||
|           else if ((mode & S_ISGID) != 0 && is_colored (C_SETGID)) | ||||
|             colored_filetype = C_SETGID; | ||||
|           else if (is_colored (C_CAP) && 0) //f->has_capability)
 | ||||
|             colored_filetype = C_CAP; | ||||
|           else if ((mode & S_IXUGO) != 0 && is_colored (C_EXEC)) | ||||
|             colored_filetype = C_EXEC; | ||||
|           else if ((1 < astat.st_nlink) && is_colored (C_MULTIHARDLINK)) | ||||
|             colored_filetype = C_MULTIHARDLINK; | ||||
|         } | ||||
|       else if (S_ISDIR (mode)) | ||||
|         { | ||||
|           colored_filetype = C_DIR; | ||||
| 
 | ||||
| #if defined (S_ISVTX) | ||||
|           if ((mode & S_ISVTX) && (mode & S_IWOTH) | ||||
|               && is_colored (C_STICKY_OTHER_WRITABLE)) | ||||
|             colored_filetype = C_STICKY_OTHER_WRITABLE; | ||||
|           else | ||||
| #endif | ||||
|           if ((mode & S_IWOTH) != 0 && is_colored (C_OTHER_WRITABLE)) | ||||
|             colored_filetype = C_OTHER_WRITABLE; | ||||
| #if defined (S_ISVTX) | ||||
|           else if ((mode & S_ISVTX) != 0 && is_colored (C_STICKY)) | ||||
|             colored_filetype = C_STICKY; | ||||
| #endif | ||||
|         } | ||||
|       else if (S_ISLNK (mode)) | ||||
|         colored_filetype = ((linkok == 0 | ||||
|                  && (!strncmp (_rl_color_indicator[C_LINK].string, "target", 6) | ||||
|                      || _rl_color_indicator[C_ORPHAN].string)) | ||||
|                 ? C_ORPHAN : C_LINK); | ||||
|       else if (S_ISFIFO (mode)) | ||||
|         colored_filetype = C_FIFO; | ||||
|       else if (S_ISSOCK (mode)) | ||||
|         colored_filetype = C_SOCK; | ||||
|       else if (S_ISBLK (mode)) | ||||
|         colored_filetype = C_BLK; | ||||
|       else if (S_ISCHR (mode)) | ||||
|         colored_filetype = C_CHR; | ||||
|       else | ||||
|         { | ||||
|           /* Classify a file of some other type as C_ORPHAN.  */ | ||||
|           colored_filetype = C_ORPHAN; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   /* Check the file's suffix only if still classified as C_FILE.  */ | ||||
|   ext = NULL; | ||||
|   if (colored_filetype == C_FILE) | ||||
|     { | ||||
|       /* Test if NAME has a recognized suffix.  */ | ||||
|       len = strlen (name); | ||||
|       name += len;		/* Pointer to final \0.  */ | ||||
|       for (ext = _rl_color_ext_list; ext != NULL; ext = ext->next) | ||||
|         { | ||||
|           if (ext->ext.len <= len | ||||
|               && strncmp (name - ext->ext.len, ext->ext.string, | ||||
|                           ext->ext.len) == 0) | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   free (filename);	/* NULL or savestring return value */ | ||||
| 
 | ||||
|   { | ||||
|     const struct bin_str *const s | ||||
|       = ext ? &(ext->seq) : &_rl_color_indicator[colored_filetype]; | ||||
|     if (s->string != NULL) | ||||
|       { | ||||
|         /* Need to reset so not dealing with attribute combinations */ | ||||
|         if (is_colored (C_NORM)) | ||||
| 	  restore_default_color (); | ||||
|         _rl_put_indicator (&_rl_color_indicator[C_LEFT]); | ||||
|         _rl_put_indicator (s); | ||||
|         _rl_put_indicator (&_rl_color_indicator[C_RIGHT]); | ||||
|         return 0; | ||||
|       } | ||||
|     else | ||||
|       return 1; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void | ||||
| _rl_prep_non_filename_text (void) | ||||
| { | ||||
|   if (_rl_color_indicator[C_END].string != NULL) | ||||
|     _rl_put_indicator (&_rl_color_indicator[C_END]); | ||||
|   else | ||||
|     { | ||||
|       _rl_put_indicator (&_rl_color_indicator[C_LEFT]); | ||||
|       _rl_put_indicator (&_rl_color_indicator[C_RESET]); | ||||
|       _rl_put_indicator (&_rl_color_indicator[C_RIGHT]); | ||||
|     } | ||||
| } | ||||
| #endif /* COLOR_SUPPORT */ | ||||
							
								
								
									
										122
									
								
								lib/readline/colors.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								lib/readline/colors.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,122 @@ | |||
| /* `dir', `vdir' and `ls' directory listing programs for GNU.
 | ||||
| 
 | ||||
|    Modified by Chet Ramey for Readline. | ||||
| 
 | ||||
|    Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012 Free Software Foundation, | ||||
|    Inc. | ||||
| 
 | ||||
|    This program 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 3 of the License, or | ||||
|    (at your option) any later version. | ||||
| 
 | ||||
|    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */
 | ||||
| 
 | ||||
| /* Written by Richard Stallman and David MacKenzie.  */ | ||||
| 
 | ||||
| /* Color support by Peter Anvin <Peter.Anvin@linux.org> and Dennis
 | ||||
|    Flaherty <dennisf@denix.elk.miles.com> based on original patches by | ||||
|    Greg Lee <lee@uhunix.uhcc.hawaii.edu>.  */ | ||||
| 
 | ||||
| #ifndef _COLORS_H_ | ||||
| #define _COLORS_H_ | ||||
| 
 | ||||
| #include <stdio.h> // size_t | ||||
| 
 | ||||
| #if defined(__TANDEM) && defined(HAVE_STDBOOL_H) && (__STDC_VERSION__ < 199901L) | ||||
| typedef int _Bool; | ||||
| #endif | ||||
| 
 | ||||
| #if defined (HAVE_STDBOOL_H) | ||||
| #  include <stdbool.h> // bool
 | ||||
| #else | ||||
| typedef int _rl_bool_t; | ||||
| 
 | ||||
| #ifdef bool | ||||
| #  undef bool | ||||
| #endif | ||||
| #define bool _rl_bool_t | ||||
| 
 | ||||
| #ifndef true | ||||
| #  define true 1 | ||||
| #  define false 0 | ||||
| #endif | ||||
| 
 | ||||
| #endif /* !HAVE_STDBOOL_H */ | ||||
| 
 | ||||
| /* Null is a valid character in a color indicator (think about Epson
 | ||||
|    printers, for example) so we have to use a length/buffer string | ||||
|    type. */ | ||||
| struct bin_str | ||||
|   { | ||||
|     size_t len; | ||||
|     const char *string; | ||||
|   }; | ||||
| 
 | ||||
| /* file type indicators (dir, sock, fifo, ...)
 | ||||
|    Default value is initialized in parse-colors.c. | ||||
|    It is then modified from the values of $LS_COLORS. */ | ||||
| extern struct bin_str _rl_color_indicator[]; | ||||
| 
 | ||||
| /* The LS_COLORS variable is in a termcap-like format. */ | ||||
| typedef struct _color_ext_type | ||||
|   { | ||||
|     struct bin_str ext;         	/* The extension we're looking for */ | ||||
|     struct bin_str seq;         	/* The sequence to output when we do */ | ||||
|     struct _color_ext_type *next;	/* Next in list */ | ||||
|   } COLOR_EXT_TYPE; | ||||
| 
 | ||||
| /* file extensions indicators (.txt, .log, .jpg, ...)
 | ||||
|    Values are taken from $LS_COLORS in rl_parse_colors(). */ | ||||
| extern COLOR_EXT_TYPE *_rl_color_ext_list; | ||||
| 
 | ||||
| #define FILETYPE_INDICATORS				\ | ||||
|   {							\ | ||||
|     C_ORPHAN, C_FIFO, C_CHR, C_DIR, C_BLK, C_FILE,	\ | ||||
|     C_LINK, C_SOCK, C_FILE, C_DIR			\ | ||||
|   } | ||||
| 
 | ||||
| /* Whether we used any colors in the output so far.  If so, we will
 | ||||
|    need to restore the default color later.  If not, we will need to | ||||
|    call prep_non_filename_text before using color for the first time. */ | ||||
| 
 | ||||
| enum indicator_no | ||||
|   { | ||||
|     C_LEFT, C_RIGHT, C_END, C_RESET, C_NORM, C_FILE, C_DIR, C_LINK, | ||||
|     C_FIFO, C_SOCK, | ||||
|     C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC, C_DOOR, C_SETUID, C_SETGID, | ||||
|     C_STICKY, C_OTHER_WRITABLE, C_STICKY_OTHER_WRITABLE, C_CAP, C_MULTIHARDLINK, | ||||
|     C_CLR_TO_EOL | ||||
|   }; | ||||
| 
 | ||||
| 
 | ||||
| #if !S_IXUGO | ||||
| # define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) | ||||
| #endif | ||||
| 
 | ||||
| enum filetype | ||||
|   { | ||||
|     unknown, | ||||
|     fifo, | ||||
|     chardev, | ||||
|     directory, | ||||
|     blockdev, | ||||
|     normal, | ||||
|     symbolic_link, | ||||
|     sock, | ||||
|     whiteout, | ||||
|     arg_directory | ||||
|   }; | ||||
| 
 | ||||
| extern void _rl_put_indicator (const struct bin_str *ind); | ||||
| extern void _rl_set_normal_color (void); | ||||
| extern bool _rl_print_color_indicator (char *f); | ||||
| extern void _rl_prep_non_filename_text (void); | ||||
| 
 | ||||
| #endif /* !_COLORS_H_ */ | ||||
|  | @ -1,6 +1,6 @@ | |||
| /* complete.c -- filename completion for readline. */ | ||||
| 
 | ||||
| /* Copyright (C) 1987-2011 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 1987-2012 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file is part of the GNU Readline Library (Readline), a library | ||||
|    for reading lines of text with interactive input and history editing. | ||||
|  | @ -31,6 +31,8 @@ | |||
| #  include <sys/file.h> | ||||
| #endif | ||||
| 
 | ||||
| #include <signal.h> | ||||
| 
 | ||||
| #if defined (HAVE_UNISTD_H) | ||||
| #  include <unistd.h> | ||||
| #endif /* HAVE_UNISTD_H */ | ||||
|  | @ -64,6 +66,10 @@ extern int errno; | |||
| #include "xmalloc.h" | ||||
| #include "rlprivate.h" | ||||
| 
 | ||||
| #if defined (COLOR_SUPPORT) | ||||
| #  include "colors.h" | ||||
| #endif | ||||
| 
 | ||||
| #ifdef __STDC__ | ||||
| typedef int QSFUNC (const void *, const void *); | ||||
| #else | ||||
|  | @ -94,17 +100,27 @@ extern struct passwd *getpwent PARAMS((void)); | |||
|    longest string in that array. */ | ||||
| rl_compdisp_func_t *rl_completion_display_matches_hook = (rl_compdisp_func_t *)NULL; | ||||
| 
 | ||||
| #if defined (VISIBLE_STATS) | ||||
| #if defined (VISIBLE_STATS) || defined (COLOR_SUPPORT) | ||||
| #  if !defined (X_OK) | ||||
| #    define X_OK 1 | ||||
| #  endif | ||||
| #endif | ||||
| 
 | ||||
| #if defined (VISIBLE_STATS) | ||||
| static int stat_char PARAMS((char *)); | ||||
| #endif | ||||
| 
 | ||||
| #if defined (COLOR_SUPPORT) | ||||
| static int colored_stat_start PARAMS((char *)); | ||||
| static void colored_stat_end PARAMS((void)); | ||||
| #endif | ||||
| 
 | ||||
| static int path_isdir PARAMS((const char *)); | ||||
| 
 | ||||
| static char *rl_quote_filename PARAMS((char *, int, char *)); | ||||
| 
 | ||||
| static void _rl_complete_sigcleanup PARAMS((int, void *)); | ||||
| 
 | ||||
| static void set_completion_defaults PARAMS((int)); | ||||
| static int get_y_or_n PARAMS((int)); | ||||
| static int _rl_internal_pager PARAMS((int)); | ||||
|  | @ -189,6 +205,12 @@ int _rl_completion_columns = -1; | |||
| int rl_visible_stats = 0; | ||||
| #endif /* VISIBLE_STATS */ | ||||
| 
 | ||||
| #if defined (COLOR_SUPPORT) | ||||
| /* Non-zero means to use colors to indicate file type when listing possible
 | ||||
|    completions.  The colors used are taken from $LS_COLORS, if set. */ | ||||
| int _rl_colored_stats = 0; | ||||
| #endif | ||||
| 
 | ||||
| /* If non-zero, when completing in the middle of a word, don't insert
 | ||||
|    characters from the match that match characters following point in | ||||
|    the word.  This means, for instance, completing when the cursor is | ||||
|  | @ -206,6 +228,8 @@ rl_icppfunc_t *rl_directory_completion_hook = (rl_icppfunc_t *)NULL; | |||
| 
 | ||||
| rl_icppfunc_t *rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL; | ||||
| 
 | ||||
| rl_icppfunc_t *rl_filename_stat_hook = (rl_icppfunc_t *)NULL; | ||||
| 
 | ||||
| /* If non-zero, this is the address of a function to call when reading
 | ||||
|    directory entries from the filesystem for completion and comparing | ||||
|    them to the partial word to be completed.  The function should | ||||
|  | @ -457,6 +481,15 @@ _rl_reset_completion_state () | |||
|   rl_completion_quote_character = 0; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| _rl_complete_sigcleanup (sig, ptr) | ||||
|      int sig; | ||||
|      void *ptr; | ||||
| { | ||||
|   if (sig == SIGINT)	/* XXX - for now */ | ||||
|     _rl_free_match_list ((char **)ptr); | ||||
| } | ||||
| 
 | ||||
| /* Set default values for readline word completion.  These are the variables
 | ||||
|    that application completion functions can change or inspect. */ | ||||
| static void | ||||
|  | @ -551,6 +584,8 @@ stat_char (filename) | |||
| { | ||||
|   struct stat finfo; | ||||
|   int character, r; | ||||
|   char *f; | ||||
|   const char *fn; | ||||
| 
 | ||||
|   /* Short-circuit a //server on cygwin, since that will always behave as
 | ||||
|      a directory. */ | ||||
|  | @ -559,10 +594,20 @@ stat_char (filename) | |||
|     return '/'; | ||||
| #endif | ||||
| 
 | ||||
|   f = 0; | ||||
|   if (rl_filename_stat_hook) | ||||
|     { | ||||
|       f = savestring (filename); | ||||
|       (*rl_filename_stat_hook) (&f); | ||||
|       fn = f; | ||||
|     } | ||||
|   else | ||||
|     fn = filename; | ||||
|      | ||||
| #if defined (HAVE_LSTAT) && defined (S_ISLNK) | ||||
|   r = lstat (filename, &finfo); | ||||
|   r = lstat (fn, &finfo); | ||||
| #else | ||||
|   r = stat (filename, &finfo); | ||||
|   r = stat (fn, &finfo); | ||||
| #endif | ||||
| 
 | ||||
|   if (r == -1) | ||||
|  | @ -596,10 +641,29 @@ stat_char (filename) | |||
|       if (access (filename, X_OK) == 0) | ||||
| 	character = '*'; | ||||
|     } | ||||
| 
 | ||||
|   free (f); | ||||
|   return (character); | ||||
| } | ||||
| #endif /* VISIBLE_STATS */ | ||||
| 
 | ||||
| #if defined (COLOR_SUPPORT) | ||||
| static int | ||||
| colored_stat_start (filename) | ||||
|      char *filename; | ||||
| { | ||||
|   _rl_set_normal_color (); | ||||
|   return (_rl_print_color_indicator (filename)); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| colored_stat_end () | ||||
| { | ||||
|   _rl_prep_non_filename_text (); | ||||
|   _rl_put_indicator (&_rl_color_indicator[C_CLR_TO_EOL]); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| /* Return the portion of PATHNAME that should be output when listing
 | ||||
|    possible completions.  If we are hacking filename completion, we | ||||
|    are only interested in the basename, the portion following the | ||||
|  | @ -679,7 +743,7 @@ fnwidth (string) | |||
| 	  else | ||||
| 	    { | ||||
| 	      pos += clen; | ||||
| 	      w = wcwidth (wc); | ||||
| 	      w = WCWIDTH (wc); | ||||
| 	      width += (w >= 0) ? w : 1; | ||||
| 	    } | ||||
| #else | ||||
|  | @ -766,7 +830,7 @@ fnprint (to_print, prefix_bytes) | |||
| 	    break; | ||||
| 	  else | ||||
| 	    { | ||||
| 	      w = wcwidth (wc); | ||||
| 	      w = WCWIDTH (wc); | ||||
| 	      width = (w >= 0) ? w : 1; | ||||
| 	    } | ||||
| 	  fwrite (s, 1, tlen, rl_outstream); | ||||
|  | @ -796,13 +860,20 @@ print_filename (to_print, full_pathname, prefix_bytes) | |||
|   char *s, c, *new_full_pathname, *dn; | ||||
| 
 | ||||
|   extension_char = 0; | ||||
|   printed_len = fnprint (to_print, prefix_bytes); | ||||
| 
 | ||||
| #if defined (VISIBLE_STATS) | ||||
|  if (rl_filename_completion_desired && (rl_visible_stats || _rl_complete_mark_directories)) | ||||
| #else | ||||
|  if (rl_filename_completion_desired && _rl_complete_mark_directories) | ||||
| #if defined (COLOR_SUPPORT) | ||||
|   /* Defer printing if we want to prefix with a color indicator */ | ||||
|   if (_rl_colored_stats == 0 || rl_filename_completion_desired == 0) | ||||
| #endif | ||||
|     printed_len = fnprint (to_print, prefix_bytes); | ||||
| 
 | ||||
|   if (rl_filename_completion_desired && ( | ||||
| #if defined (VISIBLE_STATS) | ||||
|      rl_visible_stats || | ||||
| #endif | ||||
| #if defined (COLOR_SUPPORT) | ||||
|      _rl_colored_stats || | ||||
| #endif | ||||
|      _rl_complete_mark_directories)) | ||||
|     { | ||||
|       /* If to_print != full_pathname, to_print is the basename of the
 | ||||
| 	 path passed.  In this case, we try to expand the directory | ||||
|  | @ -848,8 +919,28 @@ print_filename (to_print, full_pathname, prefix_bytes) | |||
| 	    extension_char = stat_char (new_full_pathname); | ||||
| 	  else | ||||
| #endif | ||||
| 	  if (path_isdir (new_full_pathname)) | ||||
| 	    extension_char = '/'; | ||||
| 	  if (_rl_complete_mark_directories) | ||||
| 	    { | ||||
| 	      dn = 0; | ||||
| 	      if (rl_directory_completion_hook == 0 && rl_filename_stat_hook) | ||||
| 		{ | ||||
| 		  dn = savestring (new_full_pathname); | ||||
| 		  (*rl_filename_stat_hook) (&dn); | ||||
| 		  free (new_full_pathname); | ||||
| 		  new_full_pathname = dn; | ||||
| 		} | ||||
| 	      if (path_isdir (new_full_pathname)) | ||||
| 		extension_char = '/'; | ||||
| 	    } | ||||
| 
 | ||||
| #if defined (COLOR_SUPPORT) | ||||
| 	  if (_rl_colored_stats) | ||||
| 	    { | ||||
| 	      colored_stat_start (new_full_pathname); | ||||
| 	      printed_len = fnprint (to_print, prefix_bytes); | ||||
| 	      colored_stat_end (); | ||||
| 	    } | ||||
| #endif | ||||
| 
 | ||||
| 	  xfree (new_full_pathname); | ||||
| 	  to_print[-1] = c; | ||||
|  | @ -862,8 +953,18 @@ print_filename (to_print, full_pathname, prefix_bytes) | |||
| 	    extension_char = stat_char (s); | ||||
| 	  else | ||||
| #endif | ||||
| 	    if (path_isdir (s)) | ||||
| 	    if (_rl_complete_mark_directories && path_isdir (s)) | ||||
| 	      extension_char = '/'; | ||||
| 
 | ||||
| #if defined (COLOR_SUPPORT) | ||||
| 	  if (_rl_colored_stats) | ||||
| 	    { | ||||
| 	      colored_stat_start (s); | ||||
| 	      printed_len = fnprint (to_print, prefix_bytes); | ||||
| 	      colored_stat_end (); | ||||
| 	    } | ||||
| #endif | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
|       xfree (s); | ||||
|  | @ -1058,10 +1159,13 @@ gen_completion_matches (text, start, end, our_func, found_quote, quote_char) | |||
|      variable rl_attempted_completion_function. */ | ||||
|   if (rl_attempted_completion_function) | ||||
|     { | ||||
|       _rl_interrupt_immediately++; | ||||
|       matches = (*rl_attempted_completion_function) (text, start, end); | ||||
|       if (_rl_interrupt_immediately > 0) | ||||
| 	_rl_interrupt_immediately--; | ||||
|       if (RL_SIG_RECEIVED()) | ||||
| 	{ | ||||
| 	  _rl_free_match_list (matches); | ||||
| 	  matches = 0; | ||||
| 	  RL_CHECK_SIGNALS (); | ||||
| 	} | ||||
| 
 | ||||
|       if (matches || rl_attempted_completion_over) | ||||
| 	{ | ||||
|  | @ -1072,7 +1176,15 @@ gen_completion_matches (text, start, end, our_func, found_quote, quote_char) | |||
| 
 | ||||
|   /* XXX -- filename dequoting moved into rl_filename_completion_function */ | ||||
| 
 | ||||
|   /* rl_completion_matches will check for signals as well to avoid a long
 | ||||
|      delay while reading a directory. */ | ||||
|   matches = rl_completion_matches (text, our_func); | ||||
|   if (RL_SIG_RECEIVED()) | ||||
|     { | ||||
|       _rl_free_match_list (matches); | ||||
|       matches = 0; | ||||
|       RL_CHECK_SIGNALS (); | ||||
|     } | ||||
|   return matches;   | ||||
| } | ||||
| 
 | ||||
|  | @ -1147,9 +1259,11 @@ compute_lcd_of_matches (match_list, matches, text) | |||
| { | ||||
|   register int i, c1, c2, si; | ||||
|   int low;		/* Count of max-matched characters. */ | ||||
|   int lx; | ||||
|   char *dtext;		/* dequoted TEXT, if needed */ | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
|   int v; | ||||
|   size_t v1, v2; | ||||
|   mbstate_t ps1, ps2; | ||||
|   wchar_t wc1, wc2; | ||||
| #endif | ||||
|  | @ -1182,14 +1296,20 @@ compute_lcd_of_matches (match_list, matches, text) | |||
| #if defined (HANDLE_MULTIBYTE) | ||||
| 	    if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | ||||
| 	      { | ||||
| 		v = mbrtowc (&wc1, match_list[i]+si, strlen (match_list[i]+si), &ps1); | ||||
| 		mbrtowc (&wc2, match_list[i+1]+si, strlen (match_list[i+1]+si), &ps2); | ||||
| 		v1 = mbrtowc(&wc1, match_list[i]+si, strlen (match_list[i]+si), &ps1); | ||||
| 		v2 = mbrtowc (&wc2, match_list[i+1]+si, strlen (match_list[i+1]+si), &ps2); | ||||
| 		if (MB_INVALIDCH (v1) || MB_INVALIDCH (v2)) | ||||
| 		  { | ||||
| 		    if (c1 != c2)	/* do byte comparison */ | ||||
| 		      break; | ||||
| 		    continue; | ||||
| 		  } | ||||
| 		wc1 = towlower (wc1); | ||||
| 		wc2 = towlower (wc2); | ||||
| 		if (wc1 != wc2) | ||||
| 		  break; | ||||
| 		else if (v > 1) | ||||
| 		  si += v - 1; | ||||
| 		else if (v1 > 1) | ||||
| 		  si += v1 - 1; | ||||
| 	      } | ||||
| 	    else | ||||
| #endif | ||||
|  | @ -1264,21 +1384,20 @@ compute_lcd_of_matches (match_list, matches, text) | |||
| 	  qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare); | ||||
| 
 | ||||
| 	  si = strlen (text); | ||||
| 	  if (si <= low) | ||||
| 	    { | ||||
| 	      for (i = 1; i <= matches; i++) | ||||
| 		if (strncmp (match_list[i], text, si) == 0) | ||||
| 		  { | ||||
| 		    strncpy (match_list[0], match_list[i], low); | ||||
| 		    break; | ||||
| 		  } | ||||
| 	      /* no casematch, use first entry */ | ||||
| 	      if (i > matches) | ||||
| 		strncpy (match_list[0], match_list[1], low); | ||||
| 	    } | ||||
| 	  else | ||||
| 	    /* otherwise, just use the text the user typed. */ | ||||
| 	    strncpy (match_list[0], text, low); | ||||
| 	  lx = (si <= low) ? si : low;	/* check shorter of text and matches */ | ||||
| 	  /* Try to preserve the case of what the user typed in the presence of
 | ||||
| 	     multiple matches: check each match for something that matches | ||||
| 	     what the user typed taking case into account; use it up to common | ||||
| 	     length of matches if one is found.  If not, just use first match. */ | ||||
| 	  for (i = 1; i <= matches; i++) | ||||
| 	    if (strncmp (match_list[i], text, lx) == 0) | ||||
| 	      { | ||||
| 		strncpy (match_list[0], match_list[i], low); | ||||
| 		break; | ||||
| 	      } | ||||
| 	  /* no casematch, use first entry */ | ||||
| 	  if (i > matches) | ||||
| 	    strncpy (match_list[0], match_list[1], low); | ||||
| 
 | ||||
| 	  FREE (dtext); | ||||
| 	} | ||||
|  | @ -1305,7 +1424,7 @@ postprocess_matches (matchesp, matching_filenames) | |||
|     return 0; | ||||
| 
 | ||||
|   /* It seems to me that in all the cases we handle we would like
 | ||||
|      to ignore duplicate possiblilities.  Scan for the text to | ||||
|      to ignore duplicate possibilities.  Scan for the text to | ||||
|      insert being identical to the other completions. */ | ||||
|   if (rl_ignore_completion_duplicates) | ||||
|     { | ||||
|  | @ -1463,7 +1582,7 @@ rl_display_match_list (matches, len, max) | |||
| 	  /* Have we reached the end of this line? */ | ||||
| 	  if (matches[i+1]) | ||||
| 	    { | ||||
| 	      if (i && (limit > 1) && (i % limit) == 0) | ||||
| 	      if (limit == 1 || (i && (limit > 1) && (i % limit) == 0)) | ||||
| 		{ | ||||
| 		  rl_crlf (); | ||||
| 		  lines++; | ||||
|  | @ -1672,7 +1791,7 @@ append_to_match (text, delimiter, quote_char, nontrivial_match) | |||
|      char *text; | ||||
|      int delimiter, quote_char, nontrivial_match; | ||||
| { | ||||
|   char temp_string[4], *filename; | ||||
|   char temp_string[4], *filename, *fn; | ||||
|   int temp_string_index, s; | ||||
|   struct stat finfo; | ||||
| 
 | ||||
|  | @ -1691,6 +1810,13 @@ append_to_match (text, delimiter, quote_char, nontrivial_match) | |||
|   if (rl_filename_completion_desired) | ||||
|     { | ||||
|       filename = tilde_expand (text); | ||||
|       if (rl_filename_stat_hook) | ||||
|         { | ||||
|           fn = savestring (filename); | ||||
| 	  (*rl_filename_stat_hook) (&fn); | ||||
| 	  xfree (filename); | ||||
| 	  filename = fn; | ||||
|         } | ||||
|       s = (nontrivial_match && rl_completion_mark_symlink_dirs == 0) | ||||
| 		? LSTAT (filename, &finfo) | ||||
| 		: stat (filename, &finfo); | ||||
|  | @ -1710,8 +1836,7 @@ append_to_match (text, delimiter, quote_char, nontrivial_match) | |||
| #ifdef S_ISLNK | ||||
|       /* Don't add anything if the filename is a symlink and resolves to a
 | ||||
| 	 directory. */ | ||||
|       else if (s == 0 && S_ISLNK (finfo.st_mode) && | ||||
| 	       stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode)) | ||||
|       else if (s == 0 && S_ISLNK (finfo.st_mode) && path_isdir (filename)) | ||||
| 	; | ||||
| #endif | ||||
|       else | ||||
|  | @ -1831,10 +1956,8 @@ rl_complete_internal (what_to_do) | |||
|   /* nontrivial_lcd is set if the common prefix adds something to the word
 | ||||
|      being completed. */ | ||||
|   nontrivial_lcd = matches && strcmp (text, matches[0]) != 0; | ||||
| #if 1 | ||||
|   if (what_to_do == '!' || what_to_do == '@') | ||||
|     tlen = strlen (text); | ||||
| #endif | ||||
|   xfree (text); | ||||
| 
 | ||||
|   if (matches == 0) | ||||
|  | @ -1868,10 +1991,6 @@ rl_complete_internal (what_to_do) | |||
|     case '!': | ||||
|     case '@': | ||||
|       /* Insert the first match with proper quoting. */ | ||||
| #if 0 | ||||
|       if (*matches[0]) | ||||
| 	insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, "e_char); | ||||
| #else | ||||
|       if (what_to_do == TAB) | ||||
|         { | ||||
|           if (*matches[0]) | ||||
|  | @ -1886,7 +2005,6 @@ rl_complete_internal (what_to_do) | |||
| 	  if (mlen >= tlen) | ||||
| 	    insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, "e_char); | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
|       /* If there are more matches, ring the bell to indicate.
 | ||||
| 	 If we are in vi mode, Posix.2 says to not ring the bell. | ||||
|  | @ -1922,7 +2040,14 @@ rl_complete_internal (what_to_do) | |||
|       break; | ||||
| 
 | ||||
|     case '?': | ||||
|       if (rl_completion_display_matches_hook == 0) | ||||
| 	{ | ||||
| 	  _rl_sigcleanup = _rl_complete_sigcleanup; | ||||
| 	  _rl_sigcleanarg = matches; | ||||
| 	} | ||||
|       display_matches (matches); | ||||
|       _rl_sigcleanup = 0; | ||||
|       _rl_sigcleanarg = 0; | ||||
|       break; | ||||
| 
 | ||||
|     default: | ||||
|  | @ -1930,6 +2055,7 @@ rl_complete_internal (what_to_do) | |||
|       rl_ding (); | ||||
|       FREE (saved_line_buffer); | ||||
|       RL_UNSETSTATE(RL_STATE_COMPLETING); | ||||
|       _rl_free_match_list (matches); | ||||
|       _rl_reset_completion_state (); | ||||
|       return 1; | ||||
|     } | ||||
|  | @ -1971,6 +2097,8 @@ rl_completion_matches (text, entry_function) | |||
|      const char *text; | ||||
|      rl_compentry_func_t *entry_function; | ||||
| { | ||||
|   register int i; | ||||
| 
 | ||||
|   /* Number of slots in match_list. */ | ||||
|   int match_list_size; | ||||
| 
 | ||||
|  | @ -1988,18 +2116,36 @@ rl_completion_matches (text, entry_function) | |||
|   match_list = (char **)xmalloc ((match_list_size + 1) * sizeof (char *)); | ||||
|   match_list[1] = (char *)NULL; | ||||
| 
 | ||||
|   _rl_interrupt_immediately++; | ||||
|   while (string = (*entry_function) (text, matches)) | ||||
|     { | ||||
|       if (matches + 1 == match_list_size) | ||||
|       if (RL_SIG_RECEIVED ()) | ||||
| 	{ | ||||
| 	  /* Start at 1 because we don't set matches[0] in this function.
 | ||||
| 	     Only free the list members if we're building match list from | ||||
| 	     rl_filename_completion_function, since we know that doesn't | ||||
| 	     free the strings it returns. */ | ||||
| 	  if (entry_function == rl_filename_completion_function) | ||||
| 	    { | ||||
| 	      for (i = 1; match_list[i]; i++) | ||||
| 		xfree (match_list[i]); | ||||
| 	    } | ||||
| 	  xfree (match_list); | ||||
| 	  match_list = 0; | ||||
| 	  match_list_size = 0; | ||||
| 	  matches = 0; | ||||
| 	  RL_CHECK_SIGNALS (); | ||||
| 	} | ||||
| 
 | ||||
|       if (matches + 1 >= match_list_size) | ||||
| 	match_list = (char **)xrealloc | ||||
| 	  (match_list, ((match_list_size += 10) + 1) * sizeof (char *)); | ||||
| 
 | ||||
|       if (match_list == 0) | ||||
| 	return (match_list); | ||||
| 
 | ||||
|       match_list[++matches] = string; | ||||
|       match_list[matches + 1] = (char *)NULL; | ||||
|     } | ||||
|   if (_rl_interrupt_immediately > 0) | ||||
|     _rl_interrupt_immediately--; | ||||
| 
 | ||||
|   /* If there were any matches, then look through them finding out the
 | ||||
|      lowest common denominator.  That then becomes match_list[0]. */ | ||||
|  | @ -2038,7 +2184,9 @@ rl_username_completion_function (text, state) | |||
| 
 | ||||
|       username = savestring (&text[first_char_loc]); | ||||
|       namelen = strlen (username); | ||||
| #if defined (HAVE_GETPWENT) | ||||
|       setpwent (); | ||||
| #endif | ||||
|     } | ||||
| 
 | ||||
| #if defined (HAVE_GETPWENT) | ||||
|  | @ -2075,8 +2223,9 @@ rl_username_completion_function (text, state) | |||
| 
 | ||||
| /* Return non-zero if CONVFN matches FILENAME up to the length of FILENAME
 | ||||
|    (FILENAME_LEN).  If _rl_completion_case_fold is set, compare without | ||||
|    regard to the alphabetic case of characters.  CONVFN is the possibly- | ||||
|    converted directory entry; FILENAME is what the user typed. */ | ||||
|    regard to the alphabetic case of characters.  If | ||||
|    _rl_completion_case_map is set, make `-' and `_' equivalent.  CONVFN is | ||||
|    the possibly-converted directory entry; FILENAME is what the user typed. */ | ||||
| static int | ||||
| complete_fncmp (convfn, convlen, filename, filename_len) | ||||
|      const char *convfn; | ||||
|  | @ -2086,34 +2235,110 @@ complete_fncmp (convfn, convlen, filename, filename_len) | |||
| { | ||||
|   register char *s1, *s2; | ||||
|   int d, len; | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
|   size_t v1, v2; | ||||
|   mbstate_t ps1, ps2; | ||||
|   wchar_t wc1, wc2; | ||||
| #endif | ||||
| 
 | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
|   memset (&ps1, 0, sizeof (mbstate_t)); | ||||
|   memset (&ps2, 0, sizeof (mbstate_t)); | ||||
| #endif | ||||
| 
 | ||||
|   if (filename_len == 0) | ||||
|     return 1; | ||||
|   if (convlen < filename_len) | ||||
|     return 0; | ||||
| 
 | ||||
|   len = filename_len; | ||||
|   s1 = (char *)convfn; | ||||
|   s2 = (char *)filename; | ||||
| 
 | ||||
|   /* Otherwise, if these match up to the length of filename, then
 | ||||
|      it is a match. */ | ||||
|   if (_rl_completion_case_fold && _rl_completion_case_map) | ||||
|     { | ||||
|       /* Case-insensitive comparison treating _ and - as equivalent */ | ||||
|       if (filename_len == 0) | ||||
| 	return 1; | ||||
|       if (convlen < filename_len) | ||||
| 	return 0; | ||||
|       s1 = (char *)convfn; | ||||
|       s2 = (char *)filename; | ||||
|       len = filename_len; | ||||
|       do | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
|       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | ||||
| 	{ | ||||
| 	  d = _rl_to_lower (*s1) - _rl_to_lower (*s2); | ||||
| 	  /* *s1 == [-_] && *s2 == [-_] */ | ||||
| 	  if ((*s1 == '-' || *s1 == '_') && (*s2 == '-' || *s2 == '_')) | ||||
| 	    d = 0; | ||||
| 	  if (d != 0) | ||||
| 	    return 0; | ||||
| 	  s1++; s2++;	/* already checked convlen >= filename_len */ | ||||
| 	  do | ||||
| 	    { | ||||
| 	      v1 = mbrtowc (&wc1, s1, convlen, &ps1); | ||||
| 	      v2 = mbrtowc (&wc2, s2, filename_len, &ps2); | ||||
| 	      if (v1 == 0 && v2 == 0) | ||||
| 		return 1; | ||||
| 	      else if (MB_INVALIDCH (v1) || MB_INVALIDCH (v2)) | ||||
| 		{ | ||||
| 		  if (*s1 != *s2)		/* do byte comparison */ | ||||
| 		    return 0; | ||||
| 		  else if ((*s1 == '-' || *s1 == '_') && (*s2 == '-' || *s2 == '_')) | ||||
| 		    return 0; | ||||
| 		  s1++; s2++; len--; | ||||
| 		  continue; | ||||
| 		} | ||||
| 	      wc1 = towlower (wc1); | ||||
| 	      wc2 = towlower (wc2); | ||||
| 	      s1 += v1; | ||||
| 	      s2 += v1; | ||||
| 	      len -= v1; | ||||
| 	      if ((wc1 == L'-' || wc1 == L'_') && (wc2 == L'-' || wc2 == L'_')) | ||||
| 	        continue; | ||||
| 	      if (wc1 != wc2) | ||||
| 		return 0; | ||||
| 	    } | ||||
| 	  while (len != 0); | ||||
| 	} | ||||
|       while (--len != 0); | ||||
|       else | ||||
| #endif | ||||
| 	{ | ||||
| 	do | ||||
| 	  { | ||||
| 	    d = _rl_to_lower (*s1) - _rl_to_lower (*s2); | ||||
| 	    /* *s1 == [-_] && *s2 == [-_] */ | ||||
| 	    if ((*s1 == '-' || *s1 == '_') && (*s2 == '-' || *s2 == '_')) | ||||
| 	      d = 0; | ||||
| 	    if (d != 0) | ||||
| 	      return 0; | ||||
| 	    s1++; s2++;	/* already checked convlen >= filename_len */ | ||||
| 	  } | ||||
| 	while (--len != 0); | ||||
| 	} | ||||
| 
 | ||||
|       return 1; | ||||
|     } | ||||
|   else if (_rl_completion_case_fold) | ||||
|     { | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
|       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | ||||
| 	{ | ||||
| 	  do | ||||
| 	    { | ||||
| 	      v1 = mbrtowc (&wc1, s1, convlen, &ps1); | ||||
| 	      v2 = mbrtowc (&wc2, s2, filename_len, &ps2); | ||||
| 	      if (v1 == 0 && v2 == 0) | ||||
| 		return 1; | ||||
| 	      else if (MB_INVALIDCH (v1) || MB_INVALIDCH (v2)) | ||||
| 		{ | ||||
| 		  if (*s1 != *s2)		/* do byte comparison */ | ||||
| 		    return 0; | ||||
| 		  s1++; s2++; len--; | ||||
| 		  continue; | ||||
| 		} | ||||
| 	      wc1 = towlower (wc1); | ||||
| 	      wc2 = towlower (wc2); | ||||
| 	      if (wc1 != wc2) | ||||
| 		return 0; | ||||
| 	      s1 += v1; | ||||
| 	      s2 += v1; | ||||
| 	      len -= v1; | ||||
| 	    } | ||||
| 	  while (len != 0); | ||||
| 	  return 1; | ||||
| 	} | ||||
|       else | ||||
| #endif | ||||
|       if ((_rl_to_lower (convfn[0]) == _rl_to_lower (filename[0])) && | ||||
| 	  (convlen >= filename_len) && | ||||
| 	  (_rl_strnicmp (filename, convfn, filename_len) == 0)) | ||||
|  | @ -2233,8 +2458,9 @@ rl_filename_completion_function (text, state) | |||
| 	} | ||||
|       directory = opendir (dirname); | ||||
| 
 | ||||
|       /* Now dequote a non-null filename. */ | ||||
|       if (filename && *filename && rl_completion_found_quote && rl_filename_dequoting_function) | ||||
|       /* Now dequote a non-null filename.  FILENAME will not be NULL, but may
 | ||||
| 	 be empty. */ | ||||
|       if (*filename && rl_completion_found_quote && rl_filename_dequoting_function) | ||||
| 	{ | ||||
| 	  /* delete single and double quotes */ | ||||
| 	  temp = (*rl_filename_dequoting_function) (filename, rl_completion_quote_character); | ||||
|  | @ -2598,6 +2824,11 @@ rl_menu_complete (count, ignore) | |||
| 	      full_completion = 1; | ||||
| 	      return (0); | ||||
| 	    } | ||||
| 	  else if (_rl_menu_complete_prefix_first) | ||||
| 	    { | ||||
| 	      rl_ding (); | ||||
| 	      return (0); | ||||
| 	    } | ||||
| 	} | ||||
|       else if (match_list_size <= 1) | ||||
| 	{ | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| /* display.c -- readline redisplay facility. */ | ||||
| 
 | ||||
| /* Copyright (C) 1987-2009 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 1987-2013 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file is part of the GNU Readline Library (Readline), a library     | ||||
|    for reading lines of text with interactive input and history editing. | ||||
|  | @ -41,6 +41,10 @@ | |||
| 
 | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| #ifdef __MSDOS__ | ||||
| #  include <pc.h> | ||||
| #endif | ||||
| 
 | ||||
| /* System-specific feature definitions and include files. */ | ||||
| #include "rldefs.h" | ||||
| #include "rlmbutil.h" | ||||
|  | @ -63,6 +67,7 @@ static void update_line PARAMS((char *, char *, int, int, int, int)); | |||
| static void space_to_eol PARAMS((int)); | ||||
| static void delete_chars PARAMS((int)); | ||||
| static void insert_some_chars PARAMS((char *, int, int)); | ||||
| static void open_some_spaces PARAMS((int)); | ||||
| static void cr PARAMS((void)); | ||||
| 
 | ||||
| /* State of visible and invisible lines. */ | ||||
|  | @ -165,6 +170,7 @@ int _rl_last_v_pos = 0; | |||
| 
 | ||||
| static int cpos_adjusted; | ||||
| static int cpos_buffer_position; | ||||
| static int displaying_prompt_first_line; | ||||
| static int prompt_multibyte_chars; | ||||
| 
 | ||||
| /* Number of lines currently on screen minus 1. */ | ||||
|  | @ -176,7 +182,8 @@ int _rl_vis_botlin = 0; | |||
| static int last_lmargin; | ||||
| 
 | ||||
| /* A buffer for `modeline' messages. */ | ||||
| static char msg_buf[128]; | ||||
| static char *msg_buf = 0; | ||||
| static int msg_bufsiz = 0; | ||||
| 
 | ||||
| /* Non-zero forces the redisplay even if we thought it was unnecessary. */ | ||||
| static int forced_display; | ||||
|  | @ -232,6 +239,18 @@ static int saved_local_length; | |||
| static int saved_invis_chars_first_line; | ||||
| static int saved_physical_chars; | ||||
| 
 | ||||
| /* Return a character indicating the editing mode, for use in the prompt. */ | ||||
| static int | ||||
| prompt_modechar () | ||||
| { | ||||
|   if (rl_editing_mode == emacs_mode) | ||||
|     return '@'; | ||||
|   else if (_rl_keymap == vi_insertion_keymap) | ||||
|     return '+';		/* vi insert mode */ | ||||
|   else | ||||
|     return ':';		/* vi command mode */ | ||||
| } | ||||
| 
 | ||||
| /* Expand the prompt string S and return the number of visible
 | ||||
|    characters in *LP, if LP is not null.  This is currently more-or-less | ||||
|    a placeholder for expansion.  LIP, if non-null is a place to store the | ||||
|  | @ -258,7 +277,16 @@ expand_prompt (pmt, lp, lip, niflp, vlp) | |||
|   /* Short-circuit if we can. */ | ||||
|   if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (pmt, RL_PROMPT_START_IGNORE) == 0) | ||||
|     { | ||||
|       r = savestring (pmt); | ||||
|       if (pmt == rl_prompt && _rl_show_mode_in_prompt) | ||||
|         { | ||||
|           l = strlen (pmt); | ||||
|           r = (char *)xmalloc (l + 2); | ||||
|           r[0] = prompt_modechar (); | ||||
|           strcpy (r + 1, pmt); | ||||
|         } | ||||
|       else | ||||
| 	r = savestring (pmt); | ||||
| 
 | ||||
|       if (lp) | ||||
| 	*lp = strlen (r); | ||||
|       if (lip) | ||||
|  | @ -271,13 +299,20 @@ expand_prompt (pmt, lp, lip, niflp, vlp) | |||
|     } | ||||
| 
 | ||||
|   l = strlen (pmt); | ||||
|   r = ret = (char *)xmalloc (l + 1); | ||||
|   r = ret = (char *)xmalloc (l + 2); | ||||
| 
 | ||||
|   rl = physchars = 0;	/* move up here so mode show can set them */ | ||||
|   if (pmt == rl_prompt && _rl_show_mode_in_prompt) | ||||
|     { | ||||
|       *r++ = prompt_modechar (); | ||||
|       rl = physchars = 1; | ||||
|     } | ||||
| 
 | ||||
|   invfl = 0;	/* invisible chars in first line of prompt */ | ||||
|   invflset = 0;	/* we only want to set invfl once */ | ||||
| 
 | ||||
|   igstart = 0; | ||||
|   for (rl = ignoring = last = ninvis = physchars = 0, p = pmt; p && *p; p++) | ||||
|   for (ignoring = last = ninvis = 0, p = pmt; p && *p; p++) | ||||
|     { | ||||
|       /* This code strips the invisible character string markers
 | ||||
| 	 RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */ | ||||
|  | @ -366,6 +401,12 @@ _rl_strip_prompt (pmt) | |||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| _rl_reset_prompt () | ||||
| { | ||||
|   rl_visible_prompt_length = rl_expand_prompt (rl_prompt); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Expand the prompt string into the various display components, if | ||||
|  * necessary. | ||||
|  | @ -707,10 +748,9 @@ rl_redisplay () | |||
|       /* Now account for invisible characters in the current line. */ | ||||
|       /* XXX - this assumes that the invisible characters may be split, but only
 | ||||
| 	 between the first and the last lines. */ | ||||
|       temp += ((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line | ||||
| 							     : ((newlines == prompt_lines_estimate) ? wrap_offset : prompt_invis_chars_first_line)) | ||||
| 					  : ((newlines == 0) ? wrap_offset : 0)); | ||||
|               | ||||
|       temp += (newlines == 0) ? prompt_invis_chars_first_line | ||||
| 			      : ((newlines == prompt_lines_estimate) ? wrap_offset : prompt_invis_chars_first_line); | ||||
| 
 | ||||
|       inv_lbreaks[++newlines] = temp; | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
|       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0) | ||||
|  | @ -761,7 +801,7 @@ rl_redisplay () | |||
| 	    break;			/* Found '\0' */ | ||||
| 	  else | ||||
| 	    { | ||||
| 	      temp = wcwidth (wc); | ||||
| 	      temp = WCWIDTH (wc); | ||||
| 	      wc_width = (temp >= 0) ? temp : 1; | ||||
| 	    } | ||||
| 	} | ||||
|  | @ -925,7 +965,7 @@ rl_redisplay () | |||
|   /* If we can move the cursor up and down, then use multiple lines,
 | ||||
|      otherwise, let long lines display in a single terminal line, and | ||||
|      horizontally scroll it. */ | ||||
| 
 | ||||
|   displaying_prompt_first_line = 1; | ||||
|   if (_rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up) | ||||
|     { | ||||
|       int nleft, pos, changed_screen_line, tx; | ||||
|  | @ -1179,6 +1219,8 @@ rl_redisplay () | |||
|       else | ||||
| 	lmargin = last_lmargin; | ||||
| 
 | ||||
|       displaying_prompt_first_line = lmargin < nleft; | ||||
| 
 | ||||
|       /* If the first character on the screen isn't the first character
 | ||||
| 	 in the display line, indicate this with a special character. */ | ||||
|       if (lmargin > 0) | ||||
|  | @ -1204,7 +1246,8 @@ rl_redisplay () | |||
| 		       _rl_screenwidth + (lmargin ? 0 : wrap_offset), | ||||
| 		       0); | ||||
| 
 | ||||
| 	  if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && OLD_CPOS_IN_PROMPT()) | ||||
| 	  if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && | ||||
| 		displaying_prompt_first_line && OLD_CPOS_IN_PROMPT()) | ||||
| 	    _rl_last_c_pos -= prompt_invis_chars_first_line;	/* XXX - was wrap_offset */ | ||||
| 
 | ||||
| 	  /* If the visible new line is shorter than the old, but the number
 | ||||
|  | @ -1212,7 +1255,7 @@ rl_redisplay () | |||
| 	     the new line, we need to clear to eol. */ | ||||
| 	  t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset); | ||||
| 	  if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) && | ||||
| 	      (_rl_last_c_pos == out) && | ||||
| 	      (_rl_last_c_pos == out) && displaying_prompt_first_line && | ||||
| 	      t < visible_first_line_len) | ||||
| 	    { | ||||
| 	      nleft = _rl_screenwidth - t; | ||||
|  | @ -1274,6 +1317,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) | |||
|   int temp, lendiff, wsatend, od, nd, twidth, o_cpos; | ||||
|   int current_invis_chars; | ||||
|   int col_lendiff, col_temp; | ||||
|   int bytes_to_insert; | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
|   mbstate_t ps_new, ps_old; | ||||
|   int new_offset, old_offset; | ||||
|  | @ -1300,7 +1344,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) | |||
| 	  size_t ret; | ||||
| 
 | ||||
| 	  /* This fixes only double-column characters, but if the wrapped
 | ||||
| 	     character comsumes more than three columns, spaces will be | ||||
| 	     character consumes more than three columns, spaces will be | ||||
| 	     inserted in the string buffer. */ | ||||
| 	  if (current_line < line_state_visible->wbsize && line_state_visible->wrapped_line[current_line] > 0) | ||||
| 	    _rl_clear_to_eol (line_state_visible->wrapped_line[current_line]); | ||||
|  | @ -1315,7 +1359,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) | |||
| 	  else if (MB_NULLWCH (ret)) | ||||
| 	    tempwidth = 0; | ||||
| 	  else | ||||
| 	    tempwidth = wcwidth (wc); | ||||
| 	    tempwidth = WCWIDTH (wc); | ||||
| 
 | ||||
| 	  if (tempwidth > 0) | ||||
| 	    { | ||||
|  | @ -1335,7 +1379,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) | |||
| 		  memcpy (old, new, bytes); | ||||
| 		  /* Fix up indices if we copy data from one line to another */ | ||||
| 		  omax += bytes - ret; | ||||
| 		  for (i = current_line+1; i < inv_botlin+1; i++) | ||||
| 		  for (i = current_line+1; i <= inv_botlin+1; i++) | ||||
| 		    vis_lbreaks[i] += bytes - ret; | ||||
| 		} | ||||
| 	    } | ||||
|  | @ -1372,6 +1416,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) | |||
|       temp = (omax < nmax) ? omax : nmax; | ||||
|       if (memcmp (old, new, temp) == 0)		/* adding at the end */ | ||||
| 	{ | ||||
| 	  new_offset = old_offset = temp; | ||||
| 	  ofd = old + temp; | ||||
| 	  nfd = new + temp; | ||||
| 	} | ||||
|  | @ -1382,6 +1427,8 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) | |||
| 
 | ||||
| 	  if (omax == nmax && STREQN (new, old, omax)) | ||||
| 	    { | ||||
| 	      old_offset = omax; | ||||
| 	      new_offset = nmax; | ||||
| 	      ofd = old + omax; | ||||
| 	      nfd = new + nmax; | ||||
| 	    } | ||||
|  | @ -1394,6 +1441,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) | |||
| 		{ | ||||
| 		  old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY); | ||||
| 		  new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY); | ||||
| 
 | ||||
| 		  ofd = old + old_offset; | ||||
| 		  nfd = new + new_offset; | ||||
| 		} | ||||
|  | @ -1417,6 +1465,27 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) | |||
|   if (ofd == oe && nfd == ne) | ||||
|     return; | ||||
| 
 | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
|   if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && _rl_utf8locale) | ||||
|     { | ||||
|       wchar_t wc; | ||||
|       mbstate_t ps = { 0 }; | ||||
|       int t; | ||||
| 
 | ||||
|       /* If the first character in the difference is a zero-width character,
 | ||||
| 	 assume it's a combining character and back one up so the two base | ||||
| 	 characters no longer compare equivalently. */ | ||||
|       t = mbrtowc (&wc, ofd, MB_CUR_MAX, &ps); | ||||
|       if (t > 0 && UNICODE_COMBINING_CHAR (wc) && WCWIDTH (wc) == 0) | ||||
| 	{ | ||||
| 	  old_offset = _rl_find_prev_mbchar (old, ofd - old, MB_FIND_ANY); | ||||
| 	  new_offset = _rl_find_prev_mbchar (new, nfd - new, MB_FIND_ANY); | ||||
| 	  ofd = old + old_offset;	/* equal by definition */ | ||||
| 	  nfd = new + new_offset; | ||||
| 	} | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|   wsatend = 1;			/* flag for trailing whitespace */ | ||||
| 
 | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
|  | @ -1424,6 +1493,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) | |||
|     { | ||||
|       ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY); | ||||
|       nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY); | ||||
| 
 | ||||
|       while ((ols > ofd) && (nls > nfd)) | ||||
| 	{ | ||||
| 	  memset (&ps_old, 0, sizeof (mbstate_t)); | ||||
|  | @ -1540,10 +1610,10 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) | |||
|   o_cpos = _rl_last_c_pos; | ||||
| 
 | ||||
|   /* When this function returns, _rl_last_c_pos is correct, and an absolute
 | ||||
|      cursor postion in multibyte mode, but a buffer index when not in a | ||||
|      cursor position in multibyte mode, but a buffer index when not in a | ||||
|      multibyte locale. */ | ||||
|   _rl_move_cursor_relative (od, old); | ||||
| #if 1 | ||||
| 
 | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
|   /* We need to indicate that the cursor position is correct in the presence of
 | ||||
|      invisible characters in the prompt string.  Let's see if setting this when | ||||
|  | @ -1552,12 +1622,11 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) | |||
|       (_rl_last_c_pos > 0 || o_cpos > 0) && | ||||
|       _rl_last_c_pos == prompt_physical_chars) | ||||
|     cpos_adjusted = 1; | ||||
| #endif | ||||
| #endif | ||||
| 
 | ||||
|   /* if (len (new) > len (old))
 | ||||
|      lendiff == difference in buffer | ||||
|      col_lendiff == difference on screen | ||||
|      lendiff == difference in buffer (bytes) | ||||
|      col_lendiff == difference on screen (columns) | ||||
|      When not using multibyte characters, these are equal */ | ||||
|   lendiff = (nls - nfd) - (ols - ofd); | ||||
|   if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | ||||
|  | @ -1583,6 +1652,10 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) | |||
| 	} | ||||
|     } | ||||
| 
 | ||||
|   /* We use temp as a count of the number of bytes from the first difference
 | ||||
|      to the end of the new line.  col_temp is the corresponding number of | ||||
|      screen columns.  A `dumb' update moves to the spot of first difference | ||||
|      and writes TEMP bytes. */ | ||||
|   /* Insert (diff (len (old), len (new)) ch. */ | ||||
|   temp = ne - nfd; | ||||
|   if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | ||||
|  | @ -1590,6 +1663,10 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) | |||
|   else | ||||
|     col_temp = temp; | ||||
| 
 | ||||
|   /* how many bytes from the new line buffer to write to the display */ | ||||
|   bytes_to_insert = nls - nfd; | ||||
| 
 | ||||
|   /* col_lendiff > 0 if we are adding characters to the line */ | ||||
|   if (col_lendiff > 0)	/* XXX - was lendiff */ | ||||
|     { | ||||
|       /* Non-zero if we're increasing the number of lines. */ | ||||
|  | @ -1603,11 +1680,11 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) | |||
|       if (lendiff < 0) | ||||
| 	{ | ||||
| 	  _rl_output_some_chars (nfd, temp); | ||||
| 	  _rl_last_c_pos += _rl_col_width (nfd, 0, temp, 1); | ||||
| 	  _rl_last_c_pos += col_temp;	/* XXX - was _rl_col_width (nfd, 0, temp, 1); */ | ||||
| 	  /* If nfd begins before any invisible characters in the prompt,
 | ||||
| 	     adjust _rl_last_c_pos to account for wrap_offset and set | ||||
| 	     cpos_adjusted to let the caller know. */ | ||||
| 	  if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible)) | ||||
| 	  if (current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible)) | ||||
| 	    { | ||||
| 	      _rl_last_c_pos -= wrap_offset; | ||||
| 	      cpos_adjusted = 1; | ||||
|  | @ -1638,57 +1715,42 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) | |||
| 		        (col_lendiff < prompt_visible_length)) == 0) && | ||||
| 		      (visible_wrap_offset >= current_invis_chars)) | ||||
| 	    { | ||||
| 	      insert_some_chars (nfd, lendiff, col_lendiff); | ||||
| 	      _rl_last_c_pos += col_lendiff; | ||||
| 	      open_some_spaces (col_lendiff); | ||||
| 	      _rl_output_some_chars (nfd, bytes_to_insert); | ||||
| 	      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | ||||
| 		_rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, 1); | ||||
| 	      else | ||||
| 		_rl_last_c_pos += bytes_to_insert; | ||||
| 	    } | ||||
| #if 0		/* XXX - for now */
 | ||||
| 	  else if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && _rl_last_c_pos == 0 && wrap_offset && (nfd-new) <= prompt_last_invisible && col_lendiff < prompt_visible_length && visible_wrap_offset >= current_invis_chars) | ||||
| 	    { | ||||
| 	      _rl_output_some_chars (nfd, lendiff); | ||||
| 	      _rl_last_c_pos += col_lendiff; | ||||
| 	    } | ||||
| #endif | ||||
| 	  else if ((MB_CUR_MAX == 1 || rl_byte_oriented != 0) && *ols == 0 && lendiff > 0) | ||||
| 	    { | ||||
| 	      /* At the end of a line the characters do not have to
 | ||||
| 		 be "inserted".  They can just be placed on the screen. */ | ||||
| 	      /* However, this screws up the rest of this block, which
 | ||||
| 		 assumes you've done the insert because you can. */ | ||||
| 	      _rl_output_some_chars (nfd, lendiff); | ||||
| 	      _rl_last_c_pos += col_lendiff; | ||||
| 	      _rl_output_some_chars (nfd, temp); | ||||
| 	      _rl_last_c_pos += col_temp; | ||||
| 	      return; | ||||
| 	    } | ||||
| 	  else | ||||
| 	  else	/* just write from first difference to end of new line */ | ||||
| 	    { | ||||
| 	      _rl_output_some_chars (nfd, temp); | ||||
| 	      _rl_last_c_pos += col_temp; | ||||
| 	      /* If nfd begins before the last invisible character in the
 | ||||
| 		 prompt, adjust _rl_last_c_pos to account for wrap_offset | ||||
| 		 and set cpos_adjusted to let the caller know. */ | ||||
| 	      if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible)) | ||||
| 	      if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible)) | ||||
| 		{ | ||||
| 		  _rl_last_c_pos -= wrap_offset; | ||||
| 		  cpos_adjusted = 1; | ||||
| 		} | ||||
| 	      return; | ||||
| 	    } | ||||
| 	  /* Copy (new) chars to screen from first diff to last match. */ | ||||
| 	  temp = nls - nfd; | ||||
| 	  if ((temp - lendiff) > 0) | ||||
| 
 | ||||
| 	  if (bytes_to_insert > lendiff) | ||||
| 	    { | ||||
| 	      _rl_output_some_chars (nfd + lendiff, temp - lendiff); | ||||
| 	     /* XXX -- this bears closer inspection.  Fixes a redisplay bug
 | ||||
| 		reported against bash-3.0-alpha by Andreas Schwab involving | ||||
| 		multibyte characters and prompt strings with invisible | ||||
| 		characters, but was previously disabled. */ | ||||
| 	      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | ||||
| 		twidth = _rl_col_width (nfd+lendiff, 0, temp-col_lendiff, 1); | ||||
| 	      else | ||||
| 		twidth = temp - lendiff; | ||||
| 	      _rl_last_c_pos += twidth; | ||||
| 	      /* If nfd begins before the last invisible character in the
 | ||||
| 		 prompt, adjust _rl_last_c_pos to account for wrap_offset | ||||
| 		 and set cpos_adjusted to let the caller know. */ | ||||
| 	      if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible)) | ||||
| 	      if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible)) | ||||
| 		{ | ||||
| 		  _rl_last_c_pos -= wrap_offset; | ||||
| 		  cpos_adjusted = 1; | ||||
|  | @ -1706,6 +1768,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) | |||
| 	     a physical character position. */ | ||||
| 	  if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && | ||||
| 		current_line == prompt_last_screen_line && wrap_offset && | ||||
| 		displaying_prompt_first_line && | ||||
| 		wrap_offset != prompt_invis_chars_first_line && | ||||
| 		((nfd-new) < (prompt_last_invisible-(current_line*_rl_screenwidth)))) | ||||
| 	    { | ||||
|  | @ -1723,32 +1786,47 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) | |||
| 	     prompt string, don't bother.  It screws up the assumptions | ||||
| 	     about what's on the screen. */ | ||||
| 	  if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 && | ||||
| 	      displaying_prompt_first_line && | ||||
| 	      -lendiff == visible_wrap_offset) | ||||
| 	    col_lendiff = 0; | ||||
| 
 | ||||
| 	  /* If we have moved lmargin and we're shrinking the line, we've
 | ||||
| 	     already moved the cursor to the first character of the new line, | ||||
| 	     so deleting -col_lendiff characters will mess up the cursor | ||||
| 	     position calculation */ | ||||
| 	  if (_rl_horizontal_scroll_mode && displaying_prompt_first_line == 0 && | ||||
| 		col_lendiff && _rl_last_c_pos < -col_lendiff) | ||||
| 	    col_lendiff = 0; | ||||
| 
 | ||||
| 	  if (col_lendiff) | ||||
| 	    delete_chars (-col_lendiff); /* delete (diff) characters */ | ||||
| 
 | ||||
| 	  /* Copy (new) chars to screen from first diff to last match */ | ||||
| 	  temp = nls - nfd; | ||||
| 	  if (temp > 0) | ||||
| 	  /* Copy (new) chars to screen from first diff to last match,
 | ||||
| 	     overwriting what is there. */ | ||||
| 	  if (bytes_to_insert > 0) | ||||
| 	    { | ||||
| 	      /* If nfd begins at the prompt, or before the invisible
 | ||||
| 		 characters in the prompt, we need to adjust _rl_last_c_pos | ||||
| 		 in a multibyte locale to account for the wrap offset and | ||||
| 		 set cpos_adjusted accordingly. */ | ||||
| 	      _rl_output_some_chars (nfd, temp); | ||||
| 	      _rl_output_some_chars (nfd, bytes_to_insert); | ||||
| 	      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | ||||
| 		{ | ||||
| 		  _rl_last_c_pos += _rl_col_width (nfd, 0, temp, 1); | ||||
| 		  if (current_line == 0 && wrap_offset &&  ((nfd - new) <= prompt_last_invisible)) | ||||
| 		  _rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, 1); | ||||
| 		  if (current_line == 0 && wrap_offset && | ||||
| 			displaying_prompt_first_line && | ||||
| 			_rl_last_c_pos > wrap_offset && | ||||
| 			((nfd - new) <= prompt_last_invisible)) | ||||
| 		    { | ||||
| 		      _rl_last_c_pos -= wrap_offset; | ||||
| 		      cpos_adjusted = 1; | ||||
| 		    } | ||||
| 		} | ||||
| 	      else | ||||
| 		_rl_last_c_pos += temp; | ||||
| 		_rl_last_c_pos += bytes_to_insert; | ||||
| 
 | ||||
| 	      if (_rl_horizontal_scroll_mode && ((oe-old) > (ne-new))) | ||||
| 		goto clear_rest_of_line; | ||||
| 	    } | ||||
| 	} | ||||
|       /* Otherwise, print over the existing material. */ | ||||
|  | @ -1764,29 +1842,29 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) | |||
| 	      _rl_last_c_pos += col_temp;		/* XXX */ | ||||
| 	      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | ||||
| 		{ | ||||
| 		  if (current_line == 0 && wrap_offset &&  ((nfd - new) <= prompt_last_invisible)) | ||||
| 		  if (current_line == 0 && wrap_offset && | ||||
| 			displaying_prompt_first_line && | ||||
| 			_rl_last_c_pos > wrap_offset && | ||||
| 			((nfd - new) <= prompt_last_invisible)) | ||||
| 		    { | ||||
| 		      _rl_last_c_pos -= wrap_offset; | ||||
| 		      cpos_adjusted = 1; | ||||
| 		    } | ||||
| 		} | ||||
| 	    } | ||||
| clear_rest_of_line: | ||||
| 	  lendiff = (oe - old) - (ne - new); | ||||
| 	  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | ||||
| 	    col_lendiff = _rl_col_width (old, 0, oe - old, 1) - _rl_col_width (new, 0, ne - new, 1); | ||||
| 	  else | ||||
| 	    col_lendiff = lendiff; | ||||
| 
 | ||||
| #if 0 | ||||
| 	  if (col_lendiff) | ||||
| #else | ||||
| 	  /* If we've already printed over the entire width of the screen,
 | ||||
| 	     including the old material, then col_lendiff doesn't matter and | ||||
| 	     space_to_eol will insert too many spaces.  XXX - maybe we should | ||||
| 	     adjust col_lendiff based on the difference between _rl_last_c_pos | ||||
| 	     and _rl_screenwidth */ | ||||
| 	  if (col_lendiff && ((MB_CUR_MAX == 1 || rl_byte_oriented) || (_rl_last_c_pos < _rl_screenwidth))) | ||||
| #endif | ||||
| 	    {	   | ||||
| 	      if (_rl_term_autowrap && current_line < inv_botlin) | ||||
| 		space_to_eol (col_lendiff); | ||||
|  | @ -1938,6 +2016,9 @@ _rl_move_cursor_relative (new, data) | |||
|       else | ||||
|         dpos = _rl_col_width (data, 0, new, 1); | ||||
| 
 | ||||
|       if (displaying_prompt_first_line == 0) | ||||
| 	adjust = 0; | ||||
| 
 | ||||
|       /* Use NEW when comparing against the last invisible character in the
 | ||||
| 	 prompt string, since they're both buffer indices and DPOS is a | ||||
| 	 desired display position. */ | ||||
|  | @ -2056,9 +2137,18 @@ _rl_move_vert (to) | |||
|     } | ||||
|   else | ||||
|     {			/* delta < 0 */ | ||||
| #ifdef __DJGPP__ | ||||
|       int row, col; | ||||
| 
 | ||||
|       fflush (rl_outstream); | ||||
|       ScreenGetCursor (&row, &col); | ||||
|       ScreenSetCursor (row + delta, col); | ||||
|       i = -delta; | ||||
| #else | ||||
|       if (_rl_term_up && *_rl_term_up) | ||||
| 	for (i = 0; i < -delta; i++) | ||||
| 	  tputs (_rl_term_up, 1, _rl_output_character_function); | ||||
| #endif /* !__DJGPP__ */ | ||||
|     } | ||||
| 
 | ||||
|   _rl_last_v_pos = to;		/* Now TO is here */ | ||||
|  | @ -2136,6 +2226,9 @@ rl_message (va_alist) | |||
| #if defined (PREFER_VARARGS) | ||||
|   char *format; | ||||
| #endif | ||||
| #if defined (HAVE_VSNPRINTF) | ||||
|   int bneed; | ||||
| #endif | ||||
| 
 | ||||
| #if defined (PREFER_STDARG) | ||||
|   va_start (args, format); | ||||
|  | @ -2144,11 +2237,28 @@ rl_message (va_alist) | |||
|   format = va_arg (args, char *); | ||||
| #endif | ||||
| 
 | ||||
|   if (msg_buf == 0) | ||||
|     msg_buf = xmalloc (msg_bufsiz = 128); | ||||
| 
 | ||||
| #if defined (HAVE_VSNPRINTF) | ||||
|   vsnprintf (msg_buf, sizeof (msg_buf) - 1, format, args); | ||||
|   bneed = vsnprintf (msg_buf, msg_bufsiz - 1, format, args); | ||||
|   if (bneed >= msg_bufsiz - 1) | ||||
|     { | ||||
|       msg_bufsiz = bneed + 1; | ||||
|       msg_buf = xrealloc (msg_buf, msg_bufsiz); | ||||
|       va_end (args); | ||||
| 
 | ||||
| #if defined (PREFER_STDARG) | ||||
|       va_start (args, format); | ||||
| #else | ||||
|       va_start (args); | ||||
|       format = va_arg (args, char *); | ||||
| #endif | ||||
|       vsnprintf (msg_buf, msg_bufsiz - 1, format, args); | ||||
|     } | ||||
| #else | ||||
|   vsprintf (msg_buf, format, args); | ||||
|   msg_buf[sizeof(msg_buf) - 1] = '\0';	/* overflow? */ | ||||
|   msg_buf[msg_bufsiz - 1] = '\0';	/* overflow? */ | ||||
| #endif | ||||
|   va_end (args); | ||||
| 
 | ||||
|  | @ -2157,6 +2267,12 @@ rl_message (va_alist) | |||
|       rl_save_prompt (); | ||||
|       msg_saved_prompt = 1; | ||||
|     } | ||||
|   else if (local_prompt != saved_local_prompt) | ||||
|     { | ||||
|       FREE (local_prompt); | ||||
|       FREE (local_prompt_prefix); | ||||
|       local_prompt = (char *)NULL; | ||||
|     } | ||||
|   rl_display_prompt = msg_buf; | ||||
|   local_prompt = expand_prompt (msg_buf, &prompt_visible_length, | ||||
| 					 &prompt_last_invisible, | ||||
|  | @ -2173,8 +2289,11 @@ int | |||
| rl_message (format, arg1, arg2) | ||||
|      char *format; | ||||
| { | ||||
|   if (msg_buf == 0) | ||||
|     msg_buf = xmalloc (msg_bufsiz = 128); | ||||
| 
 | ||||
|   sprintf (msg_buf, format, arg1, arg2); | ||||
|   msg_buf[sizeof(msg_buf) - 1] = '\0';	/* overflow? */ | ||||
|   msg_buf[msg_bufsiz - 1] = '\0';	/* overflow? */ | ||||
| 
 | ||||
|   rl_display_prompt = msg_buf; | ||||
|   if (saved_local_prompt == 0) | ||||
|  | @ -2182,6 +2301,12 @@ rl_message (format, arg1, arg2) | |||
|       rl_save_prompt (); | ||||
|       msg_saved_prompt = 1; | ||||
|     } | ||||
|   else if (local_prompt != saved_local_prompt) | ||||
|     { | ||||
|       FREE (local_prompt); | ||||
|       FREE (local_prompt_prefix); | ||||
|       local_prompt = (char *)NULL; | ||||
|     } | ||||
|   local_prompt = expand_prompt (msg_buf, &prompt_visible_length, | ||||
| 					 &prompt_last_invisible, | ||||
| 					 &prompt_invis_chars_first_line, | ||||
|  | @ -2318,10 +2443,13 @@ void | |||
| _rl_clear_to_eol (count) | ||||
|      int count; | ||||
| { | ||||
| #ifndef __MSDOS__ | ||||
|   if (_rl_term_clreol) | ||||
|     tputs (_rl_term_clreol, 1, _rl_output_character_function); | ||||
|   else if (count) | ||||
|     space_to_eol (count); | ||||
|   else | ||||
| #endif | ||||
|     if (count) | ||||
|       space_to_eol (count); | ||||
| } | ||||
| 
 | ||||
| /* Clear to the end of the line using spaces.  COUNT is the minimum
 | ||||
|  | @ -2341,10 +2469,15 @@ space_to_eol (count) | |||
| void | ||||
| _rl_clear_screen () | ||||
| { | ||||
| #ifndef __DJGPP__ | ||||
|   if (_rl_term_clrpag) | ||||
|     tputs (_rl_term_clrpag, 1, _rl_output_character_function); | ||||
|   else | ||||
|     rl_crlf (); | ||||
| #else | ||||
|   ScreenClear (); | ||||
|   ScreenSetCursor (0, 0); | ||||
| #endif /* __DJGPP__ */ | ||||
| } | ||||
| 
 | ||||
| /* Insert COUNT characters from STRING to the output stream at column COL. */ | ||||
|  | @ -2353,48 +2486,47 @@ insert_some_chars (string, count, col) | |||
|      char *string; | ||||
|      int count, col; | ||||
| { | ||||
| #if defined (__MSDOS__) || defined (__MINGW32__) | ||||
|   open_some_spaces (col); | ||||
|   _rl_output_some_chars (string, count); | ||||
| #else | ||||
|   /* DEBUGGING */ | ||||
|   if (MB_CUR_MAX == 1 || rl_byte_oriented) | ||||
|     if (count != col) | ||||
|       _rl_ttymsg ("debug: insert_some_chars: count (%d) != col (%d)", count, col); | ||||
| } | ||||
| 
 | ||||
| /* Insert COL spaces, keeping the cursor at the same position.  We follow the
 | ||||
|    ncurses documentation and use either im/ei with explicit spaces, or IC/ic | ||||
|    by itself.  We assume there will either be ei or we don't need to use it. */ | ||||
| static void | ||||
| open_some_spaces (col) | ||||
|      int col; | ||||
| { | ||||
| #if !defined (__MSDOS__) && !defined (__MINGW32__) | ||||
|   char *buffer; | ||||
|   register int i; | ||||
| 
 | ||||
|   /* If IC is defined, then we do not have to "enter" insert mode. */ | ||||
|   if (_rl_term_IC) | ||||
|     { | ||||
|       char *buffer; | ||||
| 
 | ||||
|       buffer = tgoto (_rl_term_IC, 0, col); | ||||
|       tputs (buffer, 1, _rl_output_character_function); | ||||
|       _rl_output_some_chars (string, count); | ||||
|     } | ||||
|   else | ||||
|   else if (_rl_term_im && *_rl_term_im) | ||||
|     { | ||||
|       register int i; | ||||
| 
 | ||||
|       /* If we have to turn on insert-mode, then do so. */ | ||||
|       if (_rl_term_im && *_rl_term_im) | ||||
| 	tputs (_rl_term_im, 1, _rl_output_character_function); | ||||
| 
 | ||||
|       /* If there is a special command for inserting characters, then
 | ||||
| 	 use that first to open up the space. */ | ||||
|       if (_rl_term_ic && *_rl_term_ic) | ||||
| 	{ | ||||
| 	  for (i = col; i--; ) | ||||
| 	    tputs (_rl_term_ic, 1, _rl_output_character_function); | ||||
| 	} | ||||
| 
 | ||||
|       /* Print the text. */ | ||||
|       _rl_output_some_chars (string, count); | ||||
| 
 | ||||
|       /* If there is a string to turn off insert mode, we had best use
 | ||||
| 	 it now. */ | ||||
|       tputs (_rl_term_im, 1, _rl_output_character_function); | ||||
|       /* just output the desired number of spaces */ | ||||
|       for (i = col; i--; ) | ||||
| 	_rl_output_character_function (' '); | ||||
|       /* If there is a string to turn off insert mode, use it now. */ | ||||
|       if (_rl_term_ei && *_rl_term_ei) | ||||
| 	tputs (_rl_term_ei, 1, _rl_output_character_function); | ||||
|       /* and move back the right number of spaces */ | ||||
|       _rl_backspace (col); | ||||
|     } | ||||
| #endif /* __MSDOS__ || __MINGW32__ */ | ||||
|   else if (_rl_term_ic && *_rl_term_ic) | ||||
|     { | ||||
|       /* If there is a special command for inserting characters, then
 | ||||
| 	 use that first to open up the space. */ | ||||
|       for (i = col; i--; ) | ||||
| 	tputs (_rl_term_ic, 1, _rl_output_character_function); | ||||
|     } | ||||
| #endif /* !__MSDOS__ && !__MINGW32__ */ | ||||
| } | ||||
| 
 | ||||
| /* Delete COUNT characters from the display line. */ | ||||
|  | @ -2599,10 +2731,8 @@ _rl_col_width (str, start, end, flags) | |||
|   if (end <= start) | ||||
|     return 0; | ||||
|   if (MB_CUR_MAX == 1 || rl_byte_oriented) | ||||
| { | ||||
| _rl_ttymsg ("_rl_col_width: called with MB_CUR_MAX == 1"); | ||||
|     /* this can happen in some cases where it's inconvenient to check */ | ||||
|     return (end - start); | ||||
| } | ||||
| 
 | ||||
|   memset (&ps, 0, sizeof (mbstate_t)); | ||||
| 
 | ||||
|  | @ -2676,7 +2806,7 @@ _rl_ttymsg ("_rl_col_width: called with MB_CUR_MAX == 1"); | |||
| 	{ | ||||
| 	  point += tmp; | ||||
| 	  max -= tmp; | ||||
| 	  tmp = wcwidth(wc); | ||||
| 	  tmp = WCWIDTH(wc); | ||||
| 	  width += (tmp >= 0) ? tmp : 1; | ||||
| 	} | ||||
|     } | ||||
|  |  | |||
|  | @ -2,33 +2,25 @@ | |||
| @c %**start of header (This is for running Texinfo on a region.) | ||||
| @setfilename history.info | ||||
| @settitle GNU History Library | ||||
| @c %**end of header (This is for running Texinfo on a region.) | ||||
| 
 | ||||
| @include version.texi | ||||
| 
 | ||||
| @c %**end of header (This is for running Texinfo on a region.) | ||||
| 
 | ||||
| @copying | ||||
| This document describes the GNU History library | ||||
| (version @value{VERSION}, @value{UPDATED}), | ||||
| a programming tool that provides a consistent user interface for | ||||
| recalling lines of previously typed input. | ||||
| 
 | ||||
| Copyright @copyright{} 1988--2011 Free Software Foundation, Inc. | ||||
| 
 | ||||
| Permission is granted to make and distribute verbatim copies of | ||||
| this manual provided the copyright notice and this permission notice | ||||
| are preserved on all copies. | ||||
| Copyright @copyright{} 1988--2014 Free Software Foundation, Inc. | ||||
| 
 | ||||
| @quotation | ||||
| Permission is granted to copy, distribute and/or modify this document | ||||
| under the terms of the GNU Free Documentation License, Version 1.3 or | ||||
| any later version published by the Free Software Foundation; with no | ||||
| Invariant Sections, with the Front-Cover texts being ``A GNU Manual'', | ||||
| and with the Back-Cover Texts as in (a) below.  A copy of the license is | ||||
| included in the section entitled ``GNU Free Documentation License''. | ||||
| 
 | ||||
| (a) The FSF's Back-Cover Text is: You are free to copy and modify | ||||
| this GNU manual.  Buying copies from GNU Press supports the FSF in | ||||
| developing GNU and promoting software freedom.'' | ||||
| Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. | ||||
| A copy of the license is included in the section entitled | ||||
| ``GNU Free Documentation License''. | ||||
| 
 | ||||
| @end quotation | ||||
| @end copying | ||||
|  | @ -50,12 +42,6 @@ developing GNU and promoting software freedom.'' | |||
| @vskip 0pt plus 1filll | ||||
| @insertcopying | ||||
| 
 | ||||
| @sp 1 | ||||
| Published by the Free Software Foundation @* | ||||
| 59 Temple Place, Suite 330, @* | ||||
| Boston, MA 02111-1307 @* | ||||
| USA @* | ||||
| 
 | ||||
| @end titlepage | ||||
| 
 | ||||
| @contents | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| @ignore | ||||
| This file documents the user interface to the GNU History library. | ||||
| 
 | ||||
| Copyright (C) 1988-2011 Free Software Foundation, Inc. | ||||
| Copyright (C) 1988-2014 Free Software Foundation, Inc. | ||||
| Authored by Brian Fox and Chet Ramey. | ||||
| 
 | ||||
| Permission is granted to make and distribute verbatim copies of this manual | ||||
|  | @ -377,7 +377,7 @@ if the returned line should be displayed, but not executed, | |||
| as with the @code{:p} modifier (@pxref{Modifiers}). | ||||
| @end table | ||||
| 
 | ||||
| If an error ocurred in expansion, then @var{output} contains a descriptive | ||||
| If an error occurred in expansion, then @var{output} contains a descriptive | ||||
| error message. | ||||
| @end deftypefun | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| @ignore | ||||
| This file documents the user interface to the GNU History library. | ||||
| 
 | ||||
| Copyright (C) 1988--2011 Free Software Foundation, Inc. | ||||
| Copyright (C) 1988--2014 Free Software Foundation, Inc. | ||||
| Authored by Brian Fox and Chet Ramey. | ||||
| 
 | ||||
| Permission is granted to make and distribute verbatim copies of this manual | ||||
|  | @ -84,17 +84,18 @@ file named by the @env{HISTFILE} variable (default @file{~/.bash_history}). | |||
| The file named by the value of @env{HISTFILE} is truncated, if | ||||
| necessary, to contain no more than the number of lines specified by | ||||
| the value of the @env{HISTFILESIZE} variable. | ||||
| When an interactive shell exits, the last | ||||
| When a shell with history enabled exits, the last | ||||
| @env{$HISTSIZE} lines are copied from the history list to the file | ||||
| named by @env{$HISTFILE}. | ||||
| If the @code{histappend} shell option is set (@pxref{Bash Builtins}), | ||||
| the lines are appended to the history file, | ||||
| otherwise the history file is overwritten. | ||||
| If @env{HISTFILE} | ||||
| is unset, or if the history file is unwritable, the history is | ||||
| not saved.  After saving the history, the history file is truncated | ||||
| to contain no more than @env{$HISTFILESIZE} | ||||
| lines.  If @env{HISTFILESIZE} is not set, no truncation is performed. | ||||
| is unset, or if the history file is unwritable, the history is not saved. | ||||
| After saving the history, the history file is truncated | ||||
| to contain no more than @env{$HISTFILESIZE} lines. | ||||
| If @env{HISTFILESIZE} is unset, or set to null, a non-numeric value, or | ||||
| a numeric value less than zero, the history file is not truncated. | ||||
| 
 | ||||
| If the @env{HISTTIMEFORMAT} is set, the time stamp information | ||||
| associated with each history entry is written to the history file, | ||||
|  | @ -141,8 +142,10 @@ history list and history file. | |||
| @code{fc -s [@var{pat}=@var{rep}] [@var{command}]} | ||||
| @end example | ||||
| 
 | ||||
| Fix Command.  In the first form, a range of commands from @var{first} to | ||||
| @var{last} is selected from the history list.  Both @var{first} and | ||||
| The first form selects a range of commands from @var{first} to | ||||
| @var{last} from the history list and displays or edits and re-executes | ||||
| them. | ||||
| Both @var{first} and | ||||
| @var{last} may be specified as a string (to locate the most recent | ||||
| command beginning with that string) or as a number (an index into the | ||||
| history list, where a negative number is used as an offset from the | ||||
|  | @ -161,6 +164,7 @@ When editing is complete, the edited commands are echoed and executed. | |||
| 
 | ||||
| In the second form, @var{command} is re-executed after each instance | ||||
| of @var{pat} in the selected command is replaced by @var{rep}. | ||||
| @var{command} is intepreted the same as @var{first} above. | ||||
| 
 | ||||
| A useful alias to use with the @code{fc} command is @code{r='fc -s'}, so | ||||
| that typing @samp{r cc} runs the last command beginning with @code{cc} | ||||
|  | @ -208,11 +212,11 @@ to the current history list.  These are lines appended to the history | |||
| file since the beginning of the current Bash session. | ||||
| 
 | ||||
| @item -r | ||||
| Read the current history file and append its contents to | ||||
| Read the history file and append its contents to | ||||
| the history list. | ||||
| 
 | ||||
| @item -w | ||||
| Write out the current history to the history file. | ||||
| Write out the current history list to the history file. | ||||
| 
 | ||||
| @item -p | ||||
| Perform history substitution on the @var{arg}s and display the result | ||||
|  |  | |||
|  | @ -2,34 +2,26 @@ | |||
| @comment %**start of header (This is for running Texinfo on a region.) | ||||
| @setfilename readline.info | ||||
| @settitle GNU Readline Library | ||||
| @include version.texi | ||||
| 
 | ||||
| @comment %**end of header (This is for running Texinfo on a region.) | ||||
| @synindex vr fn | ||||
| 
 | ||||
| @include version.texi | ||||
| 
 | ||||
| @copying | ||||
| This manual describes the GNU Readline Library | ||||
| (version @value{VERSION}, @value{UPDATED}), a library which aids in the | ||||
| consistency of user interface across discrete programs which provide | ||||
| a command line interface. | ||||
| 
 | ||||
| Copyright @copyright{} 1988--2011 Free Software Foundation, Inc. | ||||
| 
 | ||||
| Permission is granted to make and distribute verbatim copies of | ||||
| this manual provided the copyright notice and this permission notice | ||||
| are preserved on all copies. | ||||
| Copyright @copyright{} 1988--2014 Free Software Foundation, Inc. | ||||
| 
 | ||||
| @quotation | ||||
| Permission is granted to copy, distribute and/or modify this document | ||||
| under the terms of the GNU Free Documentation License, Version 1.3 or | ||||
| any later version published by the Free Software Foundation; with no | ||||
| Invariant Sections, with the Front-Cover texts being ``A GNU Manual'', | ||||
| and with the Back-Cover Texts as in (a) below.  A copy of the license is | ||||
| included in the section entitled ``GNU Free Documentation License''. | ||||
| 
 | ||||
| (a) The FSF's Back-Cover Text is: You are free to copy and modify | ||||
| this GNU manual.  Buying copies from GNU Press supports the FSF in | ||||
| developing GNU and promoting software freedom.'' | ||||
| Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. | ||||
| A copy of the license is included in the section entitled | ||||
| ``GNU Free Documentation License''. | ||||
| 
 | ||||
| @end quotation | ||||
| @end copying | ||||
|  | @ -50,12 +42,6 @@ developing GNU and promoting software freedom.'' | |||
| @vskip 0pt plus 1filll | ||||
| @insertcopying | ||||
| 
 | ||||
| @sp 1 | ||||
| Published by the Free Software Foundation @* | ||||
| 59 Temple Place, Suite 330, @* | ||||
| Boston, MA 02111-1307 @* | ||||
| USA @* | ||||
| 
 | ||||
| @end titlepage | ||||
| 
 | ||||
| @contents | ||||
|  | @ -67,6 +53,7 @@ USA @* | |||
| This document describes the GNU Readline Library, a utility which aids | ||||
| in the consistency of user interface across discrete programs which | ||||
| provide a command line interface. | ||||
| The Readline home page is @url{http://www.gnu.org/software/readline/}. | ||||
| 
 | ||||
| @menu | ||||
| * Command Line Editing::	   GNU Readline User's Manual. | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ This document describes the GNU Readline Library, a utility for aiding | |||
| in the consistency of user interface across discrete programs that need | ||||
| to provide a command line interface. | ||||
| 
 | ||||
| Copyright (C) 1988--2011 Free Software Foundation, Inc. | ||||
| Copyright (C) 1988--2014 Free Software Foundation, Inc. | ||||
| 
 | ||||
| Permission is granted to make and distribute verbatim copies of | ||||
| this manual provided the copyright notice and this permission notice | ||||
|  | @ -195,7 +195,7 @@ For Readline 4.2, for example, the value of | |||
| @node Readline Typedefs | ||||
| @subsection Readline Typedefs | ||||
| 
 | ||||
| For readabilty, we declare a number of new object types, all pointers | ||||
| For readability, we declare a number of new object types, all pointers | ||||
| to functions. | ||||
| 
 | ||||
| The reason for declaring these new types is to make it easier to write | ||||
|  | @ -440,6 +440,35 @@ If non-zero, Readline will call indirectly through this pointer | |||
| to get a character from the input stream.  By default, it is set to | ||||
| @code{rl_getc}, the default Readline character input function | ||||
| (@pxref{Character Input}). | ||||
| In general, an application that sets @var{rl_getc_function} should consider | ||||
| setting @var{rl_input_available_hook} as well. | ||||
| @end deftypevar | ||||
| 
 | ||||
| @deftypevar {rl_hook_func_t *} rl_signal_event_hook | ||||
| If non-zero, this is the address of a function to call if a read system | ||||
| call is interrupted when Readline is reading terminal input. | ||||
| @end deftypevar | ||||
| 
 | ||||
| @deftypevar {rl_hook_func_t *} rl_input_available_hook | ||||
| If non-zero, Readline will use this function's return value when it needs | ||||
| to determine whether or not there is available input on the current input | ||||
| source. | ||||
| The default hook checks @code{rl_instream}; if an application is using a | ||||
| different input source, it should set the hook appropriately. | ||||
| Readline queries for available input when implementing intra-key-sequence | ||||
| timeouts during input and incremental searches. | ||||
| This may use an application-specific timeout before returning a value; | ||||
| Readline uses the value passed to @code{rl_set_keyboard_input_timeout()} | ||||
| or the value of the user-settable @var{keyseq-timeout} variable. | ||||
| This is designed for use by applications using Readline's callback interface | ||||
| (@pxref{Alternate Interface}), which may not use the traditional | ||||
| @code{read(2)} and file descriptor interface, or other applications using | ||||
| a different input mechanism. | ||||
| If an application uses an input mechanism or hook that can potentially exceed | ||||
| the value of @var{keyseq-timeout}, it should increase the timeout or set | ||||
| this hook appropriately even when not using the callback interface. | ||||
| In general, an application that sets @var{rl_getc_function} should consider | ||||
| setting @var{rl_input_available_hook} as well. | ||||
| @end deftypevar | ||||
| 
 | ||||
| @deftypevar {rl_voidfunc_t *} rl_redisplay_function | ||||
|  | @ -479,6 +508,19 @@ last key binding occurred. | |||
| This variable is set to the text of any currently-executing macro. | ||||
| @end deftypevar | ||||
| 
 | ||||
| @deftypevar int rl_executing_key | ||||
| The key that caused the dispatch to the currently-executing Readline function. | ||||
| @end deftypevar | ||||
| 
 | ||||
| @deftypevar {char *} rl_executing_keyseq | ||||
| The full key sequence that caused the dispatch to the currently-executing | ||||
| Readline function. | ||||
| @end deftypevar | ||||
| 
 | ||||
| @deftypevar int rl_key_sequence_length | ||||
| The number of characters in @var{rl_executing_keyseq}. | ||||
| @end deftypevar | ||||
| 
 | ||||
| @deftypevar {int} rl_readline_state | ||||
| A variable with bit values that encapsulate the current Readline state. | ||||
| A bit is set with the @code{RL_SETSTATE} macro, and unset with the | ||||
|  | @ -487,7 +529,7 @@ whether a particular state bit is set.  Current state bits include: | |||
| 
 | ||||
| @table @code | ||||
| @item RL_STATE_NONE | ||||
| Readline has not yet been called, nor has it begun to intialize. | ||||
| Readline has not yet been called, nor has it begun to initialize. | ||||
| @item RL_STATE_INITIALIZING | ||||
| Readline is initializing its internal data structures. | ||||
| @item RL_STATE_INITIALIZED | ||||
|  | @ -580,6 +622,7 @@ means that vi mode is active. | |||
| * Miscellaneous Functions::	Functions that don't fall into any category. | ||||
| * Alternate Interface::	Using Readline in a `callback' fashion. | ||||
| * A Readline Example::		An example Readline function. | ||||
| * Alternate Interface Example::	An example program using the alternate interface. | ||||
| @end menu | ||||
| 
 | ||||
| @node Function Naming | ||||
|  | @ -908,7 +951,7 @@ Readline thinks the screen display is correct. | |||
| 
 | ||||
| @deftypefun int rl_on_new_line (void) | ||||
| Tell the update functions that we have moved onto a new (empty) line, | ||||
| usually after ouputting a newline. | ||||
| usually after outputting a newline. | ||||
| @end deftypefun | ||||
| 
 | ||||
| @deftypefun int rl_on_new_line_with_prompt (void) | ||||
|  | @ -1241,21 +1284,29 @@ use all of a terminal's capabilities, and this function will return | |||
| values for only those capabilities Readline uses. | ||||
| @end deftypefun | ||||
| 
 | ||||
| @deftypefun {void} rl_clear_history (void) | ||||
| Clear the history list by deleting all of the entries, in the same manner | ||||
| as the History library's @code{clear_history()} function. | ||||
| This differs from @code{clear_history} because it frees private data | ||||
| Readline saves in the history list. | ||||
| @end deftypefun | ||||
| 
 | ||||
| @node Alternate Interface | ||||
| @subsection Alternate Interface | ||||
| 
 | ||||
| An alternate interface is available to plain @code{readline()}.  Some | ||||
| applications need to interleave keyboard I/O with file, device, or | ||||
| window system I/O, typically by using a main loop to @code{select()} | ||||
| on various file descriptors.  To accomodate this need, readline can | ||||
| on various file descriptors.  To accommodate this need, readline can | ||||
| also be invoked as a `callback' function from an event loop.  There | ||||
| are functions available to make this easy. | ||||
| 
 | ||||
| @deftypefun void rl_callback_handler_install (const char *prompt, rl_vcpfunc_t *lhandler) | ||||
| Set up the terminal for readline I/O and display the initial | ||||
| expanded value of @var{prompt}.  Save the value of @var{lhandler} to | ||||
| use as a function to call when a complete line of input has been entered. | ||||
| The function takes the text of the line as an argument. | ||||
| use as a handler function to call when a complete line of input has been | ||||
| entered. | ||||
| The handler function receives the text of the line as an argument. | ||||
| @end deftypefun | ||||
| 
 | ||||
| @deftypefun void rl_callback_read_char (void) | ||||
|  | @ -1263,14 +1314,15 @@ Whenever an application determines that keyboard input is available, it | |||
| should call @code{rl_callback_read_char()}, which will read the next | ||||
| character from the current input source. | ||||
| If that character completes the line, @code{rl_callback_read_char} will | ||||
| invoke the @var{lhandler} function saved by @code{rl_callback_handler_install} | ||||
| to process the line. | ||||
| invoke the @var{lhandler} function installed by | ||||
| @code{rl_callback_handler_install} to process the line. | ||||
| Before calling the @var{lhandler} function, the terminal settings are | ||||
| reset to the values they had before calling | ||||
| @code{rl_callback_handler_install}. | ||||
| If the @var{lhandler} function returns, | ||||
| and the line handler remains installed, | ||||
| the terminal settings are modified for Readline's use again. | ||||
| @code{EOF} is  indicated by calling @var{lhandler} with a | ||||
| @code{EOF} is indicated by calling @var{lhandler} with a | ||||
| @code{NULL} line. | ||||
| @end deftypefun | ||||
| 
 | ||||
|  | @ -1350,6 +1402,98 @@ invert_case_line (count, key) | |||
| @} | ||||
| @end example | ||||
| 
 | ||||
| @node Alternate Interface Example | ||||
| @subsection Alternate Interface Example | ||||
| 
 | ||||
| Here is a complete program that illustrates Readline's alternate interface. | ||||
| It reads lines from the terminal and displays them, providing the | ||||
| standard history and TAB completion functions. | ||||
| It understands the EOF character or "exit" to exit the program. | ||||
| 
 | ||||
| @example | ||||
| /* Standard include files. stdio.h is required. */ | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| /* Used for select(2) */ | ||||
| #include <sys/types.h> | ||||
| #include <sys/select.h> | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| /* Standard readline include files. */ | ||||
| #include <readline/readline.h> | ||||
| #include <readline/history.h> | ||||
| 
 | ||||
| static void cb_linehandler (char *); | ||||
| 
 | ||||
| int running; | ||||
| const char *prompt = "rltest$ "; | ||||
| 
 | ||||
| /* Callback function called for each line when accept-line executed, EOF | ||||
|    seen, or EOF character read.  This sets a flag and returns; it could | ||||
|    also call exit(3). */ | ||||
| static void | ||||
| cb_linehandler (char *line) | ||||
| @{ | ||||
|   /* Can use ^D (stty eof) or `exit' to exit. */ | ||||
|   if (line == NULL || strcmp (line, "exit") == 0) | ||||
|     @{ | ||||
|       if (line == 0) | ||||
|         printf ("\n"); | ||||
|       printf ("exit\n"); | ||||
|       /* This function needs to be called to reset the terminal settings, | ||||
|          and calling it from the line handler keeps one extra prompt from | ||||
|          being displayed. */ | ||||
|       rl_callback_handler_remove (); | ||||
| 
 | ||||
|       running = 0; | ||||
|     @} | ||||
|   else | ||||
|     @{ | ||||
|       if (*line) | ||||
|         add_history (line); | ||||
|       printf ("input line: %s\n", line); | ||||
|       free (line); | ||||
|     @} | ||||
| @} | ||||
| 
 | ||||
| int | ||||
| main (int c, char **v) | ||||
| @{ | ||||
|   fd_set fds; | ||||
|   int r; | ||||
| 
 | ||||
|   /* Install the line handler. */ | ||||
|   rl_callback_handler_install (prompt, cb_linehandler); | ||||
| 
 | ||||
|   /* Enter a simple event loop.  This waits until something is available | ||||
|      to read on readline's input stream (defaults to standard input) and | ||||
|      calls the builtin character read callback to read it.  It does not | ||||
|      have to modify the user's terminal settings. */ | ||||
|   running = 1; | ||||
|   while (running) | ||||
|     @{ | ||||
|       FD_ZERO (&fds); | ||||
|       FD_SET (fileno (rl_instream), &fds);     | ||||
| 
 | ||||
|       r = select (FD_SETSIZE, &fds, NULL, NULL, NULL); | ||||
|       if (r < 0) | ||||
|         @{ | ||||
|           perror ("rltest: select"); | ||||
|           rl_callback_handler_remove (); | ||||
|           break; | ||||
|         @} | ||||
| 
 | ||||
|       if (FD_ISSET (fileno (rl_instream), &fds)) | ||||
|         rl_callback_read_char (); | ||||
|     @} | ||||
| 
 | ||||
|   printf ("rltest: Event loop has exited\n"); | ||||
|   return 0; | ||||
| @} | ||||
| @end example | ||||
| 
 | ||||
| @node Readline Signal Handling | ||||
| @section Readline Signal Handling | ||||
| 
 | ||||
|  | @ -1365,6 +1509,7 @@ functions to do so manually. | |||
| 
 | ||||
| Readline contains an internal signal handler that is installed for a | ||||
| number of signals (@code{SIGINT}, @code{SIGQUIT}, @code{SIGTERM}, | ||||
| @code{SIGHUP},  | ||||
| @code{SIGALRM}, @code{SIGTSTP}, @code{SIGTTIN}, and @code{SIGTTOU}). | ||||
| When one of these signals is received, the signal handler | ||||
| will reset the terminal attributes to those that were in effect before | ||||
|  | @ -1397,19 +1542,28 @@ a signal handler, so Readline's internal signal state is not corrupted. | |||
| 
 | ||||
| @deftypevar int rl_catch_signals | ||||
| If this variable is non-zero, Readline will install signal handlers for | ||||
| @code{SIGINT}, @code{SIGQUIT}, @code{SIGTERM}, @code{SIGALRM}, | ||||
| @code{SIGINT}, @code{SIGQUIT}, @code{SIGTERM}, @code{SIGHUP}, @code{SIGALRM}, | ||||
| @code{SIGTSTP}, @code{SIGTTIN}, and @code{SIGTTOU}. | ||||
| 
 | ||||
| The default value of @code{rl_catch_signals} is 1. | ||||
| @end deftypevar | ||||
| 
 | ||||
| @deftypevar int rl_catch_sigwinch | ||||
| If this variable is non-zero, Readline will install a signal handler for | ||||
| @code{SIGWINCH}. | ||||
| If this variable is set to a non-zero value, | ||||
| Readline will install a signal handler for @code{SIGWINCH}. | ||||
| 
 | ||||
| The default value of @code{rl_catch_sigwinch} is 1. | ||||
| @end deftypevar | ||||
| 
 | ||||
| @deftypevar int rl_change_environment | ||||
| If this variable is set to a non-zero value, | ||||
| and Readline is handling @code{SIGWINCH}, Readline will modify the | ||||
| @var{LINES} and @var{COLUMNS} environment variables upon receipt of a | ||||
| @code{SIGWINCH} | ||||
| 
 | ||||
| The default value of @code{rl_change_environment} is 1. | ||||
| @end deftypevar | ||||
| 
 | ||||
| If an application does not wish to have Readline catch any signals, or | ||||
| to handle signals other than those Readline catches (@code{SIGHUP}, | ||||
| for example),  | ||||
|  | @ -1477,7 +1631,7 @@ The following functions install and remove Readline's signal handlers. | |||
| 
 | ||||
| @deftypefun int rl_set_signals (void) | ||||
| Install Readline's signal handler for @code{SIGINT}, @code{SIGQUIT}, | ||||
| @code{SIGTERM}, @code{SIGALRM}, @code{SIGTSTP}, @code{SIGTTIN}, | ||||
| @code{SIGTERM}, @code{SIGHUP}, @code{SIGALRM}, @code{SIGTSTP}, @code{SIGTTIN}, | ||||
| @code{SIGTTOU}, and @code{SIGWINCH}, depending on the values of | ||||
| @code{rl_catch_signals} and @code{rl_catch_sigwinch}. | ||||
| @end deftypefun | ||||
|  | @ -1611,7 +1765,7 @@ This calls @code{rl_complete_internal()} with an argument of @samp{*}. | |||
| @end deftypefun | ||||
| 
 | ||||
| @deftypefun int rl_completion_mode (rl_command_func_t *cfunc) | ||||
| Returns the apppriate value to pass to @code{rl_complete_internal()} | ||||
| Returns the appropriate value to pass to @code{rl_complete_internal()} | ||||
| depending on whether @var{cfunc} was called twice in succession and | ||||
| the values of the @code{show-all-if-ambiguous} and | ||||
| @code{show-all-if-unmodified} variables. | ||||
|  | @ -1728,29 +1882,45 @@ the directory portion of the pathname the user typed. | |||
| At the least, even if no other expansion is performed, this function should | ||||
| remove any quote characters from the directory name, because its result will | ||||
| be passed directly to @code{opendir()}. | ||||
| 
 | ||||
| The directory completion hook returns an integer that should be non-zero if | ||||
| the function modifies its directory argument. | ||||
| The function should not modify the directory argument if it returns 0. | ||||
| @end deftypevar | ||||
| 
 | ||||
| @ignore | ||||
| @deftypevar extern rl_icppfunc_t *rl_directory_rewrite_hook; | ||||
| @deftypevar {rl_icppfunc_t *} rl_directory_rewrite_hook; | ||||
| If non-zero, this is the address of a function to call when completing | ||||
| a directory name.  This function takes the address of the directory name | ||||
| to be modified as an argument.  Unlike @code{rl_directory_completion_hook}, | ||||
| it only modifies the directory name used in @code{opendir}, not what is | ||||
| displayed when the possible completions are printed or inserted.  It is | ||||
| called before rl_directory_completion_hook. | ||||
| At the least, even if no other expansion is performed, this function should | ||||
| remove any quote characters from the directory name, because its result will | ||||
| be passed directly to @code{opendir()}. | ||||
| 
 | ||||
| I'm not happy with how this works yet, so it's undocumented. | ||||
| The directory rewrite hook returns an integer that should be non-zero if | ||||
| the function modfies its directory argument. | ||||
| The function should not modify the directory argument if it returns 0. | ||||
| @end deftypevar | ||||
| 
 | ||||
| @deftypevar {rl_icppfunc_t *} rl_filename_stat_hook | ||||
| If non-zero, this is the address of a function for the completer to | ||||
| call before deciding which character to append to a completed name. | ||||
| This function modifies its filename name argument, and the modified value | ||||
| is passed to @code{stat()} to determine the file's type and characteristics. | ||||
| This function does not need to remove quote characters from the filename. | ||||
| 
 | ||||
| The stat hook returns an integer that should be non-zero if | ||||
| the function modfies its directory argument. | ||||
| The function should not modify the directory argument if it returns 0. | ||||
| @end deftypevar | ||||
| @end ignore | ||||
| 
 | ||||
| @deftypevar {rl_dequote_func_t *} rl_filename_rewrite_hook | ||||
| If non-zero, this is the address of a function called when reading | ||||
| directory entries from the filesystem for completion and comparing | ||||
| them to the partial word to be completed.  The function should | ||||
| perform any necesary application or system-specific conversion on | ||||
| perform any necessary application or system-specific conversion on | ||||
| the filename, such as converting between character sets or converting | ||||
| from a filesystem format to a character input format. | ||||
| The function takes two arguments: @var{fname}, the filename to be converted, | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ use these features.  There is a document entitled "readline.texinfo" | |||
| which contains both end-user and programmer documentation for the | ||||
| GNU Readline Library. | ||||
| 
 | ||||
| Copyright (C) 1988--2011 Free Software Foundation, Inc. | ||||
| Copyright (C) 1988--2014 Free Software Foundation, Inc. | ||||
| 
 | ||||
| Authored by Brian Fox and Chet Ramey. | ||||
| 
 | ||||
|  | @ -72,6 +72,8 @@ Line editing can be enabled at any time using the @option{-o emacs} or | |||
| 				a specific command. | ||||
| * Programmable Completion Builtins::	Builtin commands to specify how to | ||||
| 				complete arguments for a particular command. | ||||
| * A Programmable Completion Example::	An example shell function for | ||||
| 				generating possible completions. | ||||
| @end ifset | ||||
| @end menu | ||||
| 
 | ||||
|  | @ -425,6 +427,14 @@ If set to @samp{on}, Readline attempts to bind the control characters | |||
| treated specially by the kernel's terminal driver to their Readline | ||||
| equivalents. | ||||
| 
 | ||||
| @item colored-stats | ||||
| @vindex colored-stats | ||||
| If set to @samp{on}, Readline displays possible completions using different | ||||
| colors to indicate their file type. | ||||
| The color definitions are taken from the value of the @env{LS_COLORS} | ||||
| environment variable. | ||||
| The default is @samp{off}. | ||||
| 
 | ||||
| @item comment-begin | ||||
| @vindex comment-begin | ||||
| The string to insert at the beginning of the line when the | ||||
|  | @ -521,8 +531,12 @@ or @code{next-history}.  The default is @samp{off}. | |||
| 
 | ||||
| @item history-size | ||||
| @vindex history-size | ||||
| Set the maximum number of history entries saved in the history list.  If | ||||
| set to zero, the number of entries in the history list is not limited. | ||||
| Set the maximum number of history entries saved in the history list. | ||||
| If set to zero, any existing history entries are deleted and no new entries | ||||
| are saved. | ||||
| If set to a value less than zero, the number of history entries is not | ||||
| limited. | ||||
| By default, the number of history entries is not limited. | ||||
| 
 | ||||
| @item horizontal-scroll-mode | ||||
| @vindex horizontal-scroll-mode | ||||
|  | @ -565,6 +579,22 @@ equivalent to @code{emacs-standard}.  The default value is @code{emacs}. | |||
| The value of the @code{editing-mode} variable also affects the | ||||
| default keymap. | ||||
| 
 | ||||
| @item keyseq-timeout | ||||
| Specifies the duration Readline will wait for a character when reading an | ||||
| ambiguous key sequence (one that can form a complete key sequence using | ||||
| the input read so far, or can take additional input to complete a longer | ||||
| key sequence). | ||||
| If no input is received within the timeout, Readline will use the shorter | ||||
| but complete key sequence. | ||||
| Readline uses this value to determine whether or not input is | ||||
| available on the current input source (@code{rl_instream} by default). | ||||
| The value is specified in milliseconds, so a value of 1000 means that | ||||
| Readline will wait one second for additional input. | ||||
| If this variable is set to a value less than or equal to zero, or to a | ||||
| non-numeric value, Readline will wait until another key is pressed to | ||||
| decide which key sequence to complete. | ||||
| The default value is @code{500}. | ||||
| 
 | ||||
| @item mark-directories | ||||
| If set to @samp{on}, completed directory names have a slash | ||||
| appended.  The default is @samp{on}. | ||||
|  | @ -640,6 +670,13 @@ a common prefix) cause the matches to be listed immediately instead | |||
| of ringing the bell. | ||||
| The default value is @samp{off}. | ||||
| 
 | ||||
| @item show-mode-in-prompt | ||||
| @vindex show-mode-in-prompt | ||||
| If set to @samp{on}, add a character to the beginning of the prompt | ||||
| indicating the editing mode: emacs (@samp{@@}), vi command (@samp{:}), | ||||
| or vi insertion (@samp{+}). | ||||
| The default value is @samp{off}. | ||||
| 
 | ||||
| @item skip-completed-text | ||||
| @vindex skip-completed-text | ||||
| If set to @samp{on}, this alters the default completion behavior when | ||||
|  | @ -880,7 +917,7 @@ binding, variable assignment, and conditional syntax. | |||
| # You can re-read the inputrc file with C-x C-r. | ||||
| # Lines beginning with '#' are comments. | ||||
| # | ||||
| # First, include any systemwide bindings and variable | ||||
| # First, include any system-wide bindings and variable | ||||
| # assignments from /etc/Inputrc | ||||
| $include /etc/Inputrc | ||||
| 
 | ||||
|  | @ -1100,13 +1137,30 @@ for a string supplied by the user. | |||
| @item history-search-forward () | ||||
| Search forward through the history for the string of characters | ||||
| between the start of the current line and the point. | ||||
| The search string must match at the beginning of a history line. | ||||
| This is a non-incremental search. | ||||
| By default, this command is unbound. | ||||
| 
 | ||||
| @item history-search-backward () | ||||
| Search backward through the history for the string of characters | ||||
| between the start of the current line and the point.  This | ||||
| is a non-incremental search.  By default, this command is unbound. | ||||
| between the start of the current line and the point. | ||||
| The search string must match at the beginning of a history line. | ||||
| This is a non-incremental search. | ||||
| By default, this command is unbound. | ||||
| 
 | ||||
| @item history-substr-search-forward () | ||||
| Search forward through the history for the string of characters | ||||
| between the start of the current line and the point. | ||||
| The search string may match anywhere in a history line. | ||||
| This is a non-incremental search. | ||||
| By default, this command is unbound. | ||||
| 
 | ||||
| @item history-substr-search-backward () | ||||
| Search backward through the history for the string of characters | ||||
| between the start of the current line and the point. | ||||
| The search string may match anywhere in a history line. | ||||
| This is a non-incremental search. | ||||
| By default, this command is unbound. | ||||
| 
 | ||||
| @item yank-nth-arg (M-C-y) | ||||
| Insert the first argument to the previous command (usually | ||||
|  | @ -1137,11 +1191,17 @@ as if the @samp{!$} history expansion had been specified. | |||
| @subsection Commands For Changing Text | ||||
| 
 | ||||
| @ftable @code | ||||
| 
 | ||||
| @item @i{end-of-file} (usually C-d) | ||||
| The character indicating end-of-file as set, for example, by | ||||
| @code{stty}.  If this character is read when there are no characters | ||||
| on the line, and point is at the beginning of the line, Readline | ||||
| interprets it as the end of input and returns @sc{eof}. | ||||
| 
 | ||||
| @item delete-char (C-d) | ||||
| Delete the character at point.  If point is at the | ||||
| beginning of the line, there are no characters in the line, and | ||||
| the last character typed was not bound to @code{delete-char}, then | ||||
| return @sc{eof}. | ||||
| Delete the character at point.  If this function is bound to the | ||||
| same character as the tty @sc{eof} character, as @kbd{C-d} | ||||
| commonly is, see above for the effects. | ||||
| 
 | ||||
| @item backward-delete-char (Rubout) | ||||
| Delete the character behind the cursor.  A numeric argument means | ||||
|  | @ -1435,6 +1495,10 @@ and save the definition. | |||
| Re-execute the last keyboard macro defined, by making the characters | ||||
| in the macro appear as if typed at the keyboard. | ||||
| 
 | ||||
| @item print-last-kbd-macro () | ||||
| Print the last keboard macro defined in a format suitable for the | ||||
| @var{inputrc} file. | ||||
| 
 | ||||
| @end ftable | ||||
| 
 | ||||
| @node Miscellaneous Commands | ||||
|  | @ -1693,10 +1757,11 @@ When the command or function is invoked, the @env{COMP_LINE}, | |||
| assigned values as described above (@pxref{Bash Variables}). | ||||
| If a shell function is being invoked, the @env{COMP_WORDS} and | ||||
| @env{COMP_CWORD} variables are also set. | ||||
| When the function or command is invoked, the first argument is the | ||||
| When the function or command is invoked, the first argument ($1) is the | ||||
| name of the command whose arguments are being completed, the | ||||
| second argument is the word being completed, and the third argument | ||||
| is the word preceding the word being completed on the current command line. | ||||
| second argument ($2) is the word being completed, and the third argument | ||||
| ($3) is the word preceding the word being completed on the current command | ||||
| line. | ||||
| No filtering of the generated completions against the word being completed | ||||
| is performed; the function or command has complete freedom in generating | ||||
| the matches. | ||||
|  | @ -1706,7 +1771,7 @@ The function may use any of the shell facilities, including the | |||
| @code{compgen} and @code{compopt} builtins described below | ||||
| (@pxref{Programmable Completion Builtins}), to generate the matches. | ||||
| It must put the possible completions in the @env{COMPREPLY} array | ||||
| variable. | ||||
| variable, one per array element. | ||||
| 
 | ||||
| Next, any command specified with the @option{-C} option is invoked | ||||
| in an environment equivalent to command substitution. | ||||
|  | @ -1774,17 +1839,18 @@ completion function would load completions dynamically: | |||
| @example | ||||
| _completion_loader() | ||||
| @{ | ||||
| 	. "/etc/bash_completion.d/$1.sh" >/dev/null 2>&1 && return 124 | ||||
|     . "/etc/bash_completion.d/$1.sh" >/dev/null 2>&1 && return 124 | ||||
| @} | ||||
| complete -D -F _completion_loader | ||||
| complete -D -F _completion_loader -o bashdefault -o default | ||||
| @end example | ||||
| 
 | ||||
| @node Programmable Completion Builtins | ||||
| @section Programmable Completion Builtins | ||||
| @cindex completion builtins | ||||
| 
 | ||||
| Two builtin commands are available to manipulate the programmable completion | ||||
| facilities. | ||||
| Three builtin commands are available to manipulate the programmable completion | ||||
| facilities: one to specify how the arguments to a particular command are to | ||||
| be completed, and two to modify the completion as it is happening. | ||||
| 
 | ||||
| @table @code | ||||
| @item compgen | ||||
|  | @ -1871,6 +1937,10 @@ quoting special characters, or suppressing trailing spaces). | |||
| This option is intended to be used with shell functions specified | ||||
| with @option{-F}. | ||||
| 
 | ||||
| @item noquote | ||||
| Tell Readline not to quote the completed words if they are filenames | ||||
| (quoting filenames is the default). | ||||
| 
 | ||||
| @item nospace | ||||
| Tell Readline not to append a space (the default) to words completed at | ||||
| the end of the line. | ||||
|  | @ -1970,6 +2040,10 @@ used as the possible completions. | |||
| @item -F @var{function} | ||||
| The shell function @var{function} is executed in the current shell | ||||
| environment. | ||||
| When it is executed, $1 is the name of the command whose arguments are | ||||
| being completed, $2 is the word being completed, and $3 is the word | ||||
| preceding the word being completed, as described above | ||||
| (@pxref{Programmable Completion}). | ||||
| When it finishes, the possible completions are retrieved from the value | ||||
| of the @env{COMPREPLY} array variable. | ||||
| 
 | ||||
|  | @ -2034,4 +2108,122 @@ specification exists, or an output error occurs. | |||
| 
 | ||||
| @end table | ||||
| 
 | ||||
| @node A Programmable Completion Example | ||||
| @section A Programmable Completion Example | ||||
| 
 | ||||
| The most common way to obtain additional completion functionality beyond | ||||
| the default actions @code{complete} and @code{compgen} provide is to use | ||||
| a shell function and bind it to a particular command using @code{complete -F}. | ||||
| 
 | ||||
| The following function provides completions for the @code{cd} builtin. | ||||
| It is a reasonably good example of what shell functions must do when | ||||
| used for completion.  This function uses the word passsed as @code{$2} | ||||
| to determine the directory name to complete.  You can also use the | ||||
| @code{COMP_WORDS} array variable; the current word is indexed by the | ||||
| @code{COMP_CWORD} variable. | ||||
| 
 | ||||
| The function relies on the @code{complete} and @code{compgen} builtins | ||||
| to do much of the work, adding only the things that the Bash @code{cd} | ||||
| does beyond accepting basic directory names: | ||||
| tilde expansion (@pxref{Tilde Expansion}), | ||||
| searching directories in @var{$CDPATH}, which is described above | ||||
| (@pxref{Bourne Shell Builtins}), | ||||
| and basic support for the @code{cdable_vars} shell option | ||||
| (@pxref{The Shopt Builtin}). | ||||
| @code{_comp_cd} modifies the value of @var{IFS} so that it contains only | ||||
| a newline to accommodate file names containing spaces and tabs -- | ||||
| @code{compgen} prints the possible completions it generates one per line. | ||||
| 
 | ||||
| Possible completions go into the @var{COMPREPLY} array variable, one | ||||
| completion per array element.  The programmable completion system retrieves | ||||
| the completions from there when the function returns. | ||||
| 
 | ||||
| @example | ||||
| # A completion function for the cd builtin | ||||
| # based on the cd completion function from the bash_completion package | ||||
| _comp_cd() | ||||
| @{ | ||||
|     local IFS=$' \t\n'    # normalize IFS | ||||
|     local cur _skipdot _cdpath | ||||
|     local i j k | ||||
| 
 | ||||
|     # Tilde expansion, with side effect of expanding tilde to full pathname | ||||
|     case "$2" in | ||||
|     \~*)    eval cur="$2" ;; | ||||
|     *)      cur=$2 ;; | ||||
|     esac | ||||
| 
 | ||||
|     # no cdpath or absolute pathname -- straight directory completion | ||||
|     if [[ -z "$@{CDPATH:-@}" ]] || [[ "$cur" == @@(./*|../*|/*) ]]; then | ||||
|         # compgen prints paths one per line; could also use while loop | ||||
|         IFS=$'\n' | ||||
|         COMPREPLY=( $(compgen -d -- "$cur") ) | ||||
|         IFS=$' \t\n' | ||||
|     # CDPATH+directories in the current directory if not in CDPATH | ||||
|     else | ||||
|         IFS=$'\n' | ||||
|         _skipdot=false | ||||
|         # preprocess CDPATH to convert null directory names to . | ||||
|         _cdpath=$@{CDPATH/#:/.:@} | ||||
|         _cdpath=$@{_cdpath//::/:.:@} | ||||
|         _cdpath=$@{_cdpath/%:/:.@} | ||||
|         for i in $@{_cdpath//:/$'\n'@}; do | ||||
|             if [[ $i -ef . ]]; then _skipdot=true; fi | ||||
|             k="$@{#COMPREPLY[@@]@}" | ||||
|             for j in $( compgen -d -- "$i/$cur" ); do | ||||
|                 COMPREPLY[k++]=$@{j#$i/@}        # cut off directory | ||||
|             done | ||||
|         done | ||||
|         $_skipdot || COMPREPLY+=( $(compgen -d -- "$cur") ) | ||||
|         IFS=$' \t\n' | ||||
|     fi | ||||
| 
 | ||||
|     # variable names if appropriate shell option set and no completions | ||||
|     if shopt -q cdable_vars && [[ $@{#COMPREPLY[@@]@} -eq 0 ]]; then | ||||
|         COMPREPLY=( $(compgen -v -- "$cur") ) | ||||
|     fi | ||||
| 
 | ||||
|     return 0 | ||||
| @} | ||||
| @end example | ||||
| 
 | ||||
| We install the completion function using the @option{-F} option to | ||||
| @code{complete}: | ||||
| 
 | ||||
| @example | ||||
| # Tell readline to quote appropriate and append slashes to directories; | ||||
| # use the bash default completion for other arguments | ||||
| complete -o filenames -o nospace -o bashdefault -F _comp_cd cd | ||||
| @end example | ||||
| 
 | ||||
| @noindent | ||||
| Since we'd like Bash and Readline to take care of some | ||||
| of the other details for us, we use several other options to tell Bash | ||||
| and Readline what to do.  The @option{-o filenames} option tells Readline | ||||
| that the possible completions should be treated as filenames, and quoted | ||||
| appropriately.  That option will also cause Readline to append a slash to | ||||
| filenames it can determine are directories (which is why we might want to | ||||
| extend @code{_comp_cd} to append a slash if we're using directories found | ||||
| via @var{CDPATH}: Readline can't tell those completions are directories). | ||||
| The @option{-o nospace} option tells Readline to not append a space | ||||
| character to the directory name, in case we want to append to it. | ||||
| The @option{-o bashdefault} option brings in the rest of the "Bash default" | ||||
| completions -- possible completion that Bash adds to the default Readline | ||||
| set.  These include things like command name completion, variable completion | ||||
| for words beginning with @samp{@{}, completions containing pathname | ||||
| expansion patterns (@pxref{Filename Expansion}), and so on. | ||||
| 
 | ||||
| Once installed using @code{complete}, @code{_comp_cd} will be called every | ||||
| time we attempt word completion for a @code{cd} command. | ||||
| 
 | ||||
| Many more examples -- an extensive collection of completions for most of | ||||
| the common GNU, Unix, and Linux commands -- are available as part of the | ||||
| bash_completion project.  This is installed by default on many GNU/Linux | ||||
| distributions.  Originally written by Ian Macdonald, the project now lives | ||||
| at @url{http://bash-completion.alioth.debian.org/}.  There are ports for | ||||
| other systems such as Solaris and Mac OS X. | ||||
| 
 | ||||
| An older version of the bash_completion package is distributed with bash | ||||
| in the @file{examples/complete} subdirectory. | ||||
| 
 | ||||
| @end ifset | ||||
|  |  | |||
|  | @ -2,33 +2,25 @@ | |||
| @comment %**start of header (This is for running Texinfo on a region.) | ||||
| @setfilename rluserman.info | ||||
| @settitle GNU Readline Library | ||||
| @comment %**end of header (This is for running Texinfo on a region.) | ||||
| 
 | ||||
| @include version.texi | ||||
| 
 | ||||
| @comment %**end of header (This is for running Texinfo on a region.) | ||||
| 
 | ||||
| @copying | ||||
| This manual describes the end user interface of the GNU Readline Library | ||||
| (version @value{VERSION}, @value{UPDATED}), a library which aids in the | ||||
| consistency of user interface across discrete programs which provide | ||||
| a command line interface. | ||||
| 
 | ||||
| Copyright @copyright{} 1988--2011 Free Software Foundation, Inc. | ||||
| 
 | ||||
| Permission is granted to make and distribute verbatim copies of | ||||
| this manual provided the copyright notice and this permission notice | ||||
| are preserved on all copies. | ||||
| Copyright @copyright{} 1988--2014 Free Software Foundation, Inc. | ||||
| 
 | ||||
| @quotation | ||||
| Permission is granted to copy, distribute and/or modify this document | ||||
| under the terms of the GNU Free Documentation License, Version 1.3 or | ||||
| any later version published by the Free Software Foundation; with no | ||||
| Invariant Sections, with the Front-Cover texts being ``A GNU Manual'', | ||||
| and with the Back-Cover Texts as in (a) below.  A copy of the license is | ||||
| included in the section entitled ``GNU Free Documentation License''. | ||||
| 
 | ||||
| (a) The FSF's Back-Cover Text is: You are free to copy and modify | ||||
| this GNU manual.  Buying copies from GNU Press supports the FSF in | ||||
| developing GNU and promoting software freedom.'' | ||||
| Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. | ||||
| A copy of the license is included in the section entitled | ||||
| ``GNU Free Documentation License''. | ||||
| 
 | ||||
| @end quotation | ||||
| @end copying | ||||
|  | @ -49,12 +41,6 @@ developing GNU and promoting software freedom.'' | |||
| @vskip 0pt plus 1filll | ||||
| @insertcopying | ||||
| 
 | ||||
| @sp 1 | ||||
| Published by the Free Software Foundation @* | ||||
| 59 Temple Place, Suite 330, @* | ||||
| Boston, MA 02111-1307 @* | ||||
| USA @* | ||||
| 
 | ||||
| @end titlepage | ||||
| 
 | ||||
| @contents | ||||
|  | @ -66,6 +52,7 @@ USA @* | |||
| This document describes the end user interface of the GNU Readline Library, | ||||
| a utility which aids in the consistency of user interface across discrete | ||||
| programs which provide a command line interface. | ||||
| The Readline home page is @url{http://www.gnu.org/software/readline/}. | ||||
| 
 | ||||
| @menu | ||||
| * Command Line Editing::	   GNU Readline User's Manual. | ||||
|  |  | |||
|  | @ -1,10 +1,10 @@ | |||
| @ignore | ||||
| Copyright (C) 1988-2011 Free Software Foundation, Inc.  | ||||
| Copyright (C) 1988-2014 Free Software Foundation, Inc.  | ||||
| @end ignore | ||||
| 
 | ||||
| @set EDITION 6.2 | ||||
| @set VERSION 6.2 | ||||
| @set UPDATED September 6 2010 | ||||
| @set UPDATED-MONTH September 2010 | ||||
| @set EDITION 6.3 | ||||
| @set VERSION 6.3 | ||||
| @set UPDATED 6 January 2014 | ||||
| @set UPDATED-MONTH January 2014 | ||||
| 
 | ||||
| @set LASTCHANGE Mon Sep  6 22:07:10 EDT 2010 | ||||
| @set LASTCHANGE Mon Jan  6 16:26:51 EST 2014 | ||||
|  |  | |||
|  | @ -40,13 +40,14 @@ Copyright (C) 1999 Jeff Solomon | |||
| #include <config.h> | ||||
| #endif | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include <sys/types.h> | ||||
| 
 | ||||
| #ifdef HAVE_UNISTD_H | ||||
| #include <unistd.h> | ||||
| #endif | ||||
| #include <stdlib.h> | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include <termios.h>	/* xxx - should make this more general */ | ||||
| 
 | ||||
| #ifdef READLINE_LIBRARY | ||||
|  | @ -55,6 +56,10 @@ Copyright (C) 1999 Jeff Solomon | |||
| #  include <readline/readline.h> | ||||
| #endif | ||||
| 
 | ||||
| #ifndef STDIN_FILENO | ||||
| #  define STDIN_FILENO 0 | ||||
| #endif | ||||
| 
 | ||||
| /* This little examples demonstrates the alternate interface to using readline.
 | ||||
|  * In the alternate interface, the user maintains control over program flow and | ||||
|  * only calls readline when STDIN is readable. Using the alternate interface, | ||||
|  |  | |||
							
								
								
									
										81
									
								
								lib/readline/examples/rl-callbacktest.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								lib/readline/examples/rl-callbacktest.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,81 @@ | |||
| /* Standard include files. stdio.h is required. */ | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| /* Used for select(2) */ | ||||
| #include <sys/types.h> | ||||
| #include <sys/select.h> | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| /* Standard readline include files. */ | ||||
| #include <readline/readline.h> | ||||
| #include <readline/history.h> | ||||
| 
 | ||||
| static void cb_linehandler (char *); | ||||
| 
 | ||||
| int running; | ||||
| const char *prompt = "rltest$ "; | ||||
| 
 | ||||
| /* Callback function called for each line when accept-line executed, EOF
 | ||||
|    seen, or EOF character read.  This sets a flag and returns; it could | ||||
|    also call exit(3). */ | ||||
| static void | ||||
| cb_linehandler (char *line) | ||||
| { | ||||
|   /* Can use ^D (stty eof) or `exit' to exit. */ | ||||
|   if (line == NULL || strcmp (line, "exit") == 0) | ||||
|     { | ||||
|       if (line == 0) | ||||
|         printf ("\n"); | ||||
|       printf ("exit\n"); | ||||
|       /* This function needs to be called to reset the terminal settings,
 | ||||
| 	 and calling it from the line handler keeps one extra prompt from | ||||
| 	 being displayed. */ | ||||
|       rl_callback_handler_remove (); | ||||
| 
 | ||||
|       running = 0; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       if (*line) | ||||
| 	add_history (line); | ||||
|       printf ("input line: %s\n", line); | ||||
|       free (line); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| int | ||||
| main (int c, char **v) | ||||
| { | ||||
|   fd_set fds; | ||||
|   int r; | ||||
| 
 | ||||
|   /* Install the line handler. */ | ||||
|   rl_callback_handler_install (prompt, cb_linehandler); | ||||
| 
 | ||||
|   /* Enter a simple event loop.  This waits until something is available
 | ||||
|      to read on readline's input stream (defaults to standard input) and | ||||
|      calls the builtin character read callback to read it.  It does not | ||||
|      have to modify the user's terminal settings. */ | ||||
|   running = 1; | ||||
|   while (running) | ||||
|     { | ||||
|       FD_ZERO (&fds); | ||||
|       FD_SET (fileno (rl_instream), &fds);     | ||||
| 
 | ||||
|       r = select (FD_SETSIZE, &fds, NULL, NULL, NULL); | ||||
|       if (r < 0) | ||||
| 	{ | ||||
| 	  perror ("rltest: select"); | ||||
| 	  rl_callback_handler_remove (); | ||||
| 	  break; | ||||
| 	} | ||||
| 
 | ||||
|       if (FD_ISSET (fileno (rl_instream), &fds)) | ||||
| 	rl_callback_read_char (); | ||||
|     } | ||||
| 
 | ||||
|   printf ("rltest: Event loop has exited\n"); | ||||
|   return 0; | ||||
| } | ||||
|  | @ -98,6 +98,8 @@ static const FUNMAP default_funmap[] = { | |||
|   { "forward-word", rl_forward_word }, | ||||
|   { "history-search-backward", rl_history_search_backward }, | ||||
|   { "history-search-forward", rl_history_search_forward }, | ||||
|   { "history-substring-search-backward", rl_history_substr_search_backward }, | ||||
|   { "history-substring-search-forward", rl_history_substr_search_forward }, | ||||
|   { "insert-comment", rl_insert_comment }, | ||||
|   { "insert-completions", rl_insert_completions }, | ||||
|   { "kill-whole-line", rl_kill_full_line }, | ||||
|  | @ -118,6 +120,7 @@ static const FUNMAP default_funmap[] = { | |||
| #endif | ||||
|   { "possible-completions", rl_possible_completions }, | ||||
|   { "previous-history", rl_get_previous_history }, | ||||
|   { "print-last-kbd-macro", rl_print_last_kbd_macro }, | ||||
|   { "quoted-insert", rl_quoted_insert }, | ||||
|   { "re-read-init-file", rl_re_read_init_file }, | ||||
|   { "redraw-current-line", rl_refresh_line}, | ||||
|  | @ -236,7 +239,7 @@ rl_initialize_funmap () | |||
| 
 | ||||
| /* Produce a NULL terminated array of known function names.  The array
 | ||||
|    is sorted.  The array itself is allocated, but not the strings inside. | ||||
|    You should free () the array when you done, but not the pointrs. */ | ||||
|    You should free () the array when you done, but not the pointers. */ | ||||
| const char ** | ||||
| rl_funmap_names () | ||||
| { | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| /* histexpand.c -- history expansion. */ | ||||
| 
 | ||||
| /* Copyright (C) 1989-2010 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 1989-2012 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file contains the GNU History Library (History), a set of | ||||
|    routines for managing the text of previously typed lines. | ||||
|  | @ -272,6 +272,8 @@ get_history_event (string, caller_index, delimiting_quote) | |||
|       if (local_index == 0 || substring_okay) | ||||
| 	{ | ||||
| 	  entry = current_history (); | ||||
| 	  if (entry == 0) | ||||
| 	    FAIL_SEARCH (); | ||||
| 	  history_offset = history_length; | ||||
| 	 | ||||
| 	  /* If this was a substring search, then remember the
 | ||||
|  | @ -519,9 +521,9 @@ postproc_subst_rhs () | |||
|    the returned string.  Returns the new index into string in | ||||
|    *END_INDEX_PTR, and the expanded specifier in *RET_STRING. */ | ||||
| static int | ||||
| history_expand_internal (string, start, end_index_ptr, ret_string, current_line) | ||||
| history_expand_internal (string, start, qc, end_index_ptr, ret_string, current_line) | ||||
|      char *string; | ||||
|      int start, *end_index_ptr; | ||||
|      int start, qc, *end_index_ptr; | ||||
|      char **ret_string; | ||||
|      char *current_line;	/* for !# */ | ||||
| { | ||||
|  | @ -557,30 +559,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line) | |||
|       event = current_line; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       int quoted_search_delimiter = 0; | ||||
| 
 | ||||
|       /* If the character before this `!' is a double or single
 | ||||
| 	 quote, then this expansion takes place inside of the | ||||
| 	 quoted string.  If we have to search for some text ("!foo"), | ||||
| 	 allow the delimiter to end the search string. */ | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
|       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | ||||
| 	{ | ||||
| 	  int ch, l; | ||||
| 	  l = _rl_find_prev_mbchar (string, i, MB_FIND_ANY); | ||||
| 	  ch = string[l]; | ||||
| 	  /* XXX - original patch had i - 1 ???  If i == 0 it would fail. */ | ||||
| 	  if (i && (ch == '\'' || ch == '"')) | ||||
| 	    quoted_search_delimiter = ch; | ||||
| 	} | ||||
|       else | ||||
| #endif /* HANDLE_MULTIBYTE */	   | ||||
| 	if (i && (string[i - 1] == '\'' || string[i - 1] == '"')) | ||||
| 	  quoted_search_delimiter = string[i - 1]; | ||||
| 
 | ||||
|       event = get_history_event (string, &i, quoted_search_delimiter); | ||||
|     } | ||||
|     event = get_history_event (string, &i, qc); | ||||
| 	   | ||||
|   if (event == 0) | ||||
|     { | ||||
|  | @ -854,7 +833,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line) | |||
| 	} | ||||
|       i += 2; | ||||
|     } | ||||
|   /* Done with modfiers. */ | ||||
|   /* Done with modifiers. */ | ||||
|   /* Believe it or not, we have to back the pointer up by one. */ | ||||
|   --i; | ||||
| 
 | ||||
|  | @ -928,7 +907,7 @@ history_expand (hstring, output) | |||
|      char **output; | ||||
| { | ||||
|   register int j; | ||||
|   int i, r, l, passc, cc, modified, eindex, only_printing, dquote, flag; | ||||
|   int i, r, l, passc, cc, modified, eindex, only_printing, dquote, squote, flag; | ||||
|   char *string; | ||||
| 
 | ||||
|   /* The output string, and its length. */ | ||||
|  | @ -991,7 +970,7 @@ history_expand (hstring, output) | |||
| 
 | ||||
|       /* `!' followed by one of the characters in history_no_expand_chars
 | ||||
| 	 is NOT an expansion. */ | ||||
|       for (i = dquote = 0; string[i]; i++) | ||||
|       for (i = dquote = squote = 0; string[i]; i++) | ||||
| 	{ | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
| 	  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | ||||
|  | @ -1022,6 +1001,13 @@ history_expand (hstring, output) | |||
| 	    { | ||||
| 	      if (cc == 0 || member (cc, history_no_expand_chars)) | ||||
| 		continue; | ||||
| 	      /* DQUOTE won't be set unless history_quotes_inhibit_expansion
 | ||||
| 		 is set.  The idea here is to treat double-quoted strings the | ||||
| 		 same as the word outside double quotes; in effect making the | ||||
| 		 double quote part of history_no_expand_chars when DQUOTE is | ||||
| 		 set. */ | ||||
| 	      else if (dquote && cc == '"') | ||||
| 		continue; | ||||
| 	      /* If the calling application has set
 | ||||
| 		 history_inhibit_expansion_function to a function that checks | ||||
| 		 for special cases that should not be history expanded, | ||||
|  | @ -1071,9 +1057,9 @@ history_expand (hstring, output) | |||
|     } | ||||
| 
 | ||||
|   /* Extract and perform the substitution. */ | ||||
|   for (passc = dquote = i = j = 0; i < l; i++) | ||||
|   for (passc = dquote = squote = i = j = 0; i < l; i++) | ||||
|     { | ||||
|       int tchar = string[i]; | ||||
|       int qc, tchar = string[i]; | ||||
| 
 | ||||
|       if (passc) | ||||
| 	{ | ||||
|  | @ -1130,8 +1116,14 @@ history_expand (hstring, output) | |||
| 	case '\'': | ||||
| 	  { | ||||
| 	    /* If history_quotes_inhibit_expansion is set, single quotes
 | ||||
| 	       inhibit history expansion. */ | ||||
| 	    if (dquote == 0 && history_quotes_inhibit_expansion) | ||||
| 	       inhibit history expansion, otherwise they are treated like | ||||
| 	       double quotes. */ | ||||
| 	    if (squote) | ||||
| 	      { | ||||
| 	        squote = 0; | ||||
| 	        ADD_CHAR (tchar); | ||||
| 	      } | ||||
| 	    else if (dquote == 0 && history_quotes_inhibit_expansion) | ||||
| 	      { | ||||
| 		int quote, slen; | ||||
| 
 | ||||
|  | @ -1146,6 +1138,11 @@ history_expand (hstring, output) | |||
| 		ADD_STRING (temp); | ||||
| 		xfree (temp); | ||||
| 	      } | ||||
| 	    else if (dquote == 0 && squote == 0 && history_quotes_inhibit_expansion == 0) | ||||
| 	      { | ||||
| 	        squote = 1; | ||||
| 	        ADD_CHAR (string[i]); | ||||
| 	      } | ||||
| 	    else | ||||
| 	      ADD_CHAR (string[i]); | ||||
| 	    break; | ||||
|  | @ -1171,6 +1168,7 @@ history_expand (hstring, output) | |||
| 	     characters in history_no_expand_chars, then it is not a | ||||
| 	     candidate for expansion of any kind. */ | ||||
| 	  if (cc == 0 || member (cc, history_no_expand_chars) || | ||||
| 			 (dquote && cc == '"') || | ||||
| 	  		 (history_inhibit_expansion_function && (*history_inhibit_expansion_function) (string, i))) | ||||
| 	    { | ||||
| 	      ADD_CHAR (string[i]); | ||||
|  | @ -1196,8 +1194,8 @@ history_expand (hstring, output) | |||
| 	      break; | ||||
| 	    } | ||||
| #endif | ||||
| 
 | ||||
| 	  r = history_expand_internal (string, i, &eindex, &temp, result); | ||||
| 	  qc = squote ? '\'' : (dquote ? '"' : 0); | ||||
| 	  r = history_expand_internal (string, i, qc, &eindex, &temp, result); | ||||
| 	  if (r < 0) | ||||
| 	    { | ||||
| 	      *output = temp; | ||||
|  |  | |||
|  | @ -125,14 +125,7 @@ history_filename (filename) | |||
|   home = sh_get_env_value ("HOME"); | ||||
| 
 | ||||
|   if (home == 0) | ||||
|     { | ||||
| #if 0 | ||||
|       home = "."; | ||||
|       home_len = 1; | ||||
| #else | ||||
|       return (NULL); | ||||
| #endif | ||||
|     } | ||||
|     return (NULL); | ||||
|   else | ||||
|     home_len = strlen (home); | ||||
| 
 | ||||
|  | @ -148,6 +141,21 @@ history_filename (filename) | |||
|   return (return_val); | ||||
| } | ||||
| 
 | ||||
| static char * | ||||
| history_backupfile (filename) | ||||
|      const char *filename; | ||||
| { | ||||
|   char *ret; | ||||
|   size_t len; | ||||
| 
 | ||||
|   len = strlen (filename); | ||||
|   ret = xmalloc (len + 2); | ||||
|   strcpy (ret, filename); | ||||
|   ret[len] = '-'; | ||||
|   ret[len+1] = '\0'; | ||||
|   return ret; | ||||
| } | ||||
|    | ||||
| /* Add the contents of FILENAME to the history list, a line at a time.
 | ||||
|    If FILENAME is NULL, then read from ~/.history.  Returns 0 if | ||||
|    successful, or errno if not. */ | ||||
|  | @ -403,14 +411,16 @@ history_truncate_file (fname, lines) | |||
|      truncate to. */ | ||||
|   if (bp > buffer && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1)) | ||||
|     { | ||||
|       write (file, bp, chars_read - (bp - buffer)); | ||||
|       if (write (file, bp, chars_read - (bp - buffer)) < 0) | ||||
| 	rv = errno; | ||||
| 
 | ||||
| #if defined (__BEOS__) | ||||
|       /* BeOS ignores O_TRUNC. */ | ||||
|       ftruncate (file, chars_read - (bp - buffer)); | ||||
| #endif | ||||
| 
 | ||||
|       close (file); | ||||
|       if (close (file) < 0 && rv == 0) | ||||
| 	rv = errno; | ||||
|     } | ||||
| 
 | ||||
|  truncate_exit: | ||||
|  | @ -430,7 +440,7 @@ history_do_write (filename, nelements, overwrite) | |||
|      int nelements, overwrite; | ||||
| { | ||||
|   register int i; | ||||
|   char *output; | ||||
|   char *output, *bakname; | ||||
|   int file, mode, rv; | ||||
| #ifdef HISTORY_USE_MMAP | ||||
|   size_t cursize; | ||||
|  | @ -440,13 +450,22 @@ history_do_write (filename, nelements, overwrite) | |||
|   mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY; | ||||
| #endif | ||||
|   output = history_filename (filename); | ||||
|   bakname = (overwrite && output) ? history_backupfile (output) : 0; | ||||
| 
 | ||||
|   if (output && bakname) | ||||
|     rename (output, bakname); | ||||
| 
 | ||||
|   file = output ? open (output, mode, 0600) : -1; | ||||
|   rv = 0; | ||||
| 
 | ||||
|   if (file == -1) | ||||
|     { | ||||
|       rv = errno; | ||||
|       if (output && bakname) | ||||
|         rename (bakname, output); | ||||
|       FREE (output); | ||||
|       return (errno); | ||||
|       FREE (bakname); | ||||
|       return (rv); | ||||
|     } | ||||
| 
 | ||||
| #ifdef HISTORY_USE_MMAP | ||||
|  | @ -486,8 +505,11 @@ history_do_write (filename, nelements, overwrite) | |||
|       { | ||||
| mmap_error: | ||||
| 	rv = errno; | ||||
| 	FREE (output); | ||||
| 	close (file); | ||||
| 	if (output && bakname) | ||||
| 	  rename (bakname, output); | ||||
| 	FREE (output); | ||||
| 	FREE (bakname); | ||||
| 	return rv; | ||||
|       } | ||||
| #else     | ||||
|  | @ -495,8 +517,11 @@ mmap_error: | |||
|     if (buffer == 0) | ||||
|       { | ||||
|       	rv = errno; | ||||
| 	FREE (output); | ||||
| 	close (file); | ||||
| 	if (output && bakname) | ||||
| 	  rename (bakname, output); | ||||
| 	FREE (output); | ||||
| 	FREE (bakname); | ||||
| 	return rv; | ||||
|       } | ||||
| #endif | ||||
|  | @ -524,9 +549,16 @@ mmap_error: | |||
| #endif | ||||
|   } | ||||
| 
 | ||||
|   close (file); | ||||
|   if (close (file) < 0 && rv == 0) | ||||
|     rv = errno; | ||||
| 
 | ||||
|   if (rv != 0 && output && bakname) | ||||
|     rename (bakname, output); | ||||
|   else if (rv == 0 && bakname) | ||||
|     unlink (bakname); | ||||
| 
 | ||||
|   FREE (output); | ||||
|   FREE (bakname); | ||||
| 
 | ||||
|   return (rv); | ||||
| } | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| /* history.c -- standalone history library */ | ||||
| 
 | ||||
| /* Copyright (C) 1989-2009 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 1989-2011 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file contains the GNU History Library (History), a set of | ||||
|    routines for managing the text of previously typed lines. | ||||
|  | @ -236,7 +236,7 @@ history_get_time (hist) | |||
|   ts = hist->timestamp; | ||||
|   if (ts[0] != history_comment_char) | ||||
|     return 0; | ||||
|   t = (time_t) atol (ts + 1);		/* XXX - should use strtol() here */ | ||||
|   t = (time_t) strtol (ts + 1, (char **)NULL, 10);		/* XXX - should use strtol() here */ | ||||
|   return t; | ||||
| } | ||||
| 
 | ||||
|  | @ -318,7 +318,7 @@ add_history_time (string) | |||
| { | ||||
|   HIST_ENTRY *hs; | ||||
| 
 | ||||
|   if (string == 0) | ||||
|   if (string == 0 || history_length < 1) | ||||
|     return; | ||||
|   hs = the_history[history_length - 1]; | ||||
|   FREE (hs->timestamp); | ||||
|  | @ -394,7 +394,7 @@ replace_history_entry (which, line, data) | |||
|    WHICH >= 0 means to replace that particular history entry's data, as | ||||
|    long as it matches OLD. */ | ||||
| void | ||||
| replace_history_data (which,old, new) | ||||
| replace_history_data (which, old, new) | ||||
|      int which; | ||||
|      histdata_t *old, *new; | ||||
| { | ||||
|  |  | |||
|  | @ -216,7 +216,7 @@ extern int history_truncate_file PARAMS((const char *, int)); | |||
|   -1) If there was an error in expansion. | ||||
|    2) If the returned line should just be printed. | ||||
| 
 | ||||
|   If an error ocurred in expansion, then OUTPUT contains a descriptive | ||||
|   If an error occurred in expansion, then OUTPUT contains a descriptive | ||||
|   error message. */ | ||||
| extern int history_expand PARAMS((char *, char **)); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| /* input.c -- character input functions for readline. */ | ||||
| 
 | ||||
| /* Copyright (C) 1994-2010 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 1994-2013 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file is part of the GNU Readline Library (Readline), a library | ||||
|    for reading lines of text with interactive input and history editing.       | ||||
|  | @ -45,6 +45,8 @@ | |||
| #  include "ansi_stdlib.h" | ||||
| #endif /* HAVE_STDLIB_H */ | ||||
| 
 | ||||
| #include <signal.h> | ||||
| 
 | ||||
| #include "posixselect.h" | ||||
| 
 | ||||
| #if defined (FIONREAD_IN_SYS_IOCTL) | ||||
|  | @ -78,6 +80,13 @@ extern int errno; | |||
|    character input. */ | ||||
| rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL; | ||||
| 
 | ||||
| /* A function to call if a read(2) is interrupted by a signal. */ | ||||
| rl_hook_func_t *rl_signal_event_hook = (rl_hook_func_t *)NULL; | ||||
| 
 | ||||
| /* A function to replace _rl_input_available for applications using the
 | ||||
|    callback interface. */ | ||||
| rl_hook_func_t *rl_input_available_hook = (rl_hook_func_t *)NULL; | ||||
| 
 | ||||
| rl_getc_func_t *rl_getc_function = rl_getc; | ||||
| 
 | ||||
| static int _keyboard_input_timeout = 100000;		/* 0.1 seconds; it's in usec */ | ||||
|  | @ -104,6 +113,12 @@ _rl_any_typein () | |||
|   return any_typein; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| _rl_pushed_input_available () | ||||
| { | ||||
|   return (push_index != pop_index); | ||||
| } | ||||
| 
 | ||||
| /* Return the amount of space available in the buffer for stuffing
 | ||||
|    characters. */ | ||||
| static int | ||||
|  | @ -117,7 +132,7 @@ ibuffer_space () | |||
| 
 | ||||
| /* Get a key from the buffer of characters to be read.
 | ||||
|    Return the key in KEY. | ||||
|    Result is KEY if there was a key, or 0 if there wasn't. */ | ||||
|    Result is non-zero if there was a key, or 0 if there wasn't. */ | ||||
| static int | ||||
| rl_get_char (key) | ||||
|      int *key; | ||||
|  | @ -154,12 +169,6 @@ _rl_unget_char (key) | |||
|   return (0); | ||||
| } | ||||
| 
 | ||||
| int | ||||
| _rl_pushed_input_available () | ||||
| { | ||||
|   return (push_index != pop_index); | ||||
| } | ||||
| 
 | ||||
| /* If a character is available to be read, then read it and stuff it into
 | ||||
|    IBUFFER.  Otherwise, just return.  Returns number of characters read | ||||
|    (0 if none available) and -1 on error (EIO). */ | ||||
|  | @ -291,6 +300,9 @@ _rl_input_available () | |||
| #endif | ||||
|   int tty; | ||||
| 
 | ||||
|   if (rl_input_available_hook) | ||||
|     return (*rl_input_available_hook) (); | ||||
| 
 | ||||
|   tty = fileno (rl_instream); | ||||
| 
 | ||||
| #if defined (HAVE_SELECT) | ||||
|  | @ -411,8 +423,6 @@ rl_read_key () | |||
| { | ||||
|   int c, r; | ||||
| 
 | ||||
|   rl_key_sequence_length++; | ||||
| 
 | ||||
|   if (rl_pending_input) | ||||
|     { | ||||
|       c = rl_pending_input; | ||||
|  | @ -437,7 +447,7 @@ rl_read_key () | |||
| 		  rl_done = 1; | ||||
| 		  return ('\n'); | ||||
| 		} | ||||
| 	      else if (r == 1)			/* read something */ | ||||
| 	      else if (r > 0)			/* read something */ | ||||
| 		continue; | ||||
| 
 | ||||
| 	      RL_CHECK_SIGNALS (); | ||||
|  | @ -450,6 +460,7 @@ rl_read_key () | |||
| 	{ | ||||
| 	  if (rl_get_char (&c) == 0) | ||||
| 	    c = (*rl_getc_function) (rl_instream); | ||||
| /* fprintf(stderr, "rl_read_key: calling RL_CHECK_SIGNALS: _rl_caught_signal = %d", _rl_caught_signal); */ | ||||
| 	  RL_CHECK_SIGNALS (); | ||||
| 	} | ||||
|     } | ||||
|  | @ -468,6 +479,8 @@ rl_getc (stream) | |||
|     { | ||||
|       RL_CHECK_SIGNALS (); | ||||
| 
 | ||||
|       /* We know at this point that _rl_caught_signal == 0 */ | ||||
| 
 | ||||
| #if defined (__MINGW32__) | ||||
|       if (isatty (fileno (stream))) | ||||
| 	return (getch ()); | ||||
|  | @ -509,11 +522,23 @@ rl_getc (stream) | |||
| #undef X_EWOULDBLOCK | ||||
| #undef X_EAGAIN | ||||
| 
 | ||||
|       /* If the error that we received was SIGINT, then try again,
 | ||||
| 	 this is simply an interrupted system call to read (). | ||||
| 	 Otherwise, some error ocurred, also signifying EOF. */ | ||||
| /* fprintf(stderr, "rl_getc: result = %d errno = %d\n", result, errno); */ | ||||
| 
 | ||||
|       /* If the error that we received was EINTR, then try again,
 | ||||
| 	 this is simply an interrupted system call to read ().  We allow | ||||
| 	 the read to be interrupted if we caught SIGHUP or SIGTERM (but | ||||
| 	 not SIGINT; let the signal handler deal with that), but if the | ||||
| 	 application sets an event hook, call it for other signals. | ||||
| 	 Otherwise (not EINTR), some error occurred, also signifying EOF. */ | ||||
|       if (errno != EINTR) | ||||
| 	return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF); | ||||
|       else if (_rl_caught_signal == SIGHUP || _rl_caught_signal == SIGTERM) | ||||
| 	return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF); | ||||
|       else if (_rl_caught_signal == SIGINT || _rl_caught_signal == SIGQUIT) | ||||
|         RL_CHECK_SIGNALS (); | ||||
| 
 | ||||
|       if (rl_signal_event_hook) | ||||
| 	(*rl_signal_event_hook) (); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ | |||
| /*								    */ | ||||
| /* **************************************************************** */ | ||||
| 
 | ||||
| /* Copyright (C) 1987-2009 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 1987-2012 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file is part of the GNU Readline Library (Readline), a library | ||||
|    for reading lines of text with interactive input and history editing.       | ||||
|  | @ -110,7 +110,7 @@ _rl_scxt_alloc (type, flags) | |||
|   cxt->history_pos = 0; | ||||
|   cxt->direction = 0; | ||||
| 
 | ||||
|   cxt->lastc = 0; | ||||
|   cxt->prevc = cxt->lastc = 0; | ||||
| 
 | ||||
|   cxt->sline = 0; | ||||
|   cxt->sline_len = cxt->sline_index = 0; | ||||
|  | @ -156,16 +156,16 @@ rl_forward_search_history (sign, key) | |||
|    WHERE is the history list number of the current line.  If it is | ||||
|    -1, then this line is the starting one. */ | ||||
| static void | ||||
| rl_display_search (search_string, reverse_p, where) | ||||
| rl_display_search (search_string, flags, where) | ||||
|      char *search_string; | ||||
|      int reverse_p, where; | ||||
|      int flags, where; | ||||
| { | ||||
|   char *message; | ||||
|   int msglen, searchlen; | ||||
| 
 | ||||
|   searchlen = (search_string && *search_string) ? strlen (search_string) : 0; | ||||
| 
 | ||||
|   message = (char *)xmalloc (searchlen + 33); | ||||
|   message = (char *)xmalloc (searchlen + 64); | ||||
|   msglen = 0; | ||||
| 
 | ||||
| #if defined (NOTDEF) | ||||
|  | @ -178,7 +178,13 @@ rl_display_search (search_string, reverse_p, where) | |||
| 
 | ||||
|   message[msglen++] = '('; | ||||
| 
 | ||||
|   if (reverse_p) | ||||
|   if (flags & SF_FAILED) | ||||
|     { | ||||
|       strcpy (message + msglen, "failed "); | ||||
|       msglen += 7; | ||||
|     } | ||||
| 
 | ||||
|   if (flags & SF_REVERSE) | ||||
|     { | ||||
|       strcpy (message + msglen, "reverse-"); | ||||
|       msglen += 8; | ||||
|  | @ -215,7 +221,7 @@ _rl_isearch_init (direction) | |||
|   cxt->search_terminators = _rl_isearch_terminators ? _rl_isearch_terminators | ||||
| 						: default_isearch_terminators; | ||||
| 
 | ||||
|   /* Create an arrary of pointers to the lines that we want to search. */ | ||||
|   /* Create an array of pointers to the lines that we want to search. */ | ||||
|   hlist = history_list (); | ||||
|   rl_maybe_replace_line (); | ||||
|   i = 0; | ||||
|  | @ -312,13 +318,19 @@ _rl_search_getchar (cxt) | |||
|   RL_UNSETSTATE(RL_STATE_MOREINPUT); | ||||
| 
 | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
|   /* This ends up with C (and LASTC) being set to the last byte of the
 | ||||
|      multibyte character.  In most cases c == lastc == mb[0] */ | ||||
|   if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | ||||
|     c = cxt->lastc = _rl_read_mbstring (cxt->lastc, cxt->mb, MB_LEN_MAX); | ||||
| #endif | ||||
| 
 | ||||
|   RL_CHECK_SIGNALS (); | ||||
|   return c; | ||||
| } | ||||
| 
 | ||||
| #define ENDSRCH_CHAR(c) \ | ||||
|   ((CTRL_CHAR (c) || META_CHAR (c) || (c) == RUBOUT) && ((c) != CTRL ('G'))) | ||||
| 
 | ||||
| /* Process just-read character C according to isearch context CXT.  Return
 | ||||
|    -1 if the caller should just free the context and return, 0 if we should | ||||
|    break out of the loop, and 1 if we should continue to read characters. */ | ||||
|  | @ -344,13 +356,43 @@ _rl_isearch_dispatch (cxt, c) | |||
|      incremental search, so we check */ | ||||
|   if (c >= 0 && cxt->keymap[c].type == ISKMAP && strchr (cxt->search_terminators, cxt->lastc) == 0) | ||||
|     { | ||||
|       /* _rl_keyseq_timeout specified in milliseconds; _rl_input_queued
 | ||||
| 	 takes microseconds, so multiply by 1000.  If we don't get any | ||||
| 	 additional input and this keymap shadows another function, process | ||||
| 	 that key as if it was all we read. */ | ||||
|       if (_rl_keyseq_timeout > 0 && | ||||
| 	    RL_ISSTATE (RL_STATE_CALLBACK) == 0 && | ||||
| 	    RL_ISSTATE (RL_STATE_INPUTPENDING) == 0 && | ||||
| 	    _rl_pushed_input_available () == 0 && | ||||
| 	    ((Keymap)(cxt->keymap[c].function))[ANYOTHERKEY].function && | ||||
| 	    _rl_input_queued (_rl_keyseq_timeout*1000) == 0) | ||||
| 	goto add_character; | ||||
| 
 | ||||
|       cxt->okeymap = cxt->keymap; | ||||
|       cxt->keymap = FUNCTION_TO_KEYMAP (cxt->keymap, c); | ||||
|       cxt->sflags |= SF_CHGKMAP; | ||||
|       /* XXX - we should probably save this sequence, so we can do
 | ||||
| 	 something useful if this doesn't end up mapping to a command. */ | ||||
| 	 something useful if this doesn't end up mapping to a command we | ||||
| 	 interpret here.  Right now we just save the most recent character | ||||
| 	 that caused the index into a new keymap. */ | ||||
|       cxt->prevc = c; | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
|       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | ||||
| 	{ | ||||
| 	  if (cxt->mb[1] == 0) | ||||
| 	    { | ||||
| 	      cxt->pmb[0] = c;		/* XXX should be == cxt->mb[0] */ | ||||
| 	      cxt->pmb[1] = '\0'; | ||||
| 	    } | ||||
| 	  else | ||||
| 	    memcpy (cxt->pmb, cxt->mb, sizeof (cxt->pmb)); | ||||
| 	} | ||||
| #endif | ||||
|       return 1; | ||||
|     } | ||||
| 
 | ||||
| add_character: | ||||
| 
 | ||||
|   /* Translate the keys we do something with to opcodes. */ | ||||
|   if (c >= 0 && cxt->keymap[c].type == ISFUNC) | ||||
|     { | ||||
|  | @ -376,6 +418,54 @@ _rl_isearch_dispatch (cxt, c) | |||
|     { | ||||
|       cxt->keymap = cxt->okeymap; | ||||
|       cxt->sflags &= ~SF_CHGKMAP; | ||||
|       /* If we indexed into a new keymap, but didn't map to a command that
 | ||||
| 	 affects the search (lastc > 0), and the character that mapped to a | ||||
| 	 new keymap would have ended the search (ENDSRCH_CHAR(cxt->prevc)), | ||||
| 	 handle that now as if the previous char would have ended the search | ||||
| 	 and we would have read the current character. */ | ||||
|       /* XXX - should we check cxt->mb? */ | ||||
|       if (cxt->lastc > 0 && ENDSRCH_CHAR (cxt->prevc)) | ||||
| 	{ | ||||
| 	  rl_stuff_char (cxt->lastc); | ||||
| 	  rl_execute_next (cxt->prevc); | ||||
| 	  /* XXX - do we insert everything in cxt->pmb? */ | ||||
| 	  return (0); | ||||
| 	} | ||||
|       /* Otherwise, if the current character is mapped to self-insert or
 | ||||
| 	 nothing (i.e., not an editing command), and the previous character | ||||
| 	 was a keymap index, then we need to insert both the previous | ||||
| 	 character and the current character into the search string. */ | ||||
|       else if (cxt->lastc > 0 && cxt->prevc > 0 && | ||||
| 	       cxt->keymap[cxt->prevc].type == ISKMAP && | ||||
| 	       (f == 0 || f == rl_insert)) | ||||
| 	{ | ||||
| 	  /* Make lastc be the next character read */ | ||||
| 	  /* XXX - do we insert everything in cxt->mb? */ | ||||
| 	  rl_execute_next (cxt->lastc); | ||||
| 	  /* Dispatch on the previous character (insert into search string) */ | ||||
| 	  cxt->lastc = cxt->prevc; | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
| 	  /* Have to overwrite cxt->mb here because dispatch uses it below */ | ||||
| 	  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | ||||
| 	    {   | ||||
| 	      if (cxt->pmb[1] == 0)	   | ||||
| 		{ | ||||
| 		  cxt->mb[0] = cxt->lastc;	/* == cxt->prevc */ | ||||
| 		  cxt->mb[1] = '\0'; | ||||
| 		} | ||||
| 	      else | ||||
| 		memcpy (cxt->mb, cxt->pmb, sizeof (cxt->mb)); | ||||
| 	    } | ||||
| #endif | ||||
| 	  cxt->prevc = 0;	   | ||||
| 	} | ||||
|       else if (cxt->lastc > 0 && cxt->prevc > 0 && f && f != rl_insert) | ||||
| 	{ | ||||
| 	  rl_stuff_char (cxt->lastc); | ||||
| 	  rl_execute_next (cxt->prevc); | ||||
| 	  /* XXX - do we insert everything in cxt->pmb? */ | ||||
| 	  return (0); | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
|   /* The characters in isearch_terminators (set from the user-settable
 | ||||
|  | @ -393,14 +483,11 @@ _rl_isearch_dispatch (cxt, c) | |||
| 	 XXX - since _rl_input_available depends on the application- | ||||
| 	 settable keyboard timeout value, this could alternatively | ||||
| 	 use _rl_input_queued(100000) */ | ||||
|       if (cxt->lastc == ESC && _rl_input_available ()) | ||||
|       if (cxt->lastc == ESC && (_rl_pushed_input_available () || _rl_input_available ())) | ||||
| 	rl_execute_next (ESC); | ||||
|       return (0); | ||||
|     } | ||||
| 
 | ||||
| #define ENDSRCH_CHAR(c) \ | ||||
|   ((CTRL_CHAR (c) || META_CHAR (c) || (c) == RUBOUT) && ((c) != CTRL ('G'))) | ||||
| 
 | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
|   if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | ||||
|     { | ||||
|  | @ -436,7 +523,7 @@ _rl_isearch_dispatch (cxt, c) | |||
| 	      cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size); | ||||
| 	      strcpy (cxt->search_string, last_isearch_string); | ||||
| 	      cxt->search_string_index = last_isearch_string_len; | ||||
| 	      rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), -1); | ||||
| 	      rl_display_search (cxt->search_string, cxt->sflags, -1); | ||||
| 	      break; | ||||
| 	    } | ||||
| 	  return (1); | ||||
|  | @ -544,12 +631,16 @@ _rl_isearch_dispatch (cxt, c) | |||
|       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) | ||||
| 	{ | ||||
| 	  int j, l; | ||||
| 	  for (j = 0, l = strlen (cxt->mb); j < l; ) | ||||
| 	    cxt->search_string[cxt->search_string_index++] = cxt->mb[j++]; | ||||
| 
 | ||||
| 	  if (cxt->mb[0] == 0 || cxt->mb[1] == 0) | ||||
| 	    cxt->search_string[cxt->search_string_index++] = cxt->mb[0]; | ||||
| 	  else | ||||
| 	    for (j = 0, l = RL_STRLEN (cxt->mb); j < l; ) | ||||
| 	      cxt->search_string[cxt->search_string_index++] = cxt->mb[j++]; | ||||
| 	} | ||||
|       else | ||||
| #endif | ||||
| 	cxt->search_string[cxt->search_string_index++] = c; | ||||
| 	cxt->search_string[cxt->search_string_index++] = cxt->lastc;	/* XXX - was c instead of lastc */ | ||||
|       cxt->search_string[cxt->search_string_index] = '\0'; | ||||
|       break; | ||||
|     } | ||||
|  | @ -606,6 +697,7 @@ _rl_isearch_dispatch (cxt, c) | |||
|       /* We cannot find the search string.  Ding the bell. */ | ||||
|       rl_ding (); | ||||
|       cxt->history_pos = cxt->last_found_line; | ||||
|       rl_display_search (cxt->search_string, cxt->sflags, (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos); | ||||
|       return 1; | ||||
|     } | ||||
| 
 | ||||
|  | @ -618,7 +710,7 @@ _rl_isearch_dispatch (cxt, c) | |||
|       rl_replace_line (cxt->lines[cxt->history_pos], 0); | ||||
|       rl_point = cxt->sline_index; | ||||
|       cxt->last_found_line = cxt->history_pos; | ||||
|       rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos); | ||||
|       rl_display_search (cxt->search_string, cxt->sflags, (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos); | ||||
|     } | ||||
| 
 | ||||
|   return 1; | ||||
|  | @ -653,7 +745,7 @@ rl_search_history (direction, invoking_key) | |||
|   RL_SETSTATE(RL_STATE_ISEARCH); | ||||
|   cxt = _rl_isearch_init (direction); | ||||
| 
 | ||||
|   rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), -1); | ||||
|   rl_display_search (cxt->search_string, cxt->sflags, -1); | ||||
| 
 | ||||
|   /* If we are using the callback interface, all we do is set up here and
 | ||||
|       return.  The key is that we leave RL_STATE_ISEARCH set. */ | ||||
|  |  | |||
|  | @ -121,6 +121,19 @@ _rl_next_macro_key () | |||
| #endif | ||||
| } | ||||
| 
 | ||||
| int | ||||
| _rl_prev_macro_key () | ||||
| { | ||||
|   if (rl_executing_macro == 0) | ||||
|     return (0); | ||||
| 
 | ||||
|   if (executing_macro_index == 0) | ||||
|     return (0); | ||||
| 
 | ||||
|   executing_macro_index--; | ||||
|   return (rl_executing_macro[executing_macro_index]); | ||||
| } | ||||
| 
 | ||||
| /* Save the currently executing macro on a stack of saved macros. */ | ||||
| void | ||||
| _rl_push_executing_macro () | ||||
|  | @ -234,7 +247,7 @@ rl_end_kbd_macro (count, ignore) | |||
|       return -1; | ||||
|     } | ||||
| 
 | ||||
|   current_macro_index -= rl_key_sequence_length - 1; | ||||
|   current_macro_index -= rl_key_sequence_length; | ||||
|   current_macro[current_macro_index] = '\0'; | ||||
| 
 | ||||
|   RL_UNSETSTATE(RL_STATE_MACRODEF); | ||||
|  | @ -263,6 +276,29 @@ rl_call_last_kbd_macro (count, ignore) | |||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| rl_print_last_kbd_macro (count, ignore) | ||||
|      int count, ignore; | ||||
| { | ||||
|   char *m; | ||||
| 
 | ||||
|   if (current_macro == 0) | ||||
|     { | ||||
|       rl_ding (); | ||||
|       return 0; | ||||
|     } | ||||
|   m = _rl_untranslate_macro_value (current_macro, 1); | ||||
|   rl_crlf (); | ||||
|   printf ("%s", m); | ||||
|   fflush (stdout); | ||||
|   rl_crlf (); | ||||
|   FREE (m); | ||||
|   rl_forced_update_display (); | ||||
|   rl_display_fixed = 1; | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| rl_push_macro_input (macro) | ||||
|      char *macro; | ||||
|  |  | |||
|  | @ -64,6 +64,9 @@ int rl_byte_oriented = 0; | |||
| int rl_byte_oriented = 1; | ||||
| #endif | ||||
| 
 | ||||
| /* Ditto */ | ||||
| int _rl_utf8locale = 0; | ||||
| 
 | ||||
| /* **************************************************************** */ | ||||
| /*								    */ | ||||
| /*		Multibyte Character Utility Functions		    */ | ||||
|  | @ -119,7 +122,7 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero) | |||
| 	  point += tmp; | ||||
| 	  if (find_non_zero) | ||||
| 	    { | ||||
| 	      if (wcwidth (wc) == 0) | ||||
| 	      if (WCWIDTH (wc) == 0) | ||||
| 		continue; | ||||
| 	      else | ||||
| 		count--; | ||||
|  | @ -132,7 +135,7 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero) | |||
|   if (find_non_zero) | ||||
|     { | ||||
|       tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps); | ||||
|       while (MB_NULLWCH (tmp) == 0 && MB_INVALIDCH (tmp) == 0 && wcwidth (wc) == 0) | ||||
|       while (MB_NULLWCH (tmp) == 0 && MB_INVALIDCH (tmp) == 0 && WCWIDTH (wc) == 0) | ||||
| 	{ | ||||
| 	  point += tmp; | ||||
| 	  tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps); | ||||
|  | @ -184,7 +187,7 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero) | |||
| 	{ | ||||
| 	  if (find_non_zero) | ||||
| 	    { | ||||
| 	      if (wcwidth (wc) != 0) | ||||
| 	      if (WCWIDTH (wc) != 0) | ||||
| 		prev = point; | ||||
| 	    } | ||||
| 	  else | ||||
|  | @ -263,7 +266,7 @@ _rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2) | |||
|    if point is invalied (point < 0 || more than string length), | ||||
|    it returns -1 */ | ||||
| int | ||||
| _rl_adjust_point(string, point, ps) | ||||
| _rl_adjust_point (string, point, ps) | ||||
|      char *string; | ||||
|      int point; | ||||
|      mbstate_t *ps; | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| /* misc.c -- miscellaneous bindable readline functions. */ | ||||
| 
 | ||||
| /* Copyright (C) 1987-2009 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 1987-2012 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file is part of the GNU Readline Library (Readline), a library | ||||
|    for reading lines of text with interactive input and history editing.       | ||||
|  | @ -56,6 +56,8 @@ | |||
| static int rl_digit_loop PARAMS((void)); | ||||
| static void _rl_history_set_point PARAMS((void)); | ||||
| 
 | ||||
| extern int history_offset; | ||||
| 
 | ||||
| /* Forward declarations used in this file */ | ||||
| void _rl_free_history_entry PARAMS((HIST_ENTRY *)); | ||||
| 
 | ||||
|  | @ -483,6 +485,37 @@ _rl_revert_all_lines () | |||
|   xfree (lbuf); | ||||
| }   | ||||
| 
 | ||||
| /* Free the history list, including private readline data and take care
 | ||||
|    of pointer aliases to history data.  Resets rl_undo_list if it points | ||||
|    to an UNDO_LIST * saved as some history entry's data member.  This | ||||
|    should not be called while editing is active. */ | ||||
| void | ||||
| rl_clear_history () | ||||
| { | ||||
|   HIST_ENTRY **hlist, *hent; | ||||
|   register int i; | ||||
|   UNDO_LIST *ul, *saved_undo_list; | ||||
| 
 | ||||
|   saved_undo_list = rl_undo_list; | ||||
|   hlist = history_list ();		/* direct pointer, not copy */ | ||||
| 
 | ||||
|   for (i = 0; i < history_length; i++) | ||||
|     { | ||||
|       hent = hlist[i]; | ||||
|       if (ul = (UNDO_LIST *)hent->data) | ||||
| 	{ | ||||
| 	  if (ul == saved_undo_list) | ||||
| 	    saved_undo_list = 0; | ||||
| 	  _rl_free_undo_list (ul); | ||||
| 	  hent->data = 0; | ||||
| 	} | ||||
|       _rl_free_history_entry (hent); | ||||
|     } | ||||
| 
 | ||||
|   history_offset = history_length = 0; | ||||
|   rl_undo_list = saved_undo_list;	/* should be NULL */ | ||||
| } | ||||
| 
 | ||||
| /* **************************************************************** */ | ||||
| /*								    */ | ||||
| /*			History Commands			    */ | ||||
|  | @ -623,6 +656,10 @@ rl_emacs_editing_mode (count, key) | |||
|   rl_editing_mode = emacs_mode; | ||||
|   _rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */ | ||||
|   _rl_keymap = emacs_standard_keymap; | ||||
| 
 | ||||
|   if (_rl_show_mode_in_prompt) | ||||
|     _rl_reset_prompt (); | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -43,6 +43,10 @@ | |||
| #  include <locale.h> | ||||
| #endif | ||||
| 
 | ||||
| #if defined (HAVE_LANGINFO_CODESET) | ||||
| #  include <langinfo.h> | ||||
| #endif | ||||
| 
 | ||||
| #include <ctype.h> | ||||
| 
 | ||||
| #include "rldefs.h" | ||||
|  | @ -50,6 +54,8 @@ | |||
| #include "rlshell.h" | ||||
| #include "rlprivate.h" | ||||
| 
 | ||||
| static int utf8locale PARAMS((char *)); | ||||
| 
 | ||||
| #if !defined (HAVE_SETLOCALE)     | ||||
| /* A list of legal values for the LANG or LC_CTYPE environment variables.
 | ||||
|    If a locale name in this list is the value for the LC_ALL, LC_CTYPE, | ||||
|  | @ -72,9 +78,10 @@ static char *legal_lang_values[] = | |||
| }; | ||||
| 
 | ||||
| static char *normalize_codeset PARAMS((char *)); | ||||
| static char *find_codeset PARAMS((char *, size_t *)); | ||||
| #endif /* !HAVE_SETLOCALE */ | ||||
| 
 | ||||
| static char *find_codeset PARAMS((char *, size_t *)); | ||||
| 
 | ||||
| static char *_rl_get_locale_var PARAMS((const char *)); | ||||
| 
 | ||||
| static char * | ||||
|  | @ -91,7 +98,26 @@ _rl_get_locale_var (v) | |||
| 
 | ||||
|   return lspec; | ||||
| } | ||||
|    | ||||
| 
 | ||||
| static int | ||||
| utf8locale (lspec) | ||||
|      char *lspec; | ||||
| { | ||||
|   char *cp; | ||||
|   size_t len; | ||||
| 
 | ||||
| #if HAVE_LANGINFO_CODESET | ||||
|   cp = nl_langinfo (CODESET); | ||||
|   return (STREQ (cp, "UTF-8") || STREQ (cp, "utf8")); | ||||
| #else | ||||
|   cp = find_codeset (lspec, &len); | ||||
| 
 | ||||
|   if (cp == 0 || len < 4 || len > 5) | ||||
|     return 0; | ||||
|   return ((len == 5) ? strncmp (cp, "UTF-8", len) == 0 : strncmp (cp, "utf8", 4) == 0); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| /* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value
 | ||||
|    to decide the defaults for 8-bit character input and output.  Returns | ||||
|    1 if we set eight-bit mode. */ | ||||
|  | @ -116,6 +142,9 @@ _rl_init_eightbit () | |||
|     lspec = ""; | ||||
|   t = setlocale (LC_CTYPE, lspec); | ||||
| 
 | ||||
|   if (t && *t) | ||||
|     _rl_utf8locale = utf8locale (t); | ||||
| 
 | ||||
|   if (t && *t && (t[0] != 'C' || t[1]) && (STREQ (t, "POSIX") == 0)) | ||||
|     { | ||||
|       _rl_meta_flag = 1; | ||||
|  | @ -197,6 +226,7 @@ normalize_codeset (codeset) | |||
| 
 | ||||
|   return retval; | ||||
| } | ||||
| #endif /* !HAVE_SETLOCALE */ | ||||
| 
 | ||||
| /* Isolate codeset portion of locale specification. */ | ||||
| static char * | ||||
|  | @ -249,4 +279,3 @@ find_codeset (name, lenp) | |||
| 
 | ||||
|   return result; | ||||
| } | ||||
| #endif /* !HAVE_SETLOCALE */ | ||||
|  |  | |||
							
								
								
									
										440
									
								
								lib/readline/parse-colors.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										440
									
								
								lib/readline/parse-colors.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,440 @@ | |||
| /* `dir', `vdir' and `ls' directory listing programs for GNU.
 | ||||
| 
 | ||||
|    Modified by Chet Ramey for Readline. | ||||
| 
 | ||||
|    Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012 Free Software Foundation, | ||||
|    Inc. | ||||
| 
 | ||||
|    This program 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 3 of the License, or | ||||
|    (at your option) any later version. | ||||
| 
 | ||||
|    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */
 | ||||
| 
 | ||||
| /* Written by Richard Stallman and David MacKenzie.  */ | ||||
| 
 | ||||
| /* Color support by Peter Anvin <Peter.Anvin@linux.org> and Dennis
 | ||||
|    Flaherty <dennisf@denix.elk.miles.com> based on original patches by | ||||
|    Greg Lee <lee@uhunix.uhcc.hawaii.edu>.  */ | ||||
| 
 | ||||
| #define READLINE_LIBRARY | ||||
| 
 | ||||
| #if defined (HAVE_CONFIG_H) | ||||
| #  include <config.h> | ||||
| #endif | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| // strdup() / strcpy()
 | ||||
| #if defined (HAVE_STRING_H) | ||||
| #  include <string.h> | ||||
| #else /* !HAVE_STRING_H */ | ||||
| #  include <strings.h> | ||||
| #endif /* !HAVE_STRING_H */ | ||||
| 
 | ||||
| // abort()
 | ||||
| #if defined (HAVE_STDLIB_H) | ||||
| #  include <stdlib.h> | ||||
| #else | ||||
| #  include "ansi_stdlib.h" | ||||
| #endif /* HAVE_STDLIB_H */ | ||||
| 
 | ||||
| #include "rldefs.h"	// STREQ, savestring | ||||
| #include "readline.h" | ||||
| #include "rlprivate.h" | ||||
| #include "rlshell.h" | ||||
| #include "xmalloc.h" | ||||
| 
 | ||||
| #include "colors.h" | ||||
| #include "parse-colors.h" | ||||
| 
 | ||||
| #if defined (COLOR_SUPPORT) | ||||
| 
 | ||||
| static bool get_funky_string (char **dest, const char **src, bool equals_end, size_t *output_count); | ||||
| 
 | ||||
| struct bin_str _rl_color_indicator[] = | ||||
|   { | ||||
|     { LEN_STR_PAIR ("\033[") },         //  lc: Left of color sequence
 | ||||
|     { LEN_STR_PAIR ("m") },             //  rc: Right of color sequence
 | ||||
|     { 0, NULL },                        //  ec: End color (replaces lc+no+rc)
 | ||||
|     { LEN_STR_PAIR ("0") },             //  rs: Reset to ordinary colors
 | ||||
|     { 0, NULL },                        //  no: Normal
 | ||||
|     { 0, NULL },                        //  fi: File: default
 | ||||
|     { LEN_STR_PAIR ("01;34") },         //  di: Directory: bright blue
 | ||||
|     { LEN_STR_PAIR ("01;36") },         //  ln: Symlink: bright cyan
 | ||||
|     { LEN_STR_PAIR ("33") },            //  pi: Pipe: yellow/brown
 | ||||
|     { LEN_STR_PAIR ("01;35") },         //  so: Socket: bright magenta
 | ||||
|     { LEN_STR_PAIR ("01;33") },         //  bd: Block device: bright yellow
 | ||||
|     { LEN_STR_PAIR ("01;33") },         //  cd: Char device: bright yellow
 | ||||
|     { 0, NULL },                        //  mi: Missing file: undefined
 | ||||
|     { 0, NULL },                        //  or: Orphaned symlink: undefined
 | ||||
|     { LEN_STR_PAIR ("01;32") },         //  ex: Executable: bright green
 | ||||
|     { LEN_STR_PAIR ("01;35") },         //  do: Door: bright magenta
 | ||||
|     { LEN_STR_PAIR ("37;41") },         //  su: setuid: white on red
 | ||||
|     { LEN_STR_PAIR ("30;43") },         //  sg: setgid: black on yellow
 | ||||
|     { LEN_STR_PAIR ("37;44") },         //  st: sticky: black on blue
 | ||||
|     { LEN_STR_PAIR ("34;42") },         //  ow: other-writable: blue on green
 | ||||
|     { LEN_STR_PAIR ("30;42") },         //  tw: ow w/ sticky: black on green
 | ||||
|     { LEN_STR_PAIR ("30;41") },         //  ca: black on red
 | ||||
|     { 0, NULL },                        //  mh: disabled by default
 | ||||
|     { LEN_STR_PAIR ("\033[K") },        //  cl: clear to end of line
 | ||||
|   }; | ||||
| 
 | ||||
| /* Parse a string as part of the LS_COLORS variable; this may involve
 | ||||
|    decoding all kinds of escape characters.  If equals_end is set an | ||||
|    unescaped equal sign ends the string, otherwise only a : or \0 | ||||
|    does.  Set *OUTPUT_COUNT to the number of bytes output.  Return | ||||
|    true if successful. | ||||
| 
 | ||||
|    The resulting string is *not* null-terminated, but may contain | ||||
|    embedded nulls. | ||||
| 
 | ||||
|    Note that both dest and src are char **; on return they point to | ||||
|    the first free byte after the array and the character that ended | ||||
|    the input string, respectively.  */ | ||||
| 
 | ||||
| static bool | ||||
| get_funky_string (char **dest, const char **src, bool equals_end, size_t *output_count) { | ||||
|   char num;			/* For numerical codes */ | ||||
|   size_t count;			/* Something to count with */ | ||||
|   enum { | ||||
|     ST_GND, ST_BACKSLASH, ST_OCTAL, ST_HEX, ST_CARET, ST_END, ST_ERROR | ||||
|   } state; | ||||
|   const char *p; | ||||
|   char *q; | ||||
| 
 | ||||
|   p = *src;			/* We don't want to double-indirect */ | ||||
|   q = *dest;			/* the whole darn time.  */ | ||||
| 
 | ||||
|   count = 0;			/* No characters counted in yet.  */ | ||||
|   num = 0; | ||||
| 
 | ||||
|   state = ST_GND;		/* Start in ground state.  */ | ||||
|   while (state < ST_END) | ||||
|     { | ||||
|       switch (state) | ||||
|         { | ||||
|         case ST_GND:		/* Ground state (no escapes) */ | ||||
|           switch (*p) | ||||
|             { | ||||
|             case ':': | ||||
|             case '\0': | ||||
|               state = ST_END;	/* End of string */ | ||||
|               break; | ||||
|             case '\\': | ||||
|               state = ST_BACKSLASH; /* Backslash scape sequence */ | ||||
|               ++p; | ||||
|               break; | ||||
|             case '^': | ||||
|               state = ST_CARET; /* Caret escape */ | ||||
|               ++p; | ||||
|               break; | ||||
|             case '=': | ||||
|               if (equals_end) | ||||
|                 { | ||||
|                   state = ST_END; /* End */ | ||||
|                   break; | ||||
|                 } | ||||
|               /* else fall through */ | ||||
|             default: | ||||
|               *(q++) = *(p++); | ||||
|               ++count; | ||||
|               break; | ||||
|             } | ||||
|           break; | ||||
| 
 | ||||
|         case ST_BACKSLASH:	/* Backslash escaped character */ | ||||
|           switch (*p) | ||||
|             { | ||||
|             case '0': | ||||
|             case '1': | ||||
|             case '2': | ||||
|             case '3': | ||||
|             case '4': | ||||
|             case '5': | ||||
|             case '6': | ||||
|             case '7': | ||||
|               state = ST_OCTAL;	/* Octal sequence */ | ||||
|               num = *p - '0'; | ||||
|               break; | ||||
|             case 'x': | ||||
|             case 'X': | ||||
|               state = ST_HEX;	/* Hex sequence */ | ||||
|               num = 0; | ||||
|               break; | ||||
|             case 'a':		/* Bell */ | ||||
|               num = '\a'; | ||||
|               break; | ||||
|             case 'b':		/* Backspace */ | ||||
|               num = '\b'; | ||||
|               break; | ||||
|             case 'e':		/* Escape */ | ||||
|               num = 27; | ||||
|               break; | ||||
|             case 'f':		/* Form feed */ | ||||
|               num = '\f'; | ||||
|               break; | ||||
|             case 'n':		/* Newline */ | ||||
|               num = '\n'; | ||||
|               break; | ||||
|             case 'r':		/* Carriage return */ | ||||
|               num = '\r'; | ||||
|               break; | ||||
|             case 't':		/* Tab */ | ||||
|               num = '\t'; | ||||
|               break; | ||||
|             case 'v':		/* Vtab */ | ||||
|               num = '\v'; | ||||
|               break; | ||||
|             case '?':		/* Delete */ | ||||
|               num = 127; | ||||
|               break; | ||||
|             case '_':		/* Space */ | ||||
|               num = ' '; | ||||
|               break; | ||||
|             case '\0':		/* End of string */ | ||||
|               state = ST_ERROR;	/* Error! */ | ||||
|               break; | ||||
|             default:		/* Escaped character like \ ^ : = */ | ||||
|               num = *p; | ||||
|               break; | ||||
|             } | ||||
|           if (state == ST_BACKSLASH) | ||||
|             { | ||||
|               *(q++) = num; | ||||
|               ++count; | ||||
|               state = ST_GND; | ||||
|             } | ||||
|           ++p; | ||||
|           break; | ||||
| 
 | ||||
|         case ST_OCTAL:		/* Octal sequence */ | ||||
|           if (*p < '0' || *p > '7') | ||||
|             { | ||||
|               *(q++) = num; | ||||
|               ++count; | ||||
|               state = ST_GND; | ||||
|             } | ||||
|           else | ||||
|             num = (num << 3) + (*(p++) - '0'); | ||||
|           break; | ||||
| 
 | ||||
|         case ST_HEX:		/* Hex sequence */ | ||||
|           switch (*p) | ||||
|             { | ||||
|             case '0': | ||||
|             case '1': | ||||
|             case '2': | ||||
|             case '3': | ||||
|             case '4': | ||||
|             case '5': | ||||
|             case '6': | ||||
|             case '7': | ||||
|             case '8': | ||||
|             case '9': | ||||
|               num = (num << 4) + (*(p++) - '0'); | ||||
|               break; | ||||
|             case 'a': | ||||
|             case 'b': | ||||
|             case 'c': | ||||
|             case 'd': | ||||
|             case 'e': | ||||
|             case 'f': | ||||
|               num = (num << 4) + (*(p++) - 'a') + 10; | ||||
|               break; | ||||
|             case 'A': | ||||
|             case 'B': | ||||
|             case 'C': | ||||
|             case 'D': | ||||
|             case 'E': | ||||
|             case 'F': | ||||
|               num = (num << 4) + (*(p++) - 'A') + 10; | ||||
|               break; | ||||
|             default: | ||||
|               *(q++) = num; | ||||
|               ++count; | ||||
|               state = ST_GND; | ||||
|               break; | ||||
|             } | ||||
|           break; | ||||
| 
 | ||||
|         case ST_CARET:		/* Caret escape */ | ||||
|           state = ST_GND;	/* Should be the next state... */ | ||||
|           if (*p >= '@' && *p <= '~') | ||||
|             { | ||||
|               *(q++) = *(p++) & 037; | ||||
|               ++count; | ||||
|             } | ||||
|           else if (*p == '?') | ||||
|             { | ||||
|               *(q++) = 127; | ||||
|               ++count; | ||||
|             } | ||||
|           else | ||||
|             state = ST_ERROR; | ||||
|           break; | ||||
| 
 | ||||
|         default: | ||||
| 	  /* should we ? */ | ||||
|           /* abort ();	no, we should not */ | ||||
|           state = ST_ERROR; | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   *dest = q; | ||||
|   *src = p; | ||||
|   *output_count = count; | ||||
| 
 | ||||
|   return state != ST_ERROR; | ||||
| } | ||||
| #endif /* COLOR_SUPPORT */ | ||||
| 
 | ||||
| void _rl_parse_colors() | ||||
| { | ||||
| #if defined (COLOR_SUPPORT) | ||||
|   const char *p;		/* Pointer to character being parsed */ | ||||
|   char *buf;			/* color_buf buffer pointer */ | ||||
|   int state;			/* State of parser */ | ||||
|   int ind_no;			/* Indicator number */ | ||||
|   char label[3];		/* Indicator label */ | ||||
|   COLOR_EXT_TYPE *ext;		/* Extension we are working on */ | ||||
| 
 | ||||
|   p = sh_get_env_value ("LS_COLORS"); | ||||
|   if (p == 0 || *p == '\0') | ||||
|     { | ||||
|       _rl_color_ext_list = NULL; | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|   ext = NULL; | ||||
|   strcpy (label, "??"); | ||||
| 
 | ||||
|   /* This is an overly conservative estimate, but any possible
 | ||||
|      LS_COLORS string will *not* generate a color_buf longer than | ||||
|      itself, so it is a safe way of allocating a buffer in | ||||
|      advance.  */ | ||||
|   buf = color_buf = savestring (p); | ||||
| 
 | ||||
|   state = 1; | ||||
|   while (state > 0) | ||||
|     { | ||||
|       switch (state) | ||||
|         { | ||||
|         case 1:		/* First label character */ | ||||
|           switch (*p) | ||||
|             { | ||||
|             case ':': | ||||
|               ++p; | ||||
|               break; | ||||
| 
 | ||||
|             case '*': | ||||
|               /* Allocate new extension block and add to head of
 | ||||
|                  linked list (this way a later definition will | ||||
|                  override an earlier one, which can be useful for | ||||
|                  having terminal-specific defs override global).  */ | ||||
| 
 | ||||
|               ext = (COLOR_EXT_TYPE *)xmalloc (sizeof *ext); | ||||
|               ext->next = _rl_color_ext_list; | ||||
|               _rl_color_ext_list = ext; | ||||
| 
 | ||||
|               ++p; | ||||
|               ext->ext.string = buf; | ||||
| 
 | ||||
|               state = (get_funky_string (&buf, &p, true, &ext->ext.len) | ||||
|                        ? 4 : -1); | ||||
|               break; | ||||
| 
 | ||||
|             case '\0': | ||||
|               state = 0;	/* Done! */ | ||||
|               break; | ||||
| 
 | ||||
|             default:	/* Assume it is file type label */ | ||||
|               label[0] = *(p++); | ||||
|               state = 2; | ||||
|               break; | ||||
|             } | ||||
|           break; | ||||
| 
 | ||||
|         case 2:		/* Second label character */ | ||||
|           if (*p) | ||||
|             { | ||||
|               label[1] = *(p++); | ||||
|               state = 3; | ||||
|             } | ||||
|           else | ||||
|             state = -1;	/* Error */ | ||||
|           break; | ||||
| 
 | ||||
|         case 3:		/* Equal sign after indicator label */ | ||||
|           state = -1;	/* Assume failure...  */ | ||||
|           if (*(p++) == '=')/* It *should* be...  */ | ||||
|             { | ||||
|               for (ind_no = 0; indicator_name[ind_no] != NULL; ++ind_no) | ||||
|                 { | ||||
|                   if (STREQ (label, indicator_name[ind_no])) | ||||
|                     { | ||||
|                       _rl_color_indicator[ind_no].string = buf; | ||||
|                       state = (get_funky_string (&buf, &p, false, | ||||
|                                                  &_rl_color_indicator[ind_no].len) | ||||
|                                ? 1 : -1); | ||||
|                       break; | ||||
|                     } | ||||
|                 } | ||||
|               if (state == -1) | ||||
| 		{ | ||||
|                   _rl_errmsg ("LS_COLORS: unrecognized prefix: %s", label); | ||||
|                   /* recover from an unrecognized prefix */ | ||||
|                   while (p && *p && *p != ':') | ||||
| 		    p++; | ||||
| 		  if (p && *p == ':') | ||||
| 		    state = 1; | ||||
| 		  else if (p && *p == 0) | ||||
| 		    state = 0; | ||||
| 		} | ||||
|             } | ||||
|           break; | ||||
| 
 | ||||
|         case 4:		/* Equal sign after *.ext */ | ||||
|           if (*(p++) == '=') | ||||
|             { | ||||
|               ext->seq.string = buf; | ||||
|               state = (get_funky_string (&buf, &p, false, &ext->seq.len) | ||||
|                        ? 1 : -1); | ||||
|             } | ||||
|           else | ||||
|             state = -1; | ||||
|           /* XXX - recover here as with an unrecognized prefix? */ | ||||
|           if (state == -1 && ext->ext.string) | ||||
| 	    _rl_errmsg ("LS_COLORS: syntax error: %s", ext->ext.string); | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   if (state < 0) | ||||
|     { | ||||
|       COLOR_EXT_TYPE *e; | ||||
|       COLOR_EXT_TYPE *e2; | ||||
| 
 | ||||
|       _rl_errmsg ("unparsable value for LS_COLORS environment variable"); | ||||
|       free (color_buf); | ||||
|       for (e = _rl_color_ext_list; e != NULL; /* empty */) | ||||
|         { | ||||
|           e2 = e; | ||||
|           e = e->next; | ||||
|           free (e2); | ||||
|         } | ||||
|       _rl_color_ext_list = NULL; | ||||
|       _rl_colored_stats = 0;	/* can't have colored stats without colors */ | ||||
|     } | ||||
| #else /* !COLOR_SUPPORT */ | ||||
|   ; | ||||
| #endif /* !COLOR_SUPPORT */ | ||||
| } | ||||
							
								
								
									
										46
									
								
								lib/readline/parse-colors.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								lib/readline/parse-colors.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,46 @@ | |||
| /* `dir', `vdir' and `ls' directory listing programs for GNU.
 | ||||
| 
 | ||||
|    Modified by Chet Ramey for Readline. | ||||
| 
 | ||||
|    Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012 Free Software Foundation, | ||||
|    Inc. | ||||
| 
 | ||||
|    This program 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 3 of the License, or | ||||
|    (at your option) any later version. | ||||
| 
 | ||||
|    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */
 | ||||
| 
 | ||||
| /* Written by Richard Stallman and David MacKenzie.  */ | ||||
| 
 | ||||
| /* Color support by Peter Anvin <Peter.Anvin@linux.org> and Dennis
 | ||||
|    Flaherty <dennisf@denix.elk.miles.com> based on original patches by | ||||
|    Greg Lee <lee@uhunix.uhcc.hawaii.edu>.  */ | ||||
| 
 | ||||
| #ifndef _PARSE_COLORS_H_ | ||||
| #define _PARSE_COLORS_H_ | ||||
| 
 | ||||
| #include "readline.h" | ||||
| 
 | ||||
| #define LEN_STR_PAIR(s) sizeof (s) - 1, s | ||||
| 
 | ||||
| void _rl_parse_colors (void); | ||||
| 
 | ||||
| static const char *const indicator_name[]= | ||||
|   { | ||||
|     "lc", "rc", "ec", "rs", "no", "fi", "di", "ln", "pi", "so", | ||||
|     "bd", "cd", "mi", "or", "ex", "do", "su", "sg", "st", | ||||
|     "ow", "tw", "ca", "mh", "cl", NULL | ||||
|   }; | ||||
| 
 | ||||
| /* Buffer for color sequences */ | ||||
| static char *color_buf; | ||||
| 
 | ||||
| #endif /* !_PARSE_COLORS_H_ */ | ||||
|  | @ -1,6 +1,6 @@ | |||
| /* posixdir.h -- Posix directory reading includes and defines. */ | ||||
| 
 | ||||
| /* Copyright (C) 1987,1991 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 1987,1991,2012 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file is part of GNU Bash, the Bourne Again SHell. | ||||
| 
 | ||||
|  | @ -46,16 +46,26 @@ | |||
| #  define D_NAMLEN(d)   ((d)->d_namlen) | ||||
| #endif /* !HAVE_DIRENT_H */ | ||||
| 
 | ||||
| /* The bash code fairly consistenly uses d_fileno; make sure it's available */ | ||||
| #if defined (HAVE_STRUCT_DIRENT_D_INO) && !defined (HAVE_STRUCT_DIRENT_D_FILENO) | ||||
| #  define d_fileno d_ino | ||||
| #endif | ||||
| 
 | ||||
| #if defined (_POSIX_SOURCE) && (!defined (HAVE_STRUCT_DIRENT_D_INO) || defined (BROKEN_DIRENT_D_INO)) | ||||
| /* Posix does not require that the d_ino field be present, and some
 | ||||
|    systems do not provide it. */ | ||||
| #if !defined (HAVE_STRUCT_DIRENT_D_INO) || defined (BROKEN_DIRENT_D_INO) | ||||
| #  define REAL_DIR_ENTRY(dp) 1 | ||||
| #else | ||||
| #  define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) | ||||
| #endif /* _POSIX_SOURCE */ | ||||
| 
 | ||||
| #if defined (HAVE_STRUCT_DIRENT_D_INO) && !defined (BROKEN_DIRENT_D_INO) | ||||
| #  define D_INO_AVAILABLE | ||||
| #endif | ||||
| 
 | ||||
| /* Signal the rest of the code that it can safely use dirent.d_fileno */ | ||||
| #if defined (D_INO_AVAILABLE) || defined (HAVE_STRUCT_DIRENT_D_FILENO) | ||||
| #  define D_FILENO_AVAILABLE 1 | ||||
| #endif | ||||
| 
 | ||||
| #endif /* !_POSIXDIR_H_ */ | ||||
|  |  | |||
|  | @ -30,11 +30,13 @@ | |||
| #  if !defined (__OPENNT) | ||||
| #    undef setjmp | ||||
| #    define setjmp(x)	sigsetjmp((x), 1) | ||||
| #    define setjmp_nosigs(x)	sigsetjmp((x), 0) | ||||
| #    undef longjmp | ||||
| #    define longjmp(x, n)	siglongjmp((x), (n)) | ||||
| #  endif /* !__OPENNT */ | ||||
| #else | ||||
| #  define procenv_t	jmp_buf | ||||
| #  define setjmp_nosigs	setjmp | ||||
| #endif | ||||
| 
 | ||||
| #endif /* _POSIXJMP_H_ */ | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| /* readline.c -- a general facility for reading lines of input
 | ||||
|    with emacs style editing and completion. */ | ||||
| 
 | ||||
| /* Copyright (C) 1987-2009 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 1987-2013 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file is part of the GNU Readline Library (Readline), a library | ||||
|    for reading lines of text with interactive input and history editing.       | ||||
|  | @ -82,6 +82,11 @@ extern int errno; | |||
| 
 | ||||
| extern void _rl_free_history_entry PARAMS((HIST_ENTRY *)); | ||||
| 
 | ||||
| #if defined (COLOR_SUPPORT) | ||||
| extern void _rl_parse_colors PARAMS((void));		/* XXX */ | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| /* Forward declarations used in this file. */ | ||||
| static char *readline_internal PARAMS((void)); | ||||
| static void readline_initialize_everything PARAMS((void)); | ||||
|  | @ -112,7 +117,6 @@ int rl_gnu_readline_p = 1; | |||
|    By default, it is the standard emacs keymap. */ | ||||
| Keymap _rl_keymap = emacs_standard_keymap; | ||||
| 
 | ||||
| 
 | ||||
| /* The current style of editing. */ | ||||
| int rl_editing_mode = emacs_mode; | ||||
| 
 | ||||
|  | @ -238,13 +242,32 @@ int rl_erase_empty_line = 0; | |||
|    character bound to accept-line. */ | ||||
| int rl_num_chars_to_read; | ||||
| 
 | ||||
| /* Line buffer and maintenence. */ | ||||
| /* Line buffer and maintenance. */ | ||||
| char *rl_line_buffer = (char *)NULL; | ||||
| int rl_line_buffer_len = 0; | ||||
| 
 | ||||
| /* Key sequence `contexts' */ | ||||
| _rl_keyseq_cxt *_rl_kscxt = 0; | ||||
| 
 | ||||
| int rl_executing_key; | ||||
| char *rl_executing_keyseq = 0; | ||||
| int _rl_executing_keyseq_size = 0; | ||||
| 
 | ||||
| /* Timeout (specified in milliseconds) when reading characters making up an
 | ||||
|    ambiguous multiple-key sequence */ | ||||
| int _rl_keyseq_timeout = 500; | ||||
| 
 | ||||
| #define RESIZE_KEYSEQ_BUFFER() \ | ||||
|   do \ | ||||
|     { \ | ||||
|       if (rl_key_sequence_length + 2 >= _rl_executing_keyseq_size) \ | ||||
| 	{ \ | ||||
| 	  _rl_executing_keyseq_size += 16; \ | ||||
| 	  rl_executing_keyseq = xrealloc (rl_executing_keyseq, _rl_executing_keyseq_size); \ | ||||
| 	} \ | ||||
|     } \ | ||||
|   while (0); | ||||
|          | ||||
| /* Forward declarations used by the display, termcap, and history code. */ | ||||
| 
 | ||||
| /* **************************************************************** */ | ||||
|  | @ -279,6 +302,10 @@ int _rl_revert_all_at_newline = 0; | |||
|    characters corresponding to keyboard-generated signals. */ | ||||
| int _rl_echo_control_chars = 1; | ||||
| 
 | ||||
| /* Non-zero means to prefix the displayed prompt with a character indicating
 | ||||
|    the editing mode: @ for emacs, : for vi-command, + for vi-insert. */ | ||||
| int _rl_show_mode_in_prompt = 0; | ||||
| 
 | ||||
| /* **************************************************************** */ | ||||
| /*								    */ | ||||
| /*			Top Level Functions			    */ | ||||
|  | @ -352,6 +379,11 @@ readline (prompt) | |||
|     RL_SETSTATE (RL_STATE_CALLBACK); | ||||
| #endif | ||||
| 
 | ||||
| #if HAVE_DECL_AUDIT_TTY && defined (ENABLE_TTY_AUDIT_SUPPORT) | ||||
|   if (value) | ||||
|     _rl_audit_tty (value); | ||||
| #endif | ||||
| 
 | ||||
|   return (value); | ||||
| } | ||||
| 
 | ||||
|  | @ -369,9 +401,19 @@ readline_internal_setup () | |||
|   _rl_in_stream = rl_instream; | ||||
|   _rl_out_stream = rl_outstream; | ||||
| 
 | ||||
|   /* Enable the meta key only for the duration of readline(), if this
 | ||||
|      terminal has one and the terminal has been initialized */ | ||||
|   if (_rl_enable_meta & RL_ISSTATE (RL_STATE_TERMPREPPED)) | ||||
|     _rl_enable_meta_key (); | ||||
| 
 | ||||
|   if (rl_startup_hook) | ||||
|     (*rl_startup_hook) (); | ||||
| 
 | ||||
| #if defined (VI_MODE) | ||||
|   if (rl_editing_mode == vi_mode) | ||||
|     rl_vi_insertion_mode (1, 'i');	/* don't want to reset last */ | ||||
| #endif /* VI_MODE */ | ||||
| 
 | ||||
|   /* If we're not echoing, we still want to at least print a prompt, because
 | ||||
|      rl_redisplay will not do it for us.  If the calling application has a | ||||
|      custom redisplay function, though, let that function handle it. */ | ||||
|  | @ -394,11 +436,6 @@ readline_internal_setup () | |||
|       (*rl_redisplay_function) (); | ||||
|     } | ||||
| 
 | ||||
| #if defined (VI_MODE) | ||||
|   if (rl_editing_mode == vi_mode) | ||||
|     rl_vi_insert_mode (1, 'i'); | ||||
| #endif /* VI_MODE */ | ||||
| 
 | ||||
|   if (rl_pre_input_hook) | ||||
|     (*rl_pre_input_hook) (); | ||||
| 
 | ||||
|  | @ -437,6 +474,11 @@ readline_internal_teardown (eof) | |||
|   if (rl_undo_list) | ||||
|     rl_free_undo_list (); | ||||
| 
 | ||||
|   /* Disable the meta key, if this terminal has one and we were told to use it.
 | ||||
|      The check whether or not we sent the enable string is in | ||||
|      _rl_disable_meta_key(); the flag is set in _rl_enable_meta_key */ | ||||
|   _rl_disable_meta_key (); | ||||
| 
 | ||||
|   /* Restore normal cursor, if available. */ | ||||
|   _rl_set_insert_mode (RL_IM_INSERT, 0); | ||||
| 
 | ||||
|  | @ -492,7 +534,11 @@ readline_internal_charloop () | |||
| #endif | ||||
|       lk = _rl_last_command_was_kill; | ||||
| 
 | ||||
| #if defined (HAVE_POSIX_SIGSETJMP) | ||||
|       code = sigsetjmp (_rl_top_level, 0); | ||||
| #else | ||||
|       code = setjmp (_rl_top_level); | ||||
| #endif | ||||
| 
 | ||||
|       if (code) | ||||
| 	{ | ||||
|  | @ -511,6 +557,7 @@ readline_internal_charloop () | |||
| 	  /* Then initialize the argument and number of keys read. */ | ||||
| 	  _rl_reset_argument (); | ||||
| 	  rl_key_sequence_length = 0; | ||||
| 	  rl_executing_keyseq[0] = 0; | ||||
| 	} | ||||
| 
 | ||||
|       RL_SETSTATE(RL_STATE_READCMD); | ||||
|  | @ -519,7 +566,8 @@ readline_internal_charloop () | |||
| 
 | ||||
|       /* look at input.c:rl_getc() for the circumstances under which this will
 | ||||
| 	 be returned; punt immediately on read error without converting it to | ||||
| 	 a newline. */ | ||||
| 	 a newline; assume that rl_read_key has already called the signal | ||||
| 	 handler. */ | ||||
|       if (c == READERR) | ||||
| 	{ | ||||
| #if defined (READLINE_CALLBACKS) | ||||
|  | @ -531,7 +579,9 @@ readline_internal_charloop () | |||
| #endif | ||||
| 	} | ||||
| 
 | ||||
|       /* EOF typed to a non-blank line is a <NL>. */ | ||||
|       /* EOF typed to a non-blank line is a <NL>.  If we want to change this,
 | ||||
| 	 to force any existing line to be ignored when read(2) reads EOF, | ||||
| 	 for example, this is the place to change. */ | ||||
|       if (c == EOF && rl_end) | ||||
| 	c = NEWLINE; | ||||
| 
 | ||||
|  | @ -743,9 +793,10 @@ _rl_dispatch_subseq (key, map, got_subseq) | |||
| 	{ | ||||
| 	  if (RL_ISSTATE (RL_STATE_MACRODEF)) | ||||
| 	    _rl_add_macro_char (ESC); | ||||
| 	  RESIZE_KEYSEQ_BUFFER (); | ||||
| 	  rl_executing_keyseq[rl_key_sequence_length++] = ESC; | ||||
| 	  map = FUNCTION_TO_KEYMAP (map, ESC); | ||||
| 	  key = UNMETA (key); | ||||
| 	  rl_key_sequence_length += 2; | ||||
| 	  return (_rl_dispatch (key, map)); | ||||
| 	} | ||||
|       else | ||||
|  | @ -765,13 +816,19 @@ _rl_dispatch_subseq (key, map, got_subseq) | |||
| 	{ | ||||
| 	  /* Special case rl_do_lowercase_version (). */ | ||||
| 	  if (func == rl_do_lowercase_version) | ||||
| 	    /* Should we do anything special if key == ANYOTHERKEY? */ | ||||
| 	    return (_rl_dispatch (_rl_to_lower (key), map)); | ||||
| 
 | ||||
| 	  rl_executing_keymap = map; | ||||
| 	  rl_executing_key = key; | ||||
| 
 | ||||
| 	  RESIZE_KEYSEQ_BUFFER(); | ||||
| 	  rl_executing_keyseq[rl_key_sequence_length++] = key; | ||||
| 	  rl_executing_keyseq[rl_key_sequence_length] = '\0'; | ||||
| 
 | ||||
| 	  rl_dispatching = 1; | ||||
| 	  RL_SETSTATE(RL_STATE_DISPATCHING); | ||||
| 	  (*map[key].function)(rl_numeric_arg * rl_arg_sign, key); | ||||
| 	  r = (*func) (rl_numeric_arg * rl_arg_sign, key); | ||||
| 	  RL_UNSETSTATE(RL_STATE_DISPATCHING); | ||||
| 	  rl_dispatching = 0; | ||||
| 
 | ||||
|  | @ -788,7 +845,10 @@ _rl_dispatch_subseq (key, map, got_subseq) | |||
| 	  /* OK, there's no function bound in this map, but there is a
 | ||||
| 	     shadow function that was overridden when the current keymap | ||||
| 	     was created.  Return -2 to note  that. */ | ||||
| 	  _rl_unget_char  (key); | ||||
| 	  if (RL_ISSTATE (RL_STATE_MACROINPUT)) | ||||
| 	    _rl_prev_macro_key (); | ||||
| 	  else | ||||
| 	    _rl_unget_char  (key); | ||||
| 	  return -2; | ||||
| 	} | ||||
|       else if (got_subseq) | ||||
|  | @ -797,7 +857,10 @@ _rl_dispatch_subseq (key, map, got_subseq) | |||
| 	     have a matching key, nor was one overridden.  This means | ||||
| 	     we need to back up the recursion chain and find the last | ||||
| 	     subsequence that is bound to a function. */ | ||||
| 	  _rl_unget_char (key); | ||||
| 	  if (RL_ISSTATE (RL_STATE_MACROINPUT)) | ||||
| 	    _rl_prev_macro_key (); | ||||
| 	  else | ||||
| 	    _rl_unget_char (key); | ||||
| 	  return -1; | ||||
| 	} | ||||
|       else | ||||
|  | @ -820,13 +883,17 @@ _rl_dispatch_subseq (key, map, got_subseq) | |||
| 	     check whether there's input in the queue, which there generally | ||||
| 	     will be if an arrow key has been pressed, and, if there's not, | ||||
| 	     just dispatch to (what we assume is) rl_vi_movement_mode right | ||||
| 	     away.  This is essentially an input test with a zero timeout. */ | ||||
| 	     away.  This is essentially an input test with a zero timeout (by | ||||
| 	     default) or a timeout determined by the value of `keyseq-timeout' */ | ||||
| 	  /* _rl_keyseq_timeout specified in milliseconds; _rl_input_queued
 | ||||
| 	     takes microseconds, so multiply by 1000 */ | ||||
| 	  if (rl_editing_mode == vi_mode && key == ESC && map == vi_insertion_keymap | ||||
| 	      && _rl_input_queued (0) == 0) | ||||
| 	      && _rl_input_queued ((_rl_keyseq_timeout > 0) ? _rl_keyseq_timeout*1000 : 0) == 0) | ||||
| 	    return (_rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key))); | ||||
| #endif | ||||
| 
 | ||||
| 	  rl_key_sequence_length++; | ||||
| 	  RESIZE_KEYSEQ_BUFFER (); | ||||
| 	  rl_executing_keyseq[rl_key_sequence_length++] = key; | ||||
| 	  _rl_dispatching_keymap = FUNCTION_TO_KEYMAP (map, key); | ||||
| 
 | ||||
| 	  /* Allocate new context here.  Use linked contexts (linked through
 | ||||
|  | @ -855,6 +922,18 @@ _rl_dispatch_subseq (key, map, got_subseq) | |||
| 	    } | ||||
| #endif | ||||
| 
 | ||||
| 	  /* Tentative inter-character timeout for potential multi-key
 | ||||
| 	     sequences?  If no input within timeout, abort sequence and | ||||
| 	     act as if we got non-matching input. */ | ||||
| 	  /* _rl_keyseq_timeout specified in milliseconds; _rl_input_queued
 | ||||
| 	     takes microseconds, so multiply by 1000 */ | ||||
| 	  if (_rl_keyseq_timeout > 0 && | ||||
| 	  	(RL_ISSTATE (RL_STATE_INPUTPENDING|RL_STATE_MACROINPUT) == 0) && | ||||
| 	  	_rl_pushed_input_available () == 0 && | ||||
| 		_rl_dispatching_keymap[ANYOTHERKEY].function && | ||||
| 		_rl_input_queued (_rl_keyseq_timeout*1000) == 0) | ||||
| 	    return (_rl_subseq_result (-2, map, key, got_subseq)); | ||||
| 
 | ||||
| 	  newkey = _rl_subseq_getchar (key); | ||||
| 	  if (newkey < 0) | ||||
| 	    { | ||||
|  | @ -875,6 +954,7 @@ _rl_dispatch_subseq (key, map, got_subseq) | |||
|     case ISMACR: | ||||
|       if (map[key].function != 0) | ||||
| 	{ | ||||
| 	  rl_executing_keyseq[rl_key_sequence_length] = '\0'; | ||||
| 	  macro = savestring ((char *)map[key].function); | ||||
| 	  _rl_with_macro_input (macro); | ||||
| 	  return 0; | ||||
|  | @ -884,6 +964,7 @@ _rl_dispatch_subseq (key, map, got_subseq) | |||
| #if defined (VI_MODE) | ||||
|   if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap && | ||||
|       key != ANYOTHERKEY && | ||||
|       rl_key_sequence_length == 1 &&	/* XXX */ | ||||
|       _rl_vi_textmod_command (key)) | ||||
|     _rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign); | ||||
| #endif | ||||
|  | @ -935,14 +1016,20 @@ _rl_subseq_result (r, map, key, got_subseq) | |||
|       /* We didn't match (r is probably -1), so return something to
 | ||||
| 	 tell the caller that it should try ANYOTHERKEY for an | ||||
| 	 overridden function. */ | ||||
|       _rl_unget_char (key); | ||||
|       if (RL_ISSTATE (RL_STATE_MACROINPUT)) | ||||
| 	_rl_prev_macro_key (); | ||||
|       else | ||||
| 	_rl_unget_char (key); | ||||
|       _rl_dispatching_keymap = map; | ||||
|       return -2; | ||||
|     } | ||||
|   else if (r && got_subseq) | ||||
|     { | ||||
|       /* OK, back up the chain. */ | ||||
|       _rl_unget_char (key); | ||||
|       if (RL_ISSTATE (RL_STATE_MACROINPUT)) | ||||
| 	_rl_prev_macro_key (); | ||||
|       else | ||||
| 	_rl_unget_char (key); | ||||
|       _rl_dispatching_keymap = map; | ||||
|       return -1; | ||||
|     } | ||||
|  | @ -971,7 +1058,7 @@ rl_initialize () | |||
|       RL_SETSTATE(RL_STATE_INITIALIZED); | ||||
|     } | ||||
| 
 | ||||
|   /* Initalize the current line information. */ | ||||
|   /* Initialize the current line information. */ | ||||
|   _rl_init_line_state (); | ||||
| 
 | ||||
|   /* We aren't done yet.  We haven't even gotten started yet! */ | ||||
|  | @ -1091,14 +1178,19 @@ readline_initialize_everything () | |||
|   /* Try to bind a common arrow key prefix, if not already bound. */ | ||||
|   bind_arrow_keys (); | ||||
| 
 | ||||
|   /* Enable the meta key, if this terminal has one. */ | ||||
|   if (_rl_enable_meta) | ||||
|     _rl_enable_meta_key (); | ||||
| 
 | ||||
|   /* If the completion parser's default word break characters haven't
 | ||||
|      been set yet, then do so now. */ | ||||
|   if (rl_completer_word_break_characters == (char *)NULL) | ||||
|     rl_completer_word_break_characters = (char *)rl_basic_word_break_characters; | ||||
| 
 | ||||
| #if defined (COLOR_SUPPORT) | ||||
|   if (_rl_colored_stats) | ||||
|     _rl_parse_colors (); | ||||
| #endif | ||||
| 
 | ||||
|   rl_executing_keyseq = malloc (_rl_executing_keyseq_size = 16); | ||||
|   if (rl_executing_keyseq) | ||||
|     rl_executing_keyseq[0] = '\0'; | ||||
| } | ||||
| 
 | ||||
| /* If this system allows us to look at the values of the regular
 | ||||
|  | @ -1159,6 +1251,20 @@ bind_arrow_keys_internal (map) | |||
|   rl_bind_keyseq_if_unbound ("\340P", rl_get_next_history); | ||||
|   rl_bind_keyseq_if_unbound ("\340M", rl_forward_char); | ||||
|   rl_bind_keyseq_if_unbound ("\340K", rl_backward_char); | ||||
|   rl_bind_keyseq_if_unbound ("\340G", rl_beg_of_line); | ||||
|   rl_bind_keyseq_if_unbound ("\340O", rl_end_of_line); | ||||
|   rl_bind_keyseq_if_unbound ("\340S", rl_delete); | ||||
|   rl_bind_keyseq_if_unbound ("\340R", rl_overwrite_mode); | ||||
| 
 | ||||
|   /* These may or may not work because of the embedded NUL. */ | ||||
|   rl_bind_keyseq_if_unbound ("\\000H", rl_get_previous_history); | ||||
|   rl_bind_keyseq_if_unbound ("\\000P", rl_get_next_history); | ||||
|   rl_bind_keyseq_if_unbound ("\\000M", rl_forward_char); | ||||
|   rl_bind_keyseq_if_unbound ("\\000K", rl_backward_char); | ||||
|   rl_bind_keyseq_if_unbound ("\\000G", rl_beg_of_line); | ||||
|   rl_bind_keyseq_if_unbound ("\\000O", rl_end_of_line); | ||||
|   rl_bind_keyseq_if_unbound ("\\000S", rl_delete); | ||||
|   rl_bind_keyseq_if_unbound ("\\000R", rl_overwrite_mode); | ||||
| #endif | ||||
| 
 | ||||
|   _rl_keymap = xkeymap; | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| /* Readline.h -- the names of functions callable from within readline. */ | ||||
| 
 | ||||
| /* Copyright (C) 1987-2011 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 1987-2013 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file is part of the GNU Readline Library (Readline), a library | ||||
|    for reading lines of text with interactive input and history editing.       | ||||
|  | @ -39,9 +39,9 @@ extern "C" { | |||
| #endif | ||||
| 
 | ||||
| /* Hex-encoded Readline version number. */ | ||||
| #define RL_READLINE_VERSION	0x0602		/* Readline 6.2 */ | ||||
| #define RL_READLINE_VERSION	0x0603		/* Readline 6.3 */ | ||||
| #define RL_VERSION_MAJOR	6 | ||||
| #define RL_VERSION_MINOR	2 | ||||
| #define RL_VERSION_MINOR	3 | ||||
| 
 | ||||
| /* Readline data structures. */ | ||||
| 
 | ||||
|  | @ -185,6 +185,7 @@ extern int rl_forward_search_history PARAMS((int, int)); | |||
| extern int rl_start_kbd_macro PARAMS((int, int)); | ||||
| extern int rl_end_kbd_macro PARAMS((int, int)); | ||||
| extern int rl_call_last_kbd_macro PARAMS((int, int)); | ||||
| extern int rl_print_last_kbd_macro PARAMS((int, int)); | ||||
| 
 | ||||
| /* Bindable undo commands. */ | ||||
| extern int rl_revert_line PARAMS((int, int)); | ||||
|  | @ -204,6 +205,8 @@ extern int rl_tty_status PARAMS((int, int)); | |||
| /* Bindable commands for incremental and non-incremental history searching. */ | ||||
| extern int rl_history_search_forward PARAMS((int, int)); | ||||
| extern int rl_history_search_backward PARAMS((int, int)); | ||||
| extern int rl_history_substr_search_forward PARAMS((int, int)); | ||||
| extern int rl_history_substr_search_backward PARAMS((int, int)); | ||||
| extern int rl_noninc_forward_search PARAMS((int, int)); | ||||
| extern int rl_noninc_reverse_search PARAMS((int, int)); | ||||
| extern int rl_noninc_forward_search_again PARAMS((int, int)); | ||||
|  | @ -339,6 +342,7 @@ extern Keymap rl_make_bare_keymap PARAMS((void)); | |||
| extern Keymap rl_copy_keymap PARAMS((Keymap)); | ||||
| extern Keymap rl_make_keymap PARAMS((void)); | ||||
| extern void rl_discard_keymap PARAMS((Keymap)); | ||||
| extern void rl_free_keymap PARAMS((Keymap)); | ||||
| 
 | ||||
| extern Keymap rl_get_keymap_by_name PARAMS((const char *)); | ||||
| extern char *rl_get_keymap_name PARAMS((Keymap)); | ||||
|  | @ -436,6 +440,10 @@ extern void rl_echo_signal_char PARAMS((int)); | |||
| 
 | ||||
| extern int rl_set_paren_blink_timeout PARAMS((int)); | ||||
| 
 | ||||
| /* History management functions. */ | ||||
| 
 | ||||
| extern void rl_clear_history PARAMS((void)); | ||||
| 
 | ||||
| /* Undocumented. */ | ||||
| extern int rl_maybe_save_line PARAMS((void)); | ||||
| extern int rl_maybe_unsave_line PARAMS((void)); | ||||
|  | @ -560,6 +568,13 @@ extern rl_hook_func_t *rl_pre_input_hook; | |||
|    awaiting character input, or NULL, for no event handling. */ | ||||
| extern rl_hook_func_t *rl_event_hook; | ||||
| 
 | ||||
| /* The address of a function to call if a read is interrupted by a signal. */ | ||||
| extern rl_hook_func_t *rl_signal_event_hook; | ||||
| 
 | ||||
| /* The address of a function to call if Readline needs to know whether or not
 | ||||
|    there is data available from the current input source. */ | ||||
| extern rl_hook_func_t *rl_input_available_hook; | ||||
| 
 | ||||
| /* The address of the function to call to fetch a character from the current
 | ||||
|    Readline input stream */ | ||||
| extern rl_getc_func_t *rl_getc_function; | ||||
|  | @ -573,6 +588,10 @@ extern rl_voidfunc_t *rl_deprep_term_function; | |||
| extern Keymap rl_executing_keymap; | ||||
| extern Keymap rl_binding_keymap; | ||||
| 
 | ||||
| extern int rl_executing_key; | ||||
| extern char *rl_executing_keyseq; | ||||
| extern int rl_key_sequence_length; | ||||
| 
 | ||||
| /* Display variables. */ | ||||
| /* If non-zero, readline will erase the entire line, including any prompt,
 | ||||
|    if the only thing typed on an otherwise-blank line is something bound to | ||||
|  | @ -603,6 +622,10 @@ extern int rl_catch_signals; | |||
|    to do that. */ | ||||
| extern int rl_catch_sigwinch; | ||||
| 
 | ||||
| /* If non-zero, the readline SIGWINCH handler will modify LINES and
 | ||||
|    COLUMNS in the environment. */ | ||||
| extern int rl_change_environment; | ||||
| 
 | ||||
| /* Completion variables. */ | ||||
| /* Pointer to the generator function for completion_matches ().
 | ||||
|    NULL means to use rl_filename_completion_function (), the default | ||||
|  | @ -686,6 +709,13 @@ extern rl_icppfunc_t *rl_directory_completion_hook; | |||
|    it in bash to see how well it goes. */ | ||||
| extern rl_icppfunc_t *rl_directory_rewrite_hook; | ||||
| 
 | ||||
| /* If non-zero, this is the address of a function for the completer to call
 | ||||
|    before deciding which character to append to a completed name.  It should | ||||
|    modify the directory name passed as an argument if appropriate, and return | ||||
|    non-zero if it modifies the name.  This should not worry about dequoting | ||||
|    the filename; that has already happened by the time it gets here. */ | ||||
| extern rl_icppfunc_t *rl_filename_stat_hook; | ||||
| 
 | ||||
| /* If non-zero, this is the address of a function to call when reading
 | ||||
|    directory entries from the filesystem for completion and comparing | ||||
|    them to the partial word to be completed.  The function should | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| /* rlconf.h -- readline configuration definitions */ | ||||
| 
 | ||||
| /* Copyright (C) 1992-2009 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 1992-2012 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file is part of the GNU Readline Library (Readline), a library | ||||
|    for reading lines of text with interactive input and history editing.       | ||||
|  | @ -28,8 +28,12 @@ | |||
| /* Define this to get an indication of file type when listing completions. */ | ||||
| #define VISIBLE_STATS | ||||
| 
 | ||||
| /* Define this to get support for colors when listing completions and in
 | ||||
|    other places. */ | ||||
| #define COLOR_SUPPORT | ||||
| 
 | ||||
| /* This definition is needed by readline.c, rltty.c, and signals.c. */ | ||||
| /* If on, then readline handles signals in a way that doesn't screw. */ | ||||
| /* If on, then readline handles signals in a way that doesn't suck. */ | ||||
| #define HANDLE_SIGNALS | ||||
| 
 | ||||
| /* Ugly but working hack for binding prefix meta. */ | ||||
|  | @ -58,4 +62,8 @@ | |||
| /* Define this if you want the cursor to indicate insert or overwrite mode. */ | ||||
| /* #define CURSOR_MODE */ | ||||
| 
 | ||||
| /* Define this if you want to enable code that talks to the Linux kernel
 | ||||
|    tty auditing system. */ | ||||
| #define ENABLE_TTY_AUDIT_SUPPORT | ||||
| 
 | ||||
| #endif /* _RLCONF_H_ */ | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
|    for readline.  This should be included after any files that define | ||||
|    system-specific constants like _POSIX_VERSION or USG. */ | ||||
| 
 | ||||
| /* Copyright (C) 1987-2009 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 1987-2011 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file is part of the GNU Readline Library (Readline), a library | ||||
|    for reading lines of text with interactive input and history editing.       | ||||
|  | @ -79,8 +79,8 @@ extern char *strchr (), *strrchr (); | |||
| #define _rl_stricmp strcasecmp | ||||
| #define _rl_strnicmp strncasecmp | ||||
| #else | ||||
| extern int _rl_stricmp PARAMS((char *, char *)); | ||||
| extern int _rl_strnicmp PARAMS((char *, char *, int)); | ||||
| extern int _rl_stricmp PARAMS((const char *, const char *)); | ||||
| extern int _rl_strnicmp PARAMS((const char *, const char *, int)); | ||||
| #endif | ||||
| 
 | ||||
| #if defined (HAVE_STRPBRK) && !defined (HAVE_MULTIBYTE) | ||||
|  | @ -148,6 +148,10 @@ extern char *_rl_strpbrk PARAMS((const char *, const char *)); | |||
| 				    : ((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0)) | ||||
| #endif | ||||
| 
 | ||||
| #if !defined (RL_STRLEN) | ||||
| #  define RL_STRLEN(s) (((s) && (s)[0]) ? ((s)[1] ? ((s)[2] ? strlen(s) : 2) : 1) : 0) | ||||
| #endif | ||||
| 
 | ||||
| #if !defined (FREE) | ||||
| #  define FREE(x)	if (x) free (x) | ||||
| #endif | ||||
|  |  | |||
|  | @ -123,6 +123,15 @@ extern int _rl_walphabetic PARAMS((wchar_t)); | |||
| #define MB_INVALIDCH(x)		((x) == (size_t)-1 || (x) == (size_t)-2) | ||||
| #define MB_NULLWCH(x)		((x) == 0) | ||||
| 
 | ||||
| /* Unicode combining characters range from U+0300 to U+036F */ | ||||
| #define UNICODE_COMBINING_CHAR(x) ((x) >= 768 && (x) <= 879) | ||||
| 
 | ||||
| #if defined (WCWIDTH_BROKEN) | ||||
| #  define WCWIDTH(wc)	((_rl_utf8locale && UNICODE_COMBINING_CHAR(wc)) ? 0 : wcwidth(wc)) | ||||
| #else | ||||
| #  define WCWIDTH(wc)	wcwidth(wc) | ||||
| #endif | ||||
| 
 | ||||
| #else /* !HANDLE_MULTIBYTE */ | ||||
| 
 | ||||
| #undef MB_LEN_MAX | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| /* rlprivate.h -- functions and variables global to the readline library,
 | ||||
| 		  but not intended for use by applications. */ | ||||
| 
 | ||||
| /* Copyright (C) 1999-2010 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 1999-2012 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file is part of the GNU Readline Library (Readline), a library | ||||
|    for reading lines of text with interactive input and history editing.       | ||||
|  | @ -42,6 +42,12 @@ | |||
| 	  if (_rl_caught_signal) _rl_signal_handler (_rl_caught_signal); \ | ||||
| 	} while (0) | ||||
| 
 | ||||
| #define RL_SIG_RECEIVED() (_rl_caught_signal != 0) | ||||
| #define RL_SIGINT_RECEIVED() (_rl_caught_signal == SIGINT) | ||||
| 
 | ||||
| #define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay) | ||||
| #define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc) | ||||
| 
 | ||||
| /*************************************************************************
 | ||||
|  *									 * | ||||
|  * Global structs undocumented in texinfo manual and not in readline.h   * | ||||
|  | @ -86,9 +92,11 @@ typedef struct  __rl_search_context | |||
|   int history_pos; | ||||
|   int direction; | ||||
| 
 | ||||
|   int prevc; | ||||
|   int lastc; | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
|   char mb[MB_LEN_MAX]; | ||||
|   char pmb[MB_LEN_MAX]; | ||||
| #endif | ||||
| 
 | ||||
|   char *sline; | ||||
|  | @ -156,6 +164,8 @@ typedef struct __rl_callback_generic_arg | |||
| 
 | ||||
| typedef int _rl_callback_func_t PARAMS((_rl_callback_generic_arg *)); | ||||
| 
 | ||||
| typedef void _rl_sigcleanup_func_t PARAMS((int, void *)); | ||||
| 
 | ||||
| /*************************************************************************
 | ||||
|  *									 * | ||||
|  * Global functions undocumented in texinfo manual and not in readline.h * | ||||
|  | @ -173,12 +183,14 @@ extern int rl_complete_with_tilde_expansion; | |||
| #if defined (VISIBLE_STATS) | ||||
| extern int rl_visible_stats; | ||||
| #endif /* VISIBLE_STATS */ | ||||
| #if defined (COLOR_SUPPORT) | ||||
| extern int _rl_colored_stats; | ||||
| #endif | ||||
| 
 | ||||
| /* readline.c */ | ||||
| extern int rl_line_buffer_len; | ||||
| extern int rl_arg_sign; | ||||
| extern int rl_visible_prompt_length; | ||||
| extern int rl_key_sequence_length; | ||||
| extern int rl_byte_oriented; | ||||
| 
 | ||||
| /* display.c */ | ||||
|  | @ -189,7 +201,7 @@ extern int rl_blink_matching_paren; | |||
| 
 | ||||
| /*************************************************************************
 | ||||
|  *									 * | ||||
|  * Global functions and variables unsed and undocumented		 * | ||||
|  * Global functions and variables unused and undocumented		 * | ||||
|  *									 * | ||||
|  *************************************************************************/ | ||||
| 
 | ||||
|  | @ -240,6 +252,7 @@ extern void _rl_callback_data_dispose PARAMS((_rl_callback_generic_arg *)); | |||
| #endif /* READLINE_CALLBACKS */ | ||||
| 
 | ||||
| /* bind.c */ | ||||
| extern char *_rl_untranslate_macro_value PARAMS((char *, int)); | ||||
| 
 | ||||
| /* complete.c */ | ||||
| extern void _rl_reset_completion_state PARAMS((void)); | ||||
|  | @ -248,6 +261,7 @@ extern void _rl_free_match_list PARAMS((char **)); | |||
| 
 | ||||
| /* display.c */ | ||||
| extern char *_rl_strip_prompt PARAMS((char *)); | ||||
| extern void _rl_reset_prompt PARAMS((void)); | ||||
| extern void _rl_move_cursor_relative PARAMS((int, const char *)); | ||||
| extern void _rl_move_vert PARAMS((int)); | ||||
| extern void _rl_save_prompt PARAMS((void)); | ||||
|  | @ -282,6 +296,7 @@ extern int _rl_search_getchar PARAMS((_rl_search_cxt *)); | |||
| /* macro.c */ | ||||
| extern void _rl_with_macro_input PARAMS((char *)); | ||||
| extern int _rl_next_macro_key PARAMS((void)); | ||||
| extern int _rl_prev_macro_key PARAMS((void)); | ||||
| extern void _rl_push_executing_macro PARAMS((void)); | ||||
| extern void _rl_pop_executing_macro PARAMS((void)); | ||||
| extern void _rl_add_macro_char PARAMS((int)); | ||||
|  | @ -330,6 +345,7 @@ extern void _rl_release_sigwinch PARAMS((void)); | |||
| 
 | ||||
| /* terminal.c */ | ||||
| extern void _rl_get_screen_size PARAMS((int, int)); | ||||
| extern void _rl_sigwinch_resize_terminal PARAMS((void)); | ||||
| extern int _rl_init_terminal_io PARAMS((const char *)); | ||||
| #ifdef _MINIX | ||||
| extern void _rl_output_character_function PARAMS((int)); | ||||
|  | @ -339,6 +355,7 @@ extern int _rl_output_character_function PARAMS((int)); | |||
| extern void _rl_output_some_chars PARAMS((const char *, int)); | ||||
| extern int _rl_backspace PARAMS((int)); | ||||
| extern void _rl_enable_meta_key PARAMS((void)); | ||||
| extern void _rl_disable_meta_key PARAMS((void)); | ||||
| extern void _rl_control_keypad PARAMS((int)); | ||||
| extern void _rl_set_cursor PARAMS((int, int)); | ||||
| 
 | ||||
|  | @ -360,6 +377,7 @@ extern int _rl_set_mark_at_pos PARAMS((int)); | |||
| /* undo.c */ | ||||
| extern UNDO_LIST *_rl_copy_undo_entry PARAMS((UNDO_LIST *)); | ||||
| extern UNDO_LIST *_rl_copy_undo_list PARAMS((UNDO_LIST *)); | ||||
| extern void _rl_free_undo_list PARAMS((UNDO_LIST *)); | ||||
| 
 | ||||
| /* util.c */ | ||||
| #if defined (USE_VARARGS) && defined (PREFER_STDARG) | ||||
|  | @ -371,6 +389,7 @@ extern void _rl_ttymsg (); | |||
| extern void _rl_errmsg (); | ||||
| extern void _rl_trace (); | ||||
| #endif | ||||
| extern void _rl_audit_tty PARAMS((char *)); | ||||
| 
 | ||||
| extern int _rl_tropen PARAMS((void)); | ||||
| 
 | ||||
|  | @ -441,6 +460,9 @@ extern int _rl_history_saved_point; | |||
| 
 | ||||
| extern _rl_arg_cxt _rl_argcxt; | ||||
| 
 | ||||
| /* nls.c */ | ||||
| extern int _rl_utf8locale; | ||||
| 
 | ||||
| /* readline.c */ | ||||
| extern int _rl_echoing_p; | ||||
| extern int _rl_horizontal_scroll_mode; | ||||
|  | @ -452,6 +474,7 @@ extern int _rl_output_meta_chars; | |||
| extern int _rl_bind_stty_chars; | ||||
| extern int _rl_revert_all_at_newline; | ||||
| extern int _rl_echo_control_chars; | ||||
| extern int _rl_show_mode_in_prompt; | ||||
| extern char *_rl_comment_begin; | ||||
| extern unsigned char _rl_parsing_conditionalized_out; | ||||
| extern Keymap _rl_keymap; | ||||
|  | @ -461,6 +484,9 @@ extern int _rl_last_command_was_kill; | |||
| extern int _rl_eof_char; | ||||
| extern procenv_t _rl_top_level; | ||||
| extern _rl_keyseq_cxt *_rl_kscxt; | ||||
| extern int _rl_keyseq_timeout; | ||||
| 
 | ||||
| extern int _rl_executing_keyseq_size; | ||||
| 
 | ||||
| /* search.c */ | ||||
| extern _rl_search_cxt *_rl_nscxt; | ||||
|  | @ -469,6 +495,9 @@ extern _rl_search_cxt *_rl_nscxt; | |||
| extern int _rl_interrupt_immediately; | ||||
| extern int volatile _rl_caught_signal; | ||||
| 
 | ||||
| extern _rl_sigcleanup_func_t *_rl_sigcleanup; | ||||
| extern void *_rl_sigcleanarg; | ||||
| 
 | ||||
| extern int _rl_echoctl; | ||||
| 
 | ||||
| extern int _rl_intr_char; | ||||
|  |  | |||
|  | @ -42,4 +42,16 @@ | |||
| #  endif | ||||
| #endif | ||||
| 
 | ||||
| /* Moved from config.h.in because readline.h:rl_message depends on these
 | ||||
|    defines. */ | ||||
| #if defined (__STDC__) && defined (HAVE_STDARG_H) | ||||
| #  define PREFER_STDARG | ||||
| #  define USE_VARARGS | ||||
| #else | ||||
| #  if defined (HAVE_VARARGS_H) | ||||
| #    define PREFER_VARARGS | ||||
| #    define USE_VARARGS | ||||
| #  endif | ||||
| #endif | ||||
| 
 | ||||
| #endif /* !_RL_STDC_H_ */ | ||||
|  |  | |||
|  | @ -121,7 +121,7 @@ static int set_tty_settings PARAMS((int, TIOTYPE *)); | |||
| 
 | ||||
| static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *)); | ||||
| 
 | ||||
| static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t)); | ||||
| static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t *)); | ||||
| 
 | ||||
| static void | ||||
| save_tty_chars (tiop) | ||||
|  | @ -341,7 +341,7 @@ static int set_tty_settings PARAMS((int, TIOTYPE *)); | |||
| 
 | ||||
| static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *)); | ||||
| 
 | ||||
| static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t)); | ||||
| static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t *)); | ||||
| static void _rl_bind_tty_special_chars PARAMS((Keymap, TIOTYPE)); | ||||
| 
 | ||||
| #if defined (FLUSHO) | ||||
|  | @ -528,10 +528,10 @@ prepare_terminal_settings (meta_flag, oldtio, tiop) | |||
| 
 | ||||
| #if defined (USE_XON_XOFF) | ||||
| #if defined (IXANY) | ||||
|   tiop->c_iflag &= ~(IXON | IXOFF | IXANY); | ||||
|   tiop->c_iflag &= ~(IXON | IXANY); | ||||
| #else | ||||
|   /* `strict' Posix systems do not define IXANY. */ | ||||
|   tiop->c_iflag &= ~(IXON | IXOFF); | ||||
|   tiop->c_iflag &= ~IXON; | ||||
| #endif /* IXANY */ | ||||
| #endif /* USE_XON_XOFF */ | ||||
| 
 | ||||
|  | @ -678,7 +678,7 @@ rl_deprep_terminal () | |||
|   /* Try to keep this function from being interrupted. */ | ||||
|   _rl_block_sigint (); | ||||
| 
 | ||||
|   tty = rl_instream ? fileno (rl_instream) : fileno (stdout); | ||||
|   tty = rl_instream ? fileno (rl_instream) : fileno (stdin); | ||||
| 
 | ||||
|   if (_rl_enable_keypad) | ||||
|     _rl_control_keypad (0); | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| /* rltypedefs.h -- Type declarations for readline functions. */ | ||||
| 
 | ||||
| /* Copyright (C) 2000-2009 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 2000-2011 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file is part of the GNU Readline Library (Readline), a library | ||||
|    for reading lines of text with interactive input and history editing.       | ||||
|  | @ -26,18 +26,6 @@ | |||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| /* Old-style */ | ||||
| 
 | ||||
| #if !defined (_FUNCTION_DEF) | ||||
| #  define _FUNCTION_DEF | ||||
| 
 | ||||
| typedef int Function (); | ||||
| typedef void VFunction (); | ||||
| typedef char *CPFunction (); | ||||
| typedef char **CPPFunction (); | ||||
| 
 | ||||
| #endif /* _FUNCTION_DEF */ | ||||
| 
 | ||||
| /* New style. */ | ||||
| 
 | ||||
| #if !defined (_RL_FUNCTION_TYPEDEF) | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| /* search.c - code for non-incremental searching in emacs and vi modes. */ | ||||
| 
 | ||||
| /* Copyright (C) 1992-2009 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 1992-2013 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file is part of the GNU Readline Library (Readline), a library | ||||
|    for reading lines of text with interactive input and history editing.       | ||||
|  | @ -43,6 +43,7 @@ | |||
| 
 | ||||
| #include "readline.h" | ||||
| #include "history.h" | ||||
| #include "histlib.h" | ||||
| 
 | ||||
| #include "rlprivate.h" | ||||
| #include "xmalloc.h" | ||||
|  | @ -66,6 +67,8 @@ static char *prev_line_found = (char *) NULL; | |||
| 
 | ||||
| static int rl_history_search_len; | ||||
| static int rl_history_search_pos; | ||||
| static int rl_history_search_flags; | ||||
| 
 | ||||
| static char *history_search_string; | ||||
| static int history_string_size; | ||||
| 
 | ||||
|  | @ -74,7 +77,7 @@ static int noninc_search_from_pos PARAMS((char *, int, int)); | |||
| static int noninc_dosearch PARAMS((char *, int)); | ||||
| static int noninc_search PARAMS((int, int)); | ||||
| static int rl_history_search_internal PARAMS((int, int)); | ||||
| static void rl_history_search_reinit PARAMS((void)); | ||||
| static void rl_history_search_reinit PARAMS((int)); | ||||
| 
 | ||||
| static _rl_search_cxt *_rl_nsearch_init PARAMS((int, int)); | ||||
| static int _rl_nsearch_cleanup PARAMS((_rl_search_cxt *, int)); | ||||
|  | @ -169,7 +172,8 @@ noninc_dosearch (string, dir) | |||
| 
 | ||||
|   oldpos = where_history (); | ||||
|   history_set_pos (noninc_history_pos); | ||||
|   entry = current_history (); | ||||
|   entry = current_history ();		/* will never be NULL after successful search */ | ||||
|    | ||||
| #if defined (VI_MODE) | ||||
|   if (rl_editing_mode != vi_mode) | ||||
| #endif | ||||
|  | @ -210,7 +214,7 @@ _rl_nsearch_init (dir, pchar) | |||
|   rl_end = rl_point = 0; | ||||
| 
 | ||||
|   p = _rl_make_prompt_for_search (pchar ? pchar : ':'); | ||||
|   rl_message ("%s", p, 0); | ||||
|   rl_message ("%s", p); | ||||
|   xfree (p); | ||||
| 
 | ||||
|   RL_SETSTATE(RL_STATE_NSEARCH); | ||||
|  | @ -453,15 +457,19 @@ rl_history_search_internal (count, dir) | |||
| { | ||||
|   HIST_ENTRY *temp; | ||||
|   int ret, oldpos; | ||||
|   char *t; | ||||
| 
 | ||||
|   rl_maybe_save_line (); | ||||
|   temp = (HIST_ENTRY *)NULL; | ||||
| 
 | ||||
|   /* Search COUNT times through the history for a line whose prefix
 | ||||
|      matches history_search_string.  When this loop finishes, TEMP, | ||||
|      if non-null, is the history line to copy into the line buffer. */ | ||||
|   /* Search COUNT times through the history for a line matching
 | ||||
|      history_search_string.  If history_search_string[0] == '^', the | ||||
|      line must match from the start; otherwise any substring can match. | ||||
|      When this loop finishes, TEMP, if non-null, is the history line to | ||||
|      copy into the line buffer. */ | ||||
|   while (count) | ||||
|     { | ||||
|       RL_CHECK_SIGNALS (); | ||||
|       ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir); | ||||
|       if (ret == -1) | ||||
| 	break; | ||||
|  | @ -470,7 +478,7 @@ rl_history_search_internal (count, dir) | |||
|       rl_history_search_pos = ret; | ||||
|       oldpos = where_history (); | ||||
|       history_set_pos (rl_history_search_pos); | ||||
|       temp = current_history (); | ||||
|       temp = current_history ();	/* will never be NULL after successful search */ | ||||
|       history_set_pos (oldpos); | ||||
| 
 | ||||
|       /* Don't find multiple instances of the same line. */ | ||||
|  | @ -505,35 +513,49 @@ rl_history_search_internal (count, dir) | |||
|   /* Copy the line we found into the current line buffer. */ | ||||
|   make_history_line_current (temp); | ||||
| 
 | ||||
|   rl_point = rl_history_search_len; | ||||
|   if (rl_history_search_flags & ANCHORED_SEARCH) | ||||
|     rl_point = rl_history_search_len;	/* easy case */ | ||||
|   else | ||||
|     { | ||||
|       t = strstr (rl_line_buffer, history_search_string); | ||||
|       rl_point = t ? (int)(t - rl_line_buffer) + rl_history_search_len : rl_end; | ||||
|     } | ||||
|   rl_mark = rl_end; | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| rl_history_search_reinit () | ||||
| rl_history_search_reinit (flags) | ||||
|      int flags; | ||||
| { | ||||
|   int sind; | ||||
| 
 | ||||
|   rl_history_search_pos = where_history (); | ||||
|   rl_history_search_len = rl_point; | ||||
|   rl_history_search_flags = flags; | ||||
| 
 | ||||
|   prev_line_found = (char *)NULL; | ||||
|   if (rl_point) | ||||
|     { | ||||
|       /* Allocate enough space for anchored and non-anchored searches */ | ||||
|       if (rl_history_search_len >= history_string_size - 2) | ||||
| 	{ | ||||
| 	  history_string_size = rl_history_search_len + 2; | ||||
| 	  history_search_string = (char *)xrealloc (history_search_string, history_string_size); | ||||
| 	} | ||||
|       history_search_string[0] = '^'; | ||||
|       strncpy (history_search_string + 1, rl_line_buffer, rl_point); | ||||
|       history_search_string[rl_point + 1] = '\0'; | ||||
|       sind = 0; | ||||
|       if (flags & ANCHORED_SEARCH) | ||||
| 	history_search_string[sind++] = '^'; | ||||
|       strncpy (history_search_string + sind, rl_line_buffer, rl_point); | ||||
|       history_search_string[rl_point + sind] = '\0'; | ||||
|     } | ||||
|   _rl_free_saved_history_line (); | ||||
| } | ||||
| 
 | ||||
| /* Search forward in the history for the string of characters
 | ||||
|    from the start of the line to rl_point.  This is a non-incremental | ||||
|    search. */ | ||||
|    search.  The search is anchored to the beginning of the history line. */ | ||||
| int | ||||
| rl_history_search_forward (count, ignore) | ||||
|      int count, ignore; | ||||
|  | @ -543,7 +565,7 @@ rl_history_search_forward (count, ignore) | |||
| 
 | ||||
|   if (rl_last_func != rl_history_search_forward && | ||||
|       rl_last_func != rl_history_search_backward) | ||||
|     rl_history_search_reinit (); | ||||
|     rl_history_search_reinit (ANCHORED_SEARCH); | ||||
| 
 | ||||
|   if (rl_history_search_len == 0) | ||||
|     return (rl_get_next_history (count, ignore)); | ||||
|  | @ -562,7 +584,46 @@ rl_history_search_backward (count, ignore) | |||
| 
 | ||||
|   if (rl_last_func != rl_history_search_forward && | ||||
|       rl_last_func != rl_history_search_backward) | ||||
|     rl_history_search_reinit (); | ||||
|     rl_history_search_reinit (ANCHORED_SEARCH); | ||||
| 
 | ||||
|   if (rl_history_search_len == 0) | ||||
|     return (rl_get_previous_history (count, ignore)); | ||||
|   return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1)); | ||||
| } | ||||
| 
 | ||||
| /* Search forward in the history for the string of characters
 | ||||
|    from the start of the line to rl_point.  This is a non-incremental | ||||
|    search.  The search succeeds if the search string is present anywhere | ||||
|    in the history line. */ | ||||
| int | ||||
| rl_history_substr_search_forward (count, ignore) | ||||
|      int count, ignore; | ||||
| { | ||||
|   if (count == 0) | ||||
|     return (0); | ||||
| 
 | ||||
|   if (rl_last_func != rl_history_substr_search_forward && | ||||
|       rl_last_func != rl_history_substr_search_backward) | ||||
|     rl_history_search_reinit (NON_ANCHORED_SEARCH); | ||||
| 
 | ||||
|   if (rl_history_search_len == 0) | ||||
|     return (rl_get_next_history (count, ignore)); | ||||
|   return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1)); | ||||
| } | ||||
| 
 | ||||
| /* Search backward through the history for the string of characters
 | ||||
|    from the start of the line to rl_point.  This is a non-incremental | ||||
|    search. */ | ||||
| int | ||||
| rl_history_substr_search_backward (count, ignore) | ||||
|      int count, ignore; | ||||
| { | ||||
|   if (count == 0) | ||||
|     return (0); | ||||
| 
 | ||||
|   if (rl_last_func != rl_history_substr_search_forward && | ||||
|       rl_last_func != rl_history_substr_search_backward) | ||||
|     rl_history_search_reinit (NON_ANCHORED_SEARCH); | ||||
| 
 | ||||
|   if (rl_history_search_len == 0) | ||||
|     return (rl_get_previous_history (count, ignore)); | ||||
|  |  | |||
|  | @ -59,6 +59,8 @@ | |||
| 
 | ||||
| #include "rlstdc.h" | ||||
| #include "rlshell.h" | ||||
| #include "rldefs.h" | ||||
| 
 | ||||
| #include "xmalloc.h" | ||||
| 
 | ||||
| #if defined (HAVE_GETPWUID) && !defined (HAVE_GETPW_DECLS) | ||||
|  | @ -120,31 +122,27 @@ sh_single_quote (string) | |||
| 
 | ||||
| /* Set the environment variables LINES and COLUMNS to lines and cols,
 | ||||
|    respectively. */ | ||||
| static char setenv_buf[INT_STRLEN_BOUND (int) + 1]; | ||||
| static char putenv_buf1[INT_STRLEN_BOUND (int) + 6 + 1];	/* sizeof("LINES=") == 6 */ | ||||
| static char putenv_buf2[INT_STRLEN_BOUND (int) + 8 + 1];	/* sizeof("COLUMNS=") == 8 */ | ||||
| 
 | ||||
| void | ||||
| sh_set_lines_and_columns (lines, cols) | ||||
|      int lines, cols; | ||||
| { | ||||
|   char *b; | ||||
| 
 | ||||
| #if defined (HAVE_SETENV) | ||||
|   b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1); | ||||
|   sprintf (b, "%d", lines); | ||||
|   setenv ("LINES", b, 1); | ||||
|   xfree (b); | ||||
|   sprintf (setenv_buf, "%d", lines); | ||||
|   setenv ("LINES", setenv_buf, 1); | ||||
| 
 | ||||
|   b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1); | ||||
|   sprintf (b, "%d", cols); | ||||
|   setenv ("COLUMNS", b, 1); | ||||
|   xfree (b); | ||||
|   sprintf (setenv_buf, "%d", cols); | ||||
|   setenv ("COLUMNS", setenv_buf, 1); | ||||
| #else /* !HAVE_SETENV */ | ||||
| #  if defined (HAVE_PUTENV) | ||||
|   b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("LINES=") + 1); | ||||
|   sprintf (b, "LINES=%d", lines); | ||||
|   putenv (b); | ||||
|   sprintf (putenv_buf1, "LINES=%d", lines); | ||||
|   putenv (putenv_buf1); | ||||
| 
 | ||||
|   b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("COLUMNS=") + 1); | ||||
|   sprintf (b, "COLUMNS=%d", cols); | ||||
|   putenv (b); | ||||
|   sprintf (putenv_buf2, "COLUMNS=%d", cols); | ||||
|   putenv (putenv_buf2); | ||||
| #  endif /* HAVE_PUTENV */ | ||||
| #endif /* !HAVE_SETENV */ | ||||
| } | ||||
|  | @ -159,15 +157,27 @@ sh_get_env_value (varname) | |||
| char * | ||||
| sh_get_home_dir () | ||||
| { | ||||
|   char *home_dir; | ||||
|   static char *home_dir = (char *)NULL; | ||||
|   struct passwd *entry; | ||||
| 
 | ||||
|   if (home_dir) | ||||
|     return (home_dir); | ||||
| 
 | ||||
|   home_dir = (char *)NULL; | ||||
| #if defined (HAVE_GETPWUID) | ||||
| #  if defined (__TANDEM) | ||||
|   entry = getpwnam (getlogin ()); | ||||
| #  else | ||||
|   entry = getpwuid (getuid ()); | ||||
| #  endif | ||||
|   if (entry) | ||||
|     home_dir = entry->pw_dir; | ||||
|     home_dir = savestring (entry->pw_dir); | ||||
| #endif | ||||
| 
 | ||||
| #if defined (HAVE_GETPWENT) | ||||
|   endpwent ();		/* some systems need this */ | ||||
| #endif | ||||
| 
 | ||||
|   return (home_dir); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| /* signals.c -- signal handling support for readline. */ | ||||
| 
 | ||||
| /* Copyright (C) 1987-2009 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 1987-2011 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file is part of the GNU Readline Library (Readline), a library | ||||
|    for reading lines of text with interactive input and history editing.       | ||||
|  | @ -80,6 +80,7 @@ typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt | |||
| 
 | ||||
| static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *)); | ||||
| static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *)); | ||||
| static void rl_maybe_restore_sighandler PARAMS((int, sighandler_cxt *)); | ||||
| 
 | ||||
| static RETSIGTYPE rl_signal_handler PARAMS((int)); | ||||
| static RETSIGTYPE _rl_handle_signal PARAMS((int)); | ||||
|  | @ -87,7 +88,7 @@ static RETSIGTYPE _rl_handle_signal PARAMS((int)); | |||
| /* Exported variables for use by applications. */ | ||||
| 
 | ||||
| /* If non-zero, readline will install its own signal handlers for
 | ||||
|    SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */ | ||||
|    SIGINT, SIGTERM, SIGHUP, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */ | ||||
| int rl_catch_signals = 1; | ||||
| 
 | ||||
| /* If non-zero, readline will install a signal handler for SIGWINCH. */ | ||||
|  | @ -118,7 +119,7 @@ static int sigwinch_set_flag; | |||
| /*								    */ | ||||
| /* **************************************************************** */ | ||||
| 
 | ||||
| static sighandler_cxt old_int, old_term, old_alrm, old_quit; | ||||
| static sighandler_cxt old_int, old_term, old_hup, old_alrm, old_quit; | ||||
| #if defined (SIGTSTP) | ||||
| static sighandler_cxt old_tstp, old_ttou, old_ttin; | ||||
| #endif | ||||
|  | @ -126,6 +127,9 @@ static sighandler_cxt old_tstp, old_ttou, old_ttin; | |||
| static sighandler_cxt old_winch; | ||||
| #endif | ||||
| 
 | ||||
| _rl_sigcleanup_func_t *_rl_sigcleanup; | ||||
| void *_rl_sigcleanarg; | ||||
| 
 | ||||
| /* Readline signal handler functions. */ | ||||
| 
 | ||||
| /* Called from RL_CHECK_SIGNALS() macro */ | ||||
|  | @ -135,7 +139,21 @@ _rl_signal_handler (sig) | |||
| { | ||||
|   _rl_caught_signal = 0;	/* XXX */ | ||||
| 
 | ||||
|   _rl_handle_signal (sig); | ||||
| #if defined (SIGWINCH) | ||||
|   if (sig == SIGWINCH) | ||||
|     { | ||||
|       rl_resize_terminal (); | ||||
|       /* XXX - experimental for now */ | ||||
|       /* Call a signal hook because though we called the original signal handler
 | ||||
| 	 in rl_sigwinch_handler below, we will not resend the signal to | ||||
| 	 ourselves. */ | ||||
|       if (rl_signal_event_hook) | ||||
| 	(*rl_signal_event_hook) (); | ||||
|     } | ||||
|   else | ||||
| #endif | ||||
|     _rl_handle_signal (sig); | ||||
| 
 | ||||
|   SIGHANDLER_RETURN; | ||||
| } | ||||
| 
 | ||||
|  | @ -143,7 +161,7 @@ static RETSIGTYPE | |||
| rl_signal_handler (sig) | ||||
|      int sig; | ||||
| { | ||||
|   if (_rl_interrupt_immediately || RL_ISSTATE(RL_STATE_CALLBACK)) | ||||
|   if (_rl_interrupt_immediately) | ||||
|     { | ||||
|       _rl_interrupt_immediately = 0; | ||||
|       _rl_handle_signal (sig); | ||||
|  | @ -181,6 +199,15 @@ _rl_handle_signal (sig) | |||
|     rl_set_sighandler (sig, SIG_IGN, &dummy_cxt); | ||||
| #endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */ | ||||
| 
 | ||||
|   /* If there's a sig cleanup function registered, call it and `deregister'
 | ||||
|      the cleanup function to avoid multiple calls */ | ||||
|   if (_rl_sigcleanup) | ||||
|     { | ||||
|       (*_rl_sigcleanup) (sig, _rl_sigcleanarg); | ||||
|       _rl_sigcleanup = 0; | ||||
|       _rl_sigcleanarg = 0; | ||||
|     } | ||||
|      | ||||
|   switch (sig) | ||||
|     { | ||||
|     case SIGINT: | ||||
|  | @ -189,6 +216,7 @@ _rl_handle_signal (sig) | |||
|       /* FALLTHROUGH */ | ||||
| 
 | ||||
|     case SIGTERM: | ||||
|     case SIGHUP: | ||||
| #if defined (SIGTSTP) | ||||
|     case SIGTSTP: | ||||
|     case SIGTTOU: | ||||
|  | @ -232,7 +260,7 @@ _rl_handle_signal (sig) | |||
| #  endif /* HAVE_BSD_SIGNALS */ | ||||
| #endif /* !HAVE_POSIX_SIGNALS */ | ||||
| 
 | ||||
|       rl_reset_after_signal (); | ||||
|       rl_reset_after_signal ();       | ||||
|     } | ||||
| 
 | ||||
|   RL_UNSETSTATE(RL_STATE_SIGHANDLER); | ||||
|  | @ -257,7 +285,7 @@ rl_sigwinch_handler (sig) | |||
| #endif | ||||
| 
 | ||||
|   RL_SETSTATE(RL_STATE_SIGHANDLER); | ||||
|   rl_resize_terminal (); | ||||
|   _rl_caught_signal = sig; | ||||
| 
 | ||||
|   /* If another sigwinch handler has been installed, call it. */ | ||||
|   oh = (SigHandler *)old_winch.sa_handler; | ||||
|  | @ -317,6 +345,8 @@ rl_set_sighandler (sig, handler, ohandler) | |||
|   return (ohandler->sa_handler); | ||||
| } | ||||
| 
 | ||||
| /* Set disposition of SIG to HANDLER, returning old state in OHANDLER.  Don't
 | ||||
|    change disposition if OHANDLER indicates the signal was ignored. */ | ||||
| static void | ||||
| rl_maybe_set_sighandler (sig, handler, ohandler) | ||||
|      int sig; | ||||
|  | @ -327,11 +357,29 @@ rl_maybe_set_sighandler (sig, handler, ohandler) | |||
|   SigHandler *oh; | ||||
| 
 | ||||
|   sigemptyset (&dummy.sa_mask); | ||||
|   dummy.sa_flags = 0; | ||||
|   oh = rl_set_sighandler (sig, handler, ohandler); | ||||
|   if (oh == (SigHandler *)SIG_IGN) | ||||
|     rl_sigaction (sig, ohandler, &dummy); | ||||
| } | ||||
| 
 | ||||
| /* Set the disposition of SIG to HANDLER, if HANDLER->sa_handler indicates the
 | ||||
|    signal was not being ignored.  MUST only be called for signals whose | ||||
|    disposition was changed using rl_maybe_set_sighandler or for which the | ||||
|    SIG_IGN check was performed inline (e.g., SIGALRM below). */ | ||||
| static void | ||||
| rl_maybe_restore_sighandler (sig, handler) | ||||
|      int sig; | ||||
|      sighandler_cxt *handler; | ||||
| { | ||||
|   sighandler_cxt dummy; | ||||
| 
 | ||||
|   sigemptyset (&dummy.sa_mask); | ||||
|   dummy.sa_flags = 0; | ||||
|   if (handler->sa_handler != SIG_IGN) | ||||
|     rl_sigaction (sig, handler, &dummy); | ||||
| } | ||||
| 
 | ||||
| int | ||||
| rl_set_signals () | ||||
| { | ||||
|  | @ -349,6 +397,7 @@ rl_set_signals () | |||
| 
 | ||||
|       sigaddset (&bset, SIGINT); | ||||
|       sigaddset (&bset, SIGTERM); | ||||
|       sigaddset (&bset, SIGHUP); | ||||
| #if defined (SIGQUIT) | ||||
|       sigaddset (&bset, SIGQUIT); | ||||
| #endif | ||||
|  | @ -377,6 +426,7 @@ rl_set_signals () | |||
| 
 | ||||
|       rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int); | ||||
|       rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term); | ||||
|       rl_maybe_set_sighandler (SIGHUP, rl_signal_handler, &old_hup); | ||||
| #if defined (SIGQUIT) | ||||
|       rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit); | ||||
| #endif | ||||
|  | @ -434,25 +484,31 @@ rl_clear_signals () | |||
|     { | ||||
|       sigemptyset (&dummy.sa_mask); | ||||
| 
 | ||||
|       rl_sigaction (SIGINT, &old_int, &dummy); | ||||
|       rl_sigaction (SIGTERM, &old_term, &dummy); | ||||
|       /* Since rl_maybe_set_sighandler doesn't override a SIG_IGN handler,
 | ||||
| 	 we should in theory not have to restore a handler where | ||||
| 	 old_xxx.sa_handler == SIG_IGN.  That's what rl_maybe_restore_sighandler | ||||
| 	 does.  Fewer system calls should reduce readline's per-line | ||||
| 	 overhead */ | ||||
|       rl_maybe_restore_sighandler (SIGINT, &old_int); | ||||
|       rl_maybe_restore_sighandler (SIGTERM, &old_term); | ||||
|       rl_maybe_restore_sighandler (SIGHUP, &old_hup); | ||||
| #if defined (SIGQUIT) | ||||
|       rl_sigaction (SIGQUIT, &old_quit, &dummy); | ||||
|       rl_maybe_restore_sighandler (SIGQUIT, &old_quit); | ||||
| #endif | ||||
| #if defined (SIGALRM) | ||||
|       rl_sigaction (SIGALRM, &old_alrm, &dummy); | ||||
|       rl_maybe_restore_sighandler (SIGALRM, &old_alrm); | ||||
| #endif | ||||
| 
 | ||||
| #if defined (SIGTSTP) | ||||
|       rl_sigaction (SIGTSTP, &old_tstp, &dummy); | ||||
|       rl_maybe_restore_sighandler (SIGTSTP, &old_tstp); | ||||
| #endif /* SIGTSTP */ | ||||
| 
 | ||||
| #if defined (SIGTTOU) | ||||
|       rl_sigaction (SIGTTOU, &old_ttou, &dummy); | ||||
|       rl_maybe_restore_sighandler (SIGTTOU, &old_ttou); | ||||
| #endif /* SIGTTOU */ | ||||
| 
 | ||||
| #if defined (SIGTTIN) | ||||
|       rl_sigaction (SIGTTIN, &old_ttin, &dummy); | ||||
|       rl_maybe_restore_sighandler (SIGTTIN, &old_ttin); | ||||
| #endif /* SIGTTIN */ | ||||
| 
 | ||||
|       signals_set_flag = 0; | ||||
|  | @ -540,21 +596,6 @@ _rl_block_sigint () | |||
|   if (sigint_blocked) | ||||
|     return; | ||||
| 
 | ||||
| #if defined (HAVE_POSIX_SIGNALS) | ||||
|   sigemptyset (&sigint_set); | ||||
|   sigemptyset (&sigint_oset); | ||||
|   sigaddset (&sigint_set, SIGINT); | ||||
|   sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset); | ||||
| #else /* !HAVE_POSIX_SIGNALS */ | ||||
| #  if defined (HAVE_BSD_SIGNALS) | ||||
|   sigint_oldmask = sigblock (sigmask (SIGINT)); | ||||
| #  else /* !HAVE_BSD_SIGNALS */ | ||||
| #    if defined (HAVE_USG_SIGHOLD) | ||||
|   sighold (SIGINT); | ||||
| #    endif /* HAVE_USG_SIGHOLD */ | ||||
| #  endif /* !HAVE_BSD_SIGNALS */ | ||||
| #endif /* !HAVE_POSIX_SIGNALS */ | ||||
| 
 | ||||
|   sigint_blocked = 1; | ||||
| } | ||||
| 
 | ||||
|  | @ -565,19 +606,8 @@ _rl_release_sigint () | |||
|   if (sigint_blocked == 0) | ||||
|     return; | ||||
| 
 | ||||
| #if defined (HAVE_POSIX_SIGNALS) | ||||
|   sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL); | ||||
| #else | ||||
| #  if defined (HAVE_BSD_SIGNALS) | ||||
|   sigsetmask (sigint_oldmask); | ||||
| #  else /* !HAVE_BSD_SIGNALS */ | ||||
| #    if defined (HAVE_USG_SIGHOLD) | ||||
|   sigrelse (SIGINT); | ||||
| #    endif /* HAVE_USG_SIGHOLD */ | ||||
| #  endif /* !HAVE_BSD_SIGNALS */ | ||||
| #endif /* !HAVE_POSIX_SIGNALS */ | ||||
| 
 | ||||
|   sigint_blocked = 0; | ||||
|   RL_CHECK_SIGNALS (); | ||||
| } | ||||
| 
 | ||||
| /* Cause SIGWINCH to not be delivered until the corresponding call to
 | ||||
|  | @ -588,6 +618,8 @@ _rl_block_sigwinch () | |||
|   if (sigwinch_blocked) | ||||
|     return; | ||||
| 
 | ||||
| #if defined (SIGWINCH) | ||||
| 
 | ||||
| #if defined (HAVE_POSIX_SIGNALS) | ||||
|   sigemptyset (&sigwinch_set); | ||||
|   sigemptyset (&sigwinch_oset); | ||||
|  | @ -603,6 +635,8 @@ _rl_block_sigwinch () | |||
| #  endif /* !HAVE_BSD_SIGNALS */ | ||||
| #endif /* !HAVE_POSIX_SIGNALS */ | ||||
| 
 | ||||
| #endif /* SIGWINCH */ | ||||
| 
 | ||||
|   sigwinch_blocked = 1; | ||||
| } | ||||
| 
 | ||||
|  | @ -613,6 +647,8 @@ _rl_release_sigwinch () | |||
|   if (sigwinch_blocked == 0) | ||||
|     return; | ||||
| 
 | ||||
| #if defined (SIGWINCH) | ||||
| 
 | ||||
| #if defined (HAVE_POSIX_SIGNALS) | ||||
|   sigprocmask (SIG_SETMASK, &sigwinch_oset, (sigset_t *)NULL); | ||||
| #else | ||||
|  | @ -625,6 +661,8 @@ _rl_release_sigwinch () | |||
| #  endif /* !HAVE_BSD_SIGNALS */ | ||||
| #endif /* !HAVE_POSIX_SIGNALS */ | ||||
| 
 | ||||
| #endif /* SIGWINCH */ | ||||
| 
 | ||||
|   sigwinch_blocked = 0; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -55,6 +55,10 @@ | |||
| #  include <sys/ioctl.h> | ||||
| #endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */ | ||||
| 
 | ||||
| #ifdef __MSDOS__ | ||||
| #  include <pc.h> | ||||
| #endif | ||||
| 
 | ||||
| #include "rltty.h" | ||||
| #include "tcap.h" | ||||
| 
 | ||||
|  | @ -77,22 +81,25 @@ static void _win_get_screensize PARAMS((int *, int *)); | |||
| static void _emx_get_screensize PARAMS((int *, int *)); | ||||
| #endif | ||||
| 
 | ||||
| #define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay) | ||||
| #define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc) | ||||
| 
 | ||||
| /*  If the calling application sets this to a non-zero value, readline will
 | ||||
|     use the $LINES and $COLUMNS environment variables to set its idea of the | ||||
|     window size before interrogating the kernel. */ | ||||
| /* If the calling application sets this to a non-zero value, readline will
 | ||||
|    use the $LINES and $COLUMNS environment variables to set its idea of the | ||||
|    window size before interrogating the kernel. */ | ||||
| int rl_prefer_env_winsize = 0; | ||||
| 
 | ||||
| /* If this is non-zero, readline will set LINES and COLUMNS in the
 | ||||
|    environment when it handles SIGWINCH. */ | ||||
| int rl_change_environment = 1; | ||||
| 
 | ||||
| /* **************************************************************** */ | ||||
| /*								    */ | ||||
| /*			Terminal and Termcap			    */ | ||||
| /*								    */ | ||||
| /* **************************************************************** */ | ||||
| 
 | ||||
| #ifndef __MSDOS__ | ||||
| static char *term_buffer = (char *)NULL; | ||||
| static char *term_string_buffer = (char *)NULL; | ||||
| #endif | ||||
| 
 | ||||
| static int tcap_initialized; | ||||
| 
 | ||||
|  | @ -264,7 +271,10 @@ _rl_get_screen_size (tty, ignore_env) | |||
|       if (_rl_screenwidth <= 0) | ||||
|         _rl_screenwidth = wc; | ||||
| 
 | ||||
| #if !defined (__DJGPP__) | ||||
| #if defined (__DJGPP__) | ||||
|       if (_rl_screenwidth <= 0) | ||||
| 	_rl_screenwidth = ScreenCols (); | ||||
| #else | ||||
|       if (_rl_screenwidth <= 0 && term_string_buffer) | ||||
| 	_rl_screenwidth = tgetnum ("co"); | ||||
| #endif | ||||
|  | @ -280,7 +290,10 @@ _rl_get_screen_size (tty, ignore_env) | |||
|       if (_rl_screenheight <= 0) | ||||
|         _rl_screenheight = wr; | ||||
| 
 | ||||
| #if !defined (__DJGPP__) | ||||
| #if defined (__DJGPP__) | ||||
|       if (_rl_screenheight <= 0) | ||||
| 	_rl_screenheight = ScreenRows (); | ||||
| #else | ||||
|       if (_rl_screenheight <= 0 && term_string_buffer) | ||||
| 	_rl_screenheight = tgetnum ("li"); | ||||
| #endif | ||||
|  | @ -296,7 +309,8 @@ _rl_get_screen_size (tty, ignore_env) | |||
|   /* If we're being compiled as part of bash, set the environment
 | ||||
|      variables $LINES and $COLUMNS to new values.  Otherwise, just | ||||
|      do a pair of putenv () or setenv () calls. */ | ||||
|   sh_set_lines_and_columns (_rl_screenheight, _rl_screenwidth); | ||||
|   if (rl_change_environment) | ||||
|     sh_set_lines_and_columns (_rl_screenheight, _rl_screenwidth); | ||||
| 
 | ||||
|   if (_rl_term_autowrap == 0) | ||||
|     _rl_screenwidth--; | ||||
|  | @ -346,7 +360,13 @@ rl_reset_screen_size () | |||
| { | ||||
|   _rl_get_screen_size (fileno (rl_instream), 0); | ||||
| } | ||||
|       | ||||
| 
 | ||||
| void | ||||
| _rl_sigwinch_resize_terminal () | ||||
| { | ||||
|   _rl_get_screen_size (fileno (rl_instream), 1); | ||||
| } | ||||
| 	 | ||||
| void | ||||
| rl_resize_terminal () | ||||
| { | ||||
|  | @ -432,6 +452,23 @@ _rl_init_terminal_io (terminal_name) | |||
|   if (term == 0) | ||||
|     term = "dumb"; | ||||
| 
 | ||||
| #ifdef __MSDOS__ | ||||
|   _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL; | ||||
|   _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL; | ||||
|   _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL; | ||||
|   _rl_term_mm = _rl_term_mo = (char *)NULL; | ||||
|   _rl_terminal_can_insert = term_has_meta = _rl_term_autowrap = 0; | ||||
|   _rl_term_cr = "\r"; | ||||
|   _rl_term_clreol = _rl_term_clrpag = _rl_term_backspace = (char *)NULL; | ||||
|   _rl_term_goto = _rl_term_pc = _rl_term_ip = (char *)NULL; | ||||
|   _rl_term_ks = _rl_term_ke =_rl_term_vs = _rl_term_ve = (char *)NULL; | ||||
|   _rl_term_kh = _rl_term_kH = _rl_term_at7 = _rl_term_kI = (char *)NULL; | ||||
| #if defined(HACK_TERMCAP_MOTION) | ||||
|   _rl_term_forward_char = (char *)NULL; | ||||
| #endif | ||||
| 
 | ||||
|   _rl_get_screen_size (tty, 0); | ||||
| #else  /* !__MSDOS__ */ | ||||
|   /* I've separated this out for later work on not calling tgetent at all
 | ||||
|      if the calling application has supplied a custom redisplay function, | ||||
|      (and possibly if the application has supplied a custom input function). */ | ||||
|  | @ -531,6 +568,7 @@ _rl_init_terminal_io (terminal_name) | |||
|   term_has_meta = tgetflag ("km") != 0; | ||||
|   if (term_has_meta == 0) | ||||
|     _rl_term_mm = _rl_term_mo = (char *)NULL; | ||||
| #endif /* !__MSDOS__ */ | ||||
| 
 | ||||
|   /* Attempt to find and bind the arrow keys.  Do not override already
 | ||||
|      bound keys in an overzealous attempt, however. */ | ||||
|  | @ -628,10 +666,12 @@ _rl_backspace (count) | |||
| { | ||||
|   register int i; | ||||
| 
 | ||||
| #ifndef __MSDOS__ | ||||
|   if (_rl_term_backspace) | ||||
|     for (i = 0; i < count; i++) | ||||
|       tputs (_rl_term_backspace, 1, _rl_output_character_function); | ||||
|   else | ||||
| #endif | ||||
|     for (i = 0; i < count; i++) | ||||
|       putc ('\b', _rl_out_stream); | ||||
|   return 0; | ||||
|  | @ -663,7 +703,11 @@ rl_ding () | |||
| 	case VISIBLE_BELL: | ||||
| 	  if (_rl_visible_bell) | ||||
| 	    { | ||||
| #ifdef __DJGPP__ | ||||
| 	      ScreenVisualBell (); | ||||
| #else | ||||
| 	      tputs (_rl_visible_bell, 1, _rl_output_character_function); | ||||
| #endif | ||||
| 	      break; | ||||
| 	    } | ||||
| 	  /* FALLTHROUGH */ | ||||
|  | @ -683,12 +727,29 @@ rl_ding () | |||
| /*								    */ | ||||
| /* **************************************************************** */ | ||||
| 
 | ||||
| static int enabled_meta = 0;	/* flag indicating we enabled meta mode */ | ||||
| 
 | ||||
| void | ||||
| _rl_enable_meta_key () | ||||
| { | ||||
| #if !defined (__DJGPP__) | ||||
|   if (term_has_meta && _rl_term_mm) | ||||
|     tputs (_rl_term_mm, 1, _rl_output_character_function); | ||||
|     { | ||||
|       tputs (_rl_term_mm, 1, _rl_output_character_function); | ||||
|       enabled_meta = 1; | ||||
|     } | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void | ||||
| _rl_disable_meta_key () | ||||
| { | ||||
| #if !defined (__DJGPP__) | ||||
|   if (term_has_meta && _rl_term_mo && enabled_meta) | ||||
|     { | ||||
|       tputs (_rl_term_mo, 1, _rl_output_character_function); | ||||
|       enabled_meta = 0; | ||||
|     } | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
|  | @ -718,6 +779,7 @@ void | |||
| _rl_set_cursor (im, force) | ||||
|      int im, force; | ||||
| { | ||||
| #ifndef __MSDOS__ | ||||
|   if (_rl_term_ve && _rl_term_vs) | ||||
|     { | ||||
|       if (force || im != rl_insert_mode) | ||||
|  | @ -728,4 +790,5 @@ _rl_set_cursor (im, force) | |||
| 	    tputs (_rl_term_ve, 1, _rl_output_character_function); | ||||
| 	} | ||||
|     } | ||||
| #endif | ||||
| } | ||||
|  |  | |||
|  | @ -240,7 +240,7 @@ rl_replace_line (text, clear_undo) | |||
|    this is the same as rl_end. | ||||
| 
 | ||||
|    Any command that is called interactively receives two arguments. | ||||
|    The first is a count: the numeric arg pased to this command. | ||||
|    The first is a count: the numeric arg passed to this command. | ||||
|    The second is the key which invoked this command. | ||||
| */ | ||||
| 
 | ||||
|  | @ -826,7 +826,7 @@ _rl_insert_char (count, c) | |||
| 	 pending characters that are bound to rl_insert, and insert | ||||
| 	 them all.  Don't do this if we're current reading input from | ||||
| 	 a macro. */ | ||||
|       if ((RL_ISSTATE (RL_STATE_MACROINPUT) == 0) && _rl_any_typein ()) | ||||
|       if ((RL_ISSTATE (RL_STATE_MACROINPUT) == 0) && _rl_pushed_input_available ()) | ||||
| 	_rl_insert_typein (c); | ||||
|       else | ||||
| 	{ | ||||
|  | @ -908,6 +908,9 @@ _rl_insert_next (count) | |||
|   if (c < 0) | ||||
|     return -1; | ||||
| 
 | ||||
|   if (RL_ISSTATE (RL_STATE_MACRODEF)) | ||||
|     _rl_add_macro_char (c); | ||||
| 
 | ||||
| #if defined (HANDLE_SIGNALS) | ||||
|   if (RL_ISSTATE (RL_STATE_CALLBACK) == 0) | ||||
|     _rl_restore_tty_signals (); | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| /* readline.c -- a general facility for reading lines of input
 | ||||
|    with emacs style editing and completion. */ | ||||
| 
 | ||||
| /* Copyright (C) 1987-2009 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 1987-2012 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file is part of the GNU Readline Library (Readline), a library | ||||
|    for reading lines of text with interactive input and history editing.       | ||||
|  | @ -101,6 +101,25 @@ rl_add_undo (what, start, end, text) | |||
|   rl_undo_list = temp; | ||||
| } | ||||
| 
 | ||||
| /* Free an UNDO_LIST */ | ||||
| void | ||||
| _rl_free_undo_list (ul) | ||||
|      UNDO_LIST *ul; | ||||
| { | ||||
|   UNDO_LIST *release; | ||||
| 
 | ||||
|   while (ul) | ||||
|     { | ||||
|       release = ul; | ||||
|       ul = ul->next; | ||||
| 
 | ||||
|       if (release->what == UNDO_DELETE) | ||||
| 	xfree (release->text); | ||||
| 
 | ||||
|       xfree (release); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /* Free the existing undo list. */ | ||||
| void | ||||
| rl_free_undo_list () | ||||
|  | @ -108,16 +127,7 @@ rl_free_undo_list () | |||
|   UNDO_LIST *release, *orig_list; | ||||
| 
 | ||||
|   orig_list = rl_undo_list; | ||||
|   while (rl_undo_list) | ||||
|     { | ||||
|       release = rl_undo_list; | ||||
|       rl_undo_list = rl_undo_list->next; | ||||
| 
 | ||||
|       if (release->what == UNDO_DELETE) | ||||
| 	xfree (release->text); | ||||
| 
 | ||||
|       xfree (release); | ||||
|     } | ||||
|   _rl_free_undo_list (rl_undo_list); | ||||
|   rl_undo_list = (UNDO_LIST *)NULL; | ||||
|   replace_history_data (-1, (histdata_t *)orig_list, (histdata_t *)NULL); | ||||
| } | ||||
|  | @ -168,6 +178,7 @@ rl_do_undo () | |||
| { | ||||
|   UNDO_LIST *release; | ||||
|   int waiting_for_begin, start, end; | ||||
|   HIST_ENTRY *cur, *temp; | ||||
| 
 | ||||
| #define TRANS(i) ((i) == -1 ? rl_point : ((i) == -2 ? rl_end : (i))) | ||||
| 
 | ||||
|  | @ -222,6 +233,18 @@ rl_do_undo () | |||
| 
 | ||||
|       release = rl_undo_list; | ||||
|       rl_undo_list = rl_undo_list->next; | ||||
| 
 | ||||
|       /* If we are editing a history entry, make sure the change is replicated
 | ||||
| 	 in the history entry's line */ | ||||
|       cur = current_history (); | ||||
|       if (cur && cur->data && (UNDO_LIST *)cur->data == release) | ||||
| 	{ | ||||
| 	  temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list); | ||||
| 	  xfree (temp->line); | ||||
| 	  FREE (temp->timestamp); | ||||
| 	  xfree (temp); | ||||
| 	} | ||||
| 
 | ||||
|       replace_history_data (-1, (histdata_t *)release, (histdata_t *)rl_undo_list); | ||||
| 
 | ||||
|       xfree (release); | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| /* util.c -- readline utility functions */ | ||||
| 
 | ||||
| /* Copyright (C) 1987-2010 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 1987-2012 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file is part of the GNU Readline Library (Readline), a library | ||||
|    for reading lines of text with interactive input and history editing.       | ||||
|  | @ -108,7 +108,11 @@ _rl_abort_internal () | |||
|     _rl_pop_executing_macro (); | ||||
| 
 | ||||
|   rl_last_func = (rl_command_func_t *)NULL; | ||||
| #if defined (HAVE_POSIX_SIGSETJMP) | ||||
|   siglongjmp (_rl_top_level, 1); | ||||
| #else | ||||
|   longjmp (_rl_top_level, 1); | ||||
| #endif | ||||
|   return (0); | ||||
| } | ||||
| 
 | ||||
|  | @ -369,11 +373,13 @@ _rl_strpbrk (string1, string2) | |||
|    doesn't matter (strncasecmp). */ | ||||
| int | ||||
| _rl_strnicmp (string1, string2, count) | ||||
|      char *string1, *string2; | ||||
|      const char *string1; | ||||
|      const char *string2; | ||||
|      int count; | ||||
| { | ||||
|   register char *s1, *s2; | ||||
|   int d; | ||||
|   register const char *s1; | ||||
|   register const char *s2; | ||||
|   register int d; | ||||
| 
 | ||||
|   if (count <= 0 || (string1 == string2)) | ||||
|     return 0; | ||||
|  | @ -389,7 +395,7 @@ _rl_strnicmp (string1, string2, count) | |||
|         break; | ||||
|       s2++; | ||||
|     } | ||||
|   while (--count != 0) | ||||
|   while (--count != 0); | ||||
| 
 | ||||
|   return (0); | ||||
| } | ||||
|  | @ -397,10 +403,12 @@ _rl_strnicmp (string1, string2, count) | |||
| /* strcmp (), but caseless (strcasecmp). */ | ||||
| int | ||||
| _rl_stricmp (string1, string2) | ||||
|      char *string1, *string2; | ||||
|      const char *string1; | ||||
|      const char *string2; | ||||
| { | ||||
|   register char *s1, *s2; | ||||
|   int d; | ||||
|   register const char *s1; | ||||
|   register const char *s2; | ||||
|   register int d; | ||||
| 
 | ||||
|   s1 = string1; | ||||
|   s2 = string2; | ||||
|  | @ -507,7 +515,7 @@ _rl_tropen () | |||
| 
 | ||||
|   if (_rl_tracefp) | ||||
|     fclose (_rl_tracefp); | ||||
|   sprintf (fnbuf, "/var/tmp/rltrace.%ld", getpid()); | ||||
|   sprintf (fnbuf, "/var/tmp/rltrace.%ld", (long)getpid()); | ||||
|   unlink(fnbuf); | ||||
|   _rl_tracefp = fopen (fnbuf, "w+"); | ||||
|   return _rl_tracefp != 0; | ||||
|  | @ -523,4 +531,61 @@ _rl_trclose () | |||
|   return r; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| _rl_settracefp (fp) | ||||
|      FILE *fp; | ||||
| { | ||||
|   _rl_tracefp = fp; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| #if HAVE_DECL_AUDIT_USER_TTY && defined (ENABLE_TTY_AUDIT_SUPPORT) | ||||
| #include <sys/socket.h> | ||||
| #include <linux/audit.h> | ||||
| #include <linux/netlink.h> | ||||
| 
 | ||||
| /* Report STRING to the audit system. */ | ||||
| void | ||||
| _rl_audit_tty (string) | ||||
|      char *string; | ||||
| { | ||||
|   struct sockaddr_nl addr; | ||||
|   struct msghdr msg; | ||||
|   struct nlmsghdr nlm; | ||||
|   struct iovec iov[2]; | ||||
|   size_t size; | ||||
|   int fd; | ||||
| 
 | ||||
|   fd = socket (AF_NETLINK, SOCK_RAW, NETLINK_AUDIT); | ||||
|   if (fd < 0) | ||||
|     return; | ||||
|   size = strlen (string) + 1; | ||||
| 
 | ||||
|   nlm.nlmsg_len = NLMSG_LENGTH (size); | ||||
|   nlm.nlmsg_type = AUDIT_USER_TTY; | ||||
|   nlm.nlmsg_flags = NLM_F_REQUEST; | ||||
|   nlm.nlmsg_seq = 0; | ||||
|   nlm.nlmsg_pid = 0; | ||||
| 
 | ||||
|   iov[0].iov_base = &nlm; | ||||
|   iov[0].iov_len = sizeof (nlm); | ||||
|   iov[1].iov_base = string; | ||||
|   iov[1].iov_len = size; | ||||
| 
 | ||||
|   addr.nl_family = AF_NETLINK; | ||||
|   addr.nl_pid = 0; | ||||
|   addr.nl_groups = 0; | ||||
| 
 | ||||
|   msg.msg_name = &addr; | ||||
|   msg.msg_namelen = sizeof (addr); | ||||
|   msg.msg_iov = iov; | ||||
|   msg.msg_iovlen = 2; | ||||
|   msg.msg_control = NULL; | ||||
|   msg.msg_controllen = 0; | ||||
|   msg.msg_flags = 0; | ||||
| 
 | ||||
|   (void)sendmsg (fd, &msg, 0); | ||||
|   close (fd); | ||||
| } | ||||
| #endif | ||||
|  |  | |||
|  | @ -309,7 +309,6 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = { | |||
| #endif /* KEYMAP_SIZE > 128 */ | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| KEYMAP_ENTRY_ARRAY vi_insertion_keymap = { | ||||
|   /* The regular control keys come first. */ | ||||
|   { ISFUNC, (rl_command_func_t *)0x0 },		/* Control-@ */ | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| /* vi_mode.c -- A vi emulation mode for Bash.
 | ||||
|    Derived from code written by Jeff Sparkes (jsparkes@bnr.ca).  */ | ||||
| 
 | ||||
| /* Copyright (C) 1987-2010 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 1987-2012 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file is part of the GNU Readline Library (Readline), a library | ||||
|    for reading lines of text with interactive input and history editing.       | ||||
|  | @ -108,9 +108,13 @@ static const char * const vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~"; | |||
| /* Arrays for the saved marks. */ | ||||
| static int vi_mark_chars['z' - 'a' + 1]; | ||||
| 
 | ||||
| static void _rl_vi_replace_insert PARAMS((int)); | ||||
| static void _rl_vi_save_replace PARAMS((void)); | ||||
| static void _rl_vi_stuff_insert PARAMS((int)); | ||||
| static void _rl_vi_save_insert PARAMS((UNDO_LIST *)); | ||||
| 
 | ||||
| static void vi_save_insert_buffer PARAMS ((int, int)); | ||||
| 
 | ||||
| static void _rl_vi_backup PARAMS((void)); | ||||
| 
 | ||||
| static int _rl_vi_arg_dispatch PARAMS((int)); | ||||
|  | @ -188,6 +192,22 @@ _rl_vi_textmod_command (c) | |||
|   return (member (c, vi_textmod)); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| _rl_vi_replace_insert (count) | ||||
|      int count; | ||||
| { | ||||
|   int nchars; | ||||
| 
 | ||||
|   nchars = strlen (vi_insert_buffer); | ||||
| 
 | ||||
|   rl_begin_undo_group (); | ||||
|   while (count--) | ||||
|     /* nchars-1 to compensate for _rl_replace_text using `end+1' in call
 | ||||
|        to rl_delete_text */ | ||||
|     _rl_replace_text (vi_insert_buffer, rl_point, rl_point+nchars-1); | ||||
|   rl_end_undo_group (); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| _rl_vi_stuff_insert (count) | ||||
|      int count; | ||||
|  | @ -207,7 +227,7 @@ rl_vi_redo (count, c) | |||
| { | ||||
|   int r; | ||||
| 
 | ||||
|   if (!rl_explicit_arg) | ||||
|   if (rl_explicit_arg == 0) | ||||
|     { | ||||
|       rl_numeric_arg = _rl_vi_last_repeat; | ||||
|       rl_arg_sign = _rl_vi_last_arg_sign; | ||||
|  | @ -224,6 +244,13 @@ rl_vi_redo (count, c) | |||
|       if (rl_point > 0) | ||||
| 	_rl_vi_backup (); | ||||
|     } | ||||
|   else if (_rl_vi_last_command == 'R' && vi_insert_buffer && *vi_insert_buffer) | ||||
|     { | ||||
|       _rl_vi_replace_insert (count); | ||||
|       /* And back up point over the last character inserted. */ | ||||
|       if (rl_point > 0) | ||||
| 	_rl_vi_backup (); | ||||
|     } | ||||
|   /* Ditto for redoing an insert with `I', but move to the beginning of the
 | ||||
|      line like the `I' command does. */ | ||||
|   else if (_rl_vi_last_command == 'I' && vi_insert_buffer && *vi_insert_buffer) | ||||
|  | @ -679,6 +706,8 @@ rl_vi_insertion_mode (count, key) | |||
| { | ||||
|   _rl_keymap = vi_insertion_keymap; | ||||
|   _rl_vi_last_key_before_insert = key; | ||||
|   if (_rl_show_mode_in_prompt) | ||||
|     _rl_reset_prompt (); | ||||
|   return (0); | ||||
| } | ||||
| 
 | ||||
|  | @ -690,6 +719,43 @@ rl_vi_insert_mode (count, key) | |||
|   return (0); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| vi_save_insert_buffer (start, len) | ||||
|      int start, len; | ||||
| { | ||||
|   /* Same code as _rl_vi_save_insert below */ | ||||
|   if (len >= vi_insert_buffer_size) | ||||
|     { | ||||
|       vi_insert_buffer_size += (len + 32) - (len % 32); | ||||
|       vi_insert_buffer = (char *)xrealloc (vi_insert_buffer, vi_insert_buffer_size); | ||||
|     } | ||||
|   strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1); | ||||
|   vi_insert_buffer[len-1] = '\0'; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| _rl_vi_save_replace () | ||||
| { | ||||
|   int len, start, end; | ||||
|   UNDO_LIST *up; | ||||
| 
 | ||||
|   up = rl_undo_list; | ||||
|   if (up == 0 || up->what != UNDO_END || vi_replace_count <= 0) | ||||
|     { | ||||
|       if (vi_insert_buffer_size >= 1) | ||||
| 	vi_insert_buffer[0] = '\0'; | ||||
|       return; | ||||
|     } | ||||
|   /* Let's try it the quick and easy way for now.  This should essentially
 | ||||
|      accommodate every UNDO_INSERT and save the inserted text to | ||||
|      vi_insert_buffer */ | ||||
|   end = rl_point; | ||||
|   start = end - vi_replace_count + 1; | ||||
|   len = vi_replace_count + 1; | ||||
| 
 | ||||
|   vi_save_insert_buffer (start, len);   | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| _rl_vi_save_insert (up) | ||||
|       UNDO_LIST *up; | ||||
|  | @ -706,13 +772,8 @@ _rl_vi_save_insert (up) | |||
|   start = up->start; | ||||
|   end = up->end; | ||||
|   len = end - start + 1; | ||||
|   if (len >= vi_insert_buffer_size) | ||||
|     { | ||||
|       vi_insert_buffer_size += (len + 32) - (len % 32); | ||||
|       vi_insert_buffer = (char *)xrealloc (vi_insert_buffer, vi_insert_buffer_size); | ||||
|     } | ||||
|   strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1); | ||||
|   vi_insert_buffer[len-1] = '\0'; | ||||
| 
 | ||||
|   vi_save_insert_buffer (start, len); | ||||
| } | ||||
|      | ||||
| void | ||||
|  | @ -728,7 +789,10 @@ _rl_vi_done_inserting () | |||
| 	 on absolute indices into the line which may change (though they | ||||
| 	 probably will not). */ | ||||
|       _rl_vi_doing_insert = 0; | ||||
|       _rl_vi_save_insert (rl_undo_list->next); | ||||
|       if (_rl_vi_last_key_before_insert == 'R') | ||||
| 	_rl_vi_save_replace ();		/* Half the battle */ | ||||
|       else | ||||
| 	_rl_vi_save_insert (rl_undo_list->next); | ||||
|       vi_continued_command = 1; | ||||
|     } | ||||
|   else | ||||
|  | @ -762,6 +826,9 @@ rl_vi_movement_mode (count, key) | |||
|   if (RL_ISSTATE (RL_STATE_VICMDONCE) == 0) | ||||
|     rl_free_undo_list (); | ||||
| 
 | ||||
|   if (_rl_show_mode_in_prompt) | ||||
|     _rl_reset_prompt (); | ||||
| 
 | ||||
|   RL_SETSTATE (RL_STATE_VICMDONCE); | ||||
|   return (0); | ||||
| } | ||||
|  | @ -1940,14 +2007,20 @@ rl_vi_replace (count, key) | |||
| 
 | ||||
|   vi_replace_count = 0; | ||||
| 
 | ||||
|   if (!vi_replace_map) | ||||
|   if (vi_replace_map == 0) | ||||
|     { | ||||
|       vi_replace_map = rl_make_bare_keymap (); | ||||
| 
 | ||||
|       for (i = 0; i < ' '; i++) | ||||
| 	if (vi_insertion_keymap[i].type == ISFUNC) | ||||
| 	  vi_replace_map[i].function = vi_insertion_keymap[i].function; | ||||
| 
 | ||||
|       for (i = ' '; i < KEYMAP_SIZE; i++) | ||||
| 	vi_replace_map[i].function = rl_vi_overstrike; | ||||
| 
 | ||||
|       vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete; | ||||
| 
 | ||||
|       /* Make sure these are what we want. */ | ||||
|       vi_replace_map[ESC].function = rl_vi_movement_mode; | ||||
|       vi_replace_map[RETURN].function = rl_newline; | ||||
|       vi_replace_map[NEWLINE].function = rl_newline; | ||||
|  | @ -1960,7 +2033,12 @@ rl_vi_replace (count, key) | |||
| 	vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete; | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|   rl_vi_start_inserting (key, 1, rl_arg_sign); | ||||
| 
 | ||||
|   _rl_vi_last_key_before_insert = key; | ||||
|   _rl_keymap = vi_replace_map; | ||||
| 
 | ||||
|   return (0); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Chet Ramey
				Chet Ramey