diff options
author | Chet Ramey <chet.ramey@case.edu> | 2011-11-21 20:51:19 -0500 |
---|---|---|
committer | Chet Ramey <chet.ramey@case.edu> | 2011-11-21 20:51:19 -0500 |
commit | 0001803f0b9523c94fa2ede48eaecb047fef4524 (patch) | |
tree | f334332811e033ff966d94f6268f0629a94304b3 /lib | |
parent | 89a92869e56aba4e4cab2d639c00a86f0545c862 (diff) | |
download | android_external_bash-0001803f0b9523c94fa2ede48eaecb047fef4524.tar.gz android_external_bash-0001803f0b9523c94fa2ede48eaecb047fef4524.tar.bz2 android_external_bash-0001803f0b9523c94fa2ede48eaecb047fef4524.zip |
Bash-4.1 distribution source
Diffstat (limited to 'lib')
38 files changed, 719 insertions, 222 deletions
diff --git a/lib/glob/glob.c b/lib/glob/glob.c index 3542244..c77618f 100644 --- a/lib/glob/glob.c +++ b/lib/glob/glob.c @@ -246,7 +246,8 @@ udequote_pathname (pathname) if (pathname[i - 1] == 0) break; } - pathname[j] = '\0'; + if (pathname) + pathname[j] = '\0'; } #if HANDLE_MULTIBYTE @@ -279,7 +280,8 @@ wdequote_pathname (pathname) if (wpathname[i - 1] == L'\0') break; } - wpathname[j] = L'\0'; + if (wpathname) + wpathname[j] = L'\0'; /* Convert the wide character string into unibyte character set. */ memset (&ps, '\0', sizeof(mbstate_t)); @@ -307,9 +309,9 @@ dequote_pathname (pathname) # define GLOB_TESTNAME(name) (lstat (name, &finfo)) #else /* !HAVE_LSTAT */ # if !defined (AFS) -# define GLOB_TESTNAME(name) (sh_eaccess (nextname, F_OK)) +# define GLOB_TESTNAME(name) (sh_eaccess (name, F_OK)) # else /* AFS */ -# define GLOB_TESTNAME(name) (access (nextname, F_OK)) +# define GLOB_TESTNAME(name) (access (name, F_OK)) # endif /* AFS */ #endif /* !HAVE_LSTAT */ @@ -320,6 +322,7 @@ glob_testdir (dir) { struct stat finfo; +/*itrace("glob_testdir: testing %s", dir);*/ if (stat (dir, &finfo) < 0) return (-1); @@ -426,13 +429,14 @@ glob_vector (pat, dir, flags) register struct globval *nextlink; register char *nextname, *npat, *subdir; unsigned int count; - int lose, skip, ndirs, isdir, sdlen, add_current; + int lose, skip, ndirs, isdir, sdlen, add_current, patlen; register char **name_vector; register unsigned int i; int mflags; /* Flags passed to strmatch (). */ int pflags; /* flags passed to sh_makepath () */ int nalloca; struct globval *firstmalloc, *tmplink; + char *convfn; lastlink = 0; count = lose = skip = add_current = 0; @@ -466,6 +470,8 @@ glob_vector (pat, dir, flags) skip = 1; } + patlen = strlen (pat); + /* If the filename pattern (PAT) does not contain any globbing characters, we can dispense with reading the directory, and just see if there is a filename `DIR/PAT'. If there is, and we can access it, just make the @@ -479,8 +485,8 @@ glob_vector (pat, dir, flags) return ((char **) &glob_error_return); dirlen = strlen (dir); - nextname = (char *)malloc (dirlen + strlen (pat) + 2); - npat = (char *)malloc (strlen (pat) + 1); + nextname = (char *)malloc (dirlen + patlen + 2); + npat = (char *)malloc (patlen + 1); if (nextname == 0 || npat == 0) lose = 1; else @@ -633,8 +639,9 @@ glob_vector (pat, dir, flags) ++count; continue; } - - if (strmatch (pat, dp->d_name, mflags) != FNM_NOMATCH) + + convfn = fnx_fromfs (dp->d_name, D_NAMLEN (dp)); + if (strmatch (pat, convfn, mflags) != FNM_NOMATCH) { if (nalloca < ALLOCA_MAX) { @@ -1023,7 +1030,7 @@ glob_filename (pathname, flags) dflags |= GX_ALLDIRS|GX_ADDCURDIR; #if 0 /* If we want all directories (dflags & GX_ALLDIRS) and we're not - being called recursively as something like `echo **/*.o' + being called recursively as something like `echo [star][star]/[star].o' ((flags & GX_ALLDIRS) == 0), we want to prevent glob_vector from adding a null directory name to the front of the temp_results array. We turn off ADDCURDIR if not called recursively and diff --git a/lib/readline/bind.c b/lib/readline/bind.c index 836f837..fc8c2a2 100644 --- a/lib/readline/bind.c +++ b/lib/readline/bind.c @@ -418,6 +418,13 @@ rl_generic_bind (type, keyseq, data, map) { map = FUNCTION_TO_KEYMAP (map, ic); ic = ANYOTHERKEY; + /* If we're trying to override a keymap with a null function + (e.g., trying to unbind it), we can't use a null pointer + here because that's indistinguishable from having not been + overridden. We use a special bindable function that does + nothing. */ + if (type == ISFUNC && data == 0) + data = (char *)_rl_null_function; } map[ic].function = KEYMAP_TO_FUNCTION (data); @@ -1419,7 +1426,9 @@ static const struct { { "completion-ignore-case", &_rl_completion_case_fold, 0 }, { "convert-meta", &_rl_convert_meta_chars_to_ascii, 0 }, { "disable-completion", &rl_inhibit_completion, 0 }, + { "echo-control-characters", &_rl_echo_control_chars, 0 }, { "enable-keypad", &_rl_enable_keypad, 0 }, + { "enable-meta-key", &_rl_enable_meta, 0 }, { "expand-tilde", &rl_complete_with_tilde_expansion, 0 }, { "history-preserve-point", &_rl_history_preserve_point, 0 }, { "horizontal-scroll-mode", &_rl_horizontal_scroll_mode, 0 }, @@ -1436,6 +1445,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 }, + { "skip-completed-text", &_rl_skip_completed_text, 0 }, #if defined (VISIBLE_STATS) { "visible-stats", &rl_visible_stats, 0 }, #endif /* VISIBLE_STATS */ diff --git a/lib/readline/complete.c b/lib/readline/complete.c index 59b486a..ad9ca05 100644 --- a/lib/readline/complete.c +++ b/lib/readline/complete.c @@ -179,6 +179,12 @@ int _rl_completion_prefix_display_length = 0; int rl_visible_stats = 0; #endif /* VISIBLE_STATS */ +/* 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 + after the `e' in `Makefile' won't result in `Makefilefile'. */ +int _rl_skip_completed_text = 0; + /* If non-zero, then this is the address of a function to call when completing on a directory name. The function is called with the address of a string (the current directory name) as an arg. */ @@ -186,6 +192,17 @@ rl_icppfunc_t *rl_directory_completion_hook = (rl_icppfunc_t *)NULL; rl_icppfunc_t *rl_directory_rewrite_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 + either return its first argument (if no conversion takes place) or + newly-allocated memory. This can, for instance, convert filenames + between character sets for comparison against what's typed at the + keyboard. The returned value is what is added to the list of + matches. The second argument is the length of the filename to be + converted. */ +rl_dequote_func_t *rl_filename_rewrite_hook = (rl_dequote_func_t *)NULL; + /* Non-zero means readline completion functions perform tilde expansion. */ int rl_complete_with_tilde_expansion = 0; @@ -1021,7 +1038,8 @@ gen_completion_matches (text, start, end, our_func, found_quote, quote_char) { _rl_interrupt_immediately++; matches = (*rl_attempted_completion_function) (text, start, end); - _rl_interrupt_immediately--; + if (_rl_interrupt_immediately > 0) + _rl_interrupt_immediately--; if (matches || rl_attempted_completion_over) { @@ -1551,8 +1569,9 @@ insert_match (match, start, mtype, qc) int start, mtype; char *qc; { - char *replacement; + char *replacement, *r; char oqc; + int end, rlen; oqc = qc ? *qc : '\0'; replacement = make_quoted_replacement (match, mtype, qc); @@ -1560,6 +1579,7 @@ insert_match (match, start, mtype, qc) /* Now insert the match. */ if (replacement) { + rlen = strlen (replacement); /* Don't double an opening quote character. */ if (qc && *qc && start && rl_line_buffer[start - 1] == *qc && replacement[0] == *qc) @@ -1569,7 +1589,24 @@ insert_match (match, start, mtype, qc) else if (qc && (*qc != oqc) && start && rl_line_buffer[start - 1] == oqc && replacement[0] != oqc) start--; - _rl_replace_text (replacement, start, rl_point - 1); + end = rl_point - 1; + /* Don't double a closing quote character */ + if (qc && *qc && end && rl_line_buffer[rl_point] == *qc && replacement[rlen - 1] == *qc) + end++; + if (_rl_skip_completed_text) + { + r = replacement; + while (start < rl_end && *r && rl_line_buffer[start] == *r) + { + start++; + r++; + } + if (start <= end || *r) + _rl_replace_text (r, start, end); + rl_point = start + strlen (r); + } + else + _rl_replace_text (replacement, start, end); if (replacement != match) free (replacement); } @@ -1893,7 +1930,8 @@ rl_completion_matches (text, entry_function) match_list[++matches] = string; match_list[matches + 1] = (char *)NULL; } - _rl_interrupt_immediately--; + 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]. */ @@ -1981,8 +2019,8 @@ rl_filename_completion_function (text, state) static char *dirname = (char *)NULL; static char *users_dirname = (char *)NULL; static int filename_len; - char *temp; - int dirlen; + char *temp, *dentry, *convfn; + int dirlen, dentlen, convlen; struct dirent *entry; /* If we don't have any state, then do some initialization. */ @@ -2086,6 +2124,15 @@ rl_filename_completion_function (text, state) entry = (struct dirent *)NULL; while (directory && (entry = readdir (directory))) { + convfn = dentry = entry->d_name; + convlen = dentlen = D_NAMLEN (entry); + + if (rl_filename_rewrite_hook) + { + convfn = (*rl_filename_rewrite_hook) (dentry, dentlen); + convlen = (convfn == dentry) ? dentlen : strlen (convfn); + } + /* Special case for no filename. If the user has disabled the `match-hidden-files' variable, skip filenames beginning with `.'. All other entries except "." and ".." match. */ @@ -2094,9 +2141,8 @@ rl_filename_completion_function (text, state) if (_rl_match_hidden_files == 0 && HIDDEN_FILE (entry->d_name)) continue; - if (entry->d_name[0] != '.' || - (entry->d_name[1] && - (entry->d_name[1] != '.' || entry->d_name[2]))) + if (convfn[0] != '.' || + (convfn[1] && (convfn[1] != '.' || convfn[2]))) break; } else @@ -2105,16 +2151,16 @@ rl_filename_completion_function (text, state) it is a match. */ if (_rl_completion_case_fold) { - if ((_rl_to_lower (entry->d_name[0]) == _rl_to_lower (filename[0])) && - (((int)D_NAMLEN (entry)) >= filename_len) && - (_rl_strnicmp (filename, entry->d_name, filename_len) == 0)) + if ((_rl_to_lower (convfn[0]) == _rl_to_lower (filename[0])) && + (convlen >= filename_len) && + (_rl_strnicmp (filename, convfn, filename_len) == 0)) break; } else { - if ((entry->d_name[0] == filename[0]) && - (((int)D_NAMLEN (entry)) >= filename_len) && - (strncmp (filename, entry->d_name, filename_len) == 0)) + if ((convfn[0] == filename[0]) && + (convlen >= filename_len) && + (strncmp (filename, convfn, filename_len) == 0)) break; } } @@ -2176,19 +2222,22 @@ rl_filename_completion_function (text, state) strcpy (temp + dirlen, entry->d_name); } else - temp = savestring (entry->d_name); + temp = savestring (convfn); + + if (convfn != dentry) + free (convfn); return (temp); } } /* An initial implementation of a menu completion function a la tcsh. The - first time (if the last readline command was not rl_menu_complete), we + first time (if the last readline command was not rl_old_menu_complete), we generate the list of matches. This code is very similar to the code in rl_complete_internal -- there should be a way to combine the two. Then, for each item in the list of matches, we insert the match in an undoable fashion, with the appropriate character appended (this happens on the - second and subsequent consecutive calls to rl_menu_complete). When we + second and subsequent consecutive calls to rl_old_menu_complete). When we hit the end of the match list, we restore the original unmatched text, ring the bell, and reset the counter to zero. */ int @@ -2330,7 +2379,7 @@ rl_menu_complete (count, ignore) /* The first time through, we generate the list of matches and set things up to insert them. */ - if (rl_last_func != rl_menu_complete || full_completion) + if ((rl_last_func != rl_menu_complete && rl_last_func != rl_backward_menu_complete) || full_completion) { /* Clean up from previous call, if any. */ FREE (orig_text); @@ -2470,3 +2519,12 @@ rl_menu_complete (count, ignore) completion_changed_buffer = 1; return (0); } + +int +rl_backward_menu_complete (count, key) + int count, key; +{ + /* Positive arguments to backward-menu-complete translate into negative + arguments for menu-complete, and vice versa. */ + return (rl_menu_complete (-count, key)); +} diff --git a/lib/readline/display.c b/lib/readline/display.c index c58d4f7..e4105ee 100644 --- a/lib/readline/display.c +++ b/lib/readline/display.c @@ -94,9 +94,9 @@ static int line_structures_initialized = 0; #define invisible_line (line_state_invisible->line) #if defined (HANDLE_MULTIBYTE) -static int _rl_col_width PARAMS((const char *, int, int)); +static int _rl_col_width PARAMS((const char *, int, int, int)); #else -# define _rl_col_width(l, s, e) (((e) <= (s)) ? 0 : (e) - (s)) +# define _rl_col_width(l, s, e, f) (((e) <= (s)) ? 0 : (e) - (s)) #endif /* Heuristic used to decide whether it is faster to move from CUR to NEW @@ -312,7 +312,7 @@ expand_prompt (pmt, lp, lip, niflp, vlp) not be the same as the number of physical characters on the screen in the presence of multibyte characters */ rl += ind - pind; - physchars += _rl_col_width (pmt, pind, ind); + physchars += _rl_col_width (pmt, pind, ind, 0); } else ninvis += ind - pind; @@ -688,7 +688,7 @@ rl_redisplay () temp = local_prompt_len; while (num < temp) { - z = _rl_col_width (local_prompt, n0, num); + z = _rl_col_width (local_prompt, n0, num, 1); if (z > _rl_screenwidth) { num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY); @@ -714,7 +714,7 @@ rl_redisplay () inv_lbreaks[++newlines] = temp; #if defined (HANDLE_MULTIBYTE) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0) - lpos -= _rl_col_width (local_prompt, n0, num); + lpos -= _rl_col_width (local_prompt, n0, num, 1); else #endif lpos -= _rl_screenwidth; @@ -733,6 +733,7 @@ rl_redisplay () if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) { memset (&ps, 0, sizeof (mbstate_t)); + /* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */ wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps); } else @@ -893,6 +894,7 @@ rl_redisplay () if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) { in += wc_bytes; + /* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */ wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps); } else @@ -958,6 +960,11 @@ rl_redisplay () #define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line) #define INV_LINE(line) (invisible_line + inv_lbreaks[line]) +#define OLD_CPOS_IN_PROMPT() (cpos_adjusted == 0 && \ + _rl_last_c_pos != o_cpos && \ + _rl_last_c_pos > wrap_offset && \ + o_cpos < prompt_last_invisible) + /* For each line in the buffer, do the updating display. */ for (linenum = 0; linenum <= inv_botlin; linenum++) { @@ -980,11 +987,7 @@ rl_redisplay () time update_line is called, then we can assume in our calculations that o_cpos does not need to be adjusted by wrap_offset. */ - if (linenum == 0 && (MB_CUR_MAX > 1 && rl_byte_oriented == 0) && - cpos_adjusted == 0 && - _rl_last_c_pos != o_cpos && - _rl_last_c_pos > wrap_offset && - o_cpos < prompt_last_invisible) + if (linenum == 0 && (MB_CUR_MAX > 1 && rl_byte_oriented == 0) && OLD_CPOS_IN_PROMPT()) _rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */ else if (linenum == prompt_last_screen_line && prompt_physical_chars > _rl_screenwidth && (MB_CUR_MAX > 1 && rl_byte_oriented == 0) && @@ -1084,7 +1087,7 @@ rl_redisplay () _rl_output_some_chars (local_prompt, nleft); if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - _rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft) - wrap_offset + modmark; + _rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft, 1) - wrap_offset + modmark; else _rl_last_c_pos = nleft + modmark; } @@ -1108,7 +1111,7 @@ rl_redisplay () { /* TX == new physical cursor position in multibyte locale. */ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - tx = _rl_col_width (&visible_line[pos], 0, nleft) - visible_wrap_offset; + tx = _rl_col_width (&visible_line[pos], 0, nleft, 1) - visible_wrap_offset; else tx = nleft; if (tx >= 0 && _rl_last_c_pos > tx) @@ -1201,12 +1204,8 @@ rl_redisplay () _rl_screenwidth + (lmargin ? 0 : wrap_offset), 0); - if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && - cpos_adjusted == 0 && - _rl_last_c_pos != o_cpos && - _rl_last_c_pos > wrap_offset && - o_cpos < prompt_last_invisible) - _rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */ + if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && 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 of invisible characters is greater, and we are at the end of @@ -1320,7 +1319,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) if (tempwidth > 0) { - int count; + int count, i; bytes = ret; for (count = 0; count < bytes; count++) putc (new[count], rl_outstream); @@ -1331,10 +1330,13 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) if (ret != 0 && bytes != 0) { if (MB_INVALIDCH (ret)) - memmove (old+bytes, old+1, strlen (old+1)); - else - memmove (old+bytes, old+ret, strlen (old+ret)); + ret = 1; + memmove (old+bytes, old+ret, strlen (old+ret)); 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++) + vis_lbreaks[i] += bytes - ret; } } else @@ -1528,7 +1530,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) { /* We take wrap_offset into account here so we can pass correct information to _rl_move_cursor_relative. */ - _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff) - wrap_offset + modmark; + _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff, 1) - wrap_offset + modmark; cpos_adjusted = 1; } else @@ -1559,7 +1561,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) When not using multibyte characters, these are equal */ lendiff = (nls - nfd) - (ols - ofd); if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - col_lendiff = _rl_col_width (new, nfd - new, nls - new) - _rl_col_width (old, ofd - old, ols - old); + col_lendiff = _rl_col_width (new, nfd - new, nls - new, 1) - _rl_col_width (old, ofd - old, ols - old, 1); else col_lendiff = lendiff; @@ -1584,7 +1586,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) /* Insert (diff (len (old), len (new)) ch. */ temp = ne - nfd; if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - col_temp = _rl_col_width (new, nfd - new, ne - new); + col_temp = _rl_col_width (new, nfd - new, ne - new, 1); else col_temp = temp; @@ -1601,7 +1603,7 @@ 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); + _rl_last_c_pos += _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. */ @@ -1679,7 +1681,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) 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); + twidth = _rl_col_width (nfd+lendiff, 0, temp-col_lendiff, 1); else twidth = temp - lendiff; _rl_last_c_pos += twidth; @@ -1738,7 +1740,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) _rl_output_some_chars (nfd, temp); if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) { - _rl_last_c_pos += _rl_col_width (nfd, 0, temp); + _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 -= wrap_offset; @@ -1771,7 +1773,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) } lendiff = (oe - old) - (ne - new); if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - col_lendiff = _rl_col_width (old, 0, oe - old) - _rl_col_width (new, 0, ne - new); + col_lendiff = _rl_col_width (old, 0, oe - old, 1) - _rl_col_width (new, 0, ne - new, 1); else col_lendiff = lendiff; @@ -1838,7 +1840,7 @@ rl_on_new_line_with_prompt () l = strlen (prompt_last_line); if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l); /* XXX */ + _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l, 1); /* XXX */ else _rl_last_c_pos = l; @@ -1900,6 +1902,7 @@ _rl_move_cursor_relative (new, data) register int i; int woff; /* number of invisible chars on current line */ int cpos, dpos; /* current and desired cursor positions */ + int adjust; woff = WRAP_OFFSET (_rl_last_v_pos, wrap_offset); cpos = _rl_last_c_pos; @@ -1915,15 +1918,34 @@ _rl_move_cursor_relative (new, data) as long as we are past them and they are counted by _rl_col_width. */ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) { - dpos = _rl_col_width (data, 0, new); + adjust = 1; + /* Try to short-circuit common cases and eliminate a bunch of multibyte + character function calls. */ + /* 1. prompt string */ + if (new == local_prompt_len && memcmp (data, local_prompt, new) == 0) + { + dpos = prompt_physical_chars; + cpos_adjusted = 1; + adjust = 0; + } + /* 2. prompt_string + line contents */ + else if (new > local_prompt_len && local_prompt && memcmp (data, local_prompt, local_prompt_len) == 0) + { + dpos = prompt_physical_chars + _rl_col_width (data, local_prompt_len, new, 1); + cpos_adjusted = 1; + adjust = 0; + } + else + dpos = _rl_col_width (data, 0, new, 1); + /* 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. */ - if ((new > prompt_last_invisible) || /* XXX - don't use woff here */ + if (adjust && ((new > prompt_last_invisible) || /* XXX - don't use woff here */ (prompt_physical_chars >= _rl_screenwidth && _rl_last_v_pos == prompt_last_screen_line && wrap_offset >= woff && dpos >= woff && - new > (prompt_last_invisible-(_rl_screenwidth*_rl_last_v_pos)-wrap_offset))) + new > (prompt_last_invisible-(_rl_screenwidth*_rl_last_v_pos)-wrap_offset)))) /* XXX last comparison might need to be >= */ { dpos -= woff; @@ -2566,9 +2588,9 @@ _rl_current_display_line () In the case of multibyte characters with stateful encoding, we have to scan from the beginning of the string to take the state into account. */ static int -_rl_col_width (str, start, end) +_rl_col_width (str, start, end, flags) const char *str; - int start, end; + int start, end, flags; { wchar_t wc; mbstate_t ps; @@ -2587,6 +2609,20 @@ _rl_ttymsg ("_rl_col_width: called with MB_CUR_MAX == 1"); point = 0; max = end; + /* Try to short-circuit common cases. The adjustment to remove wrap_offset + is done by the caller. */ + /* 1. prompt string */ + if (flags && start == 0 && end == local_prompt_len && memcmp (str, local_prompt, local_prompt_len) == 0) + return (prompt_physical_chars + wrap_offset); + /* 2. prompt string + line contents */ + else if (flags && start == 0 && local_prompt_len > 0 && end > local_prompt_len && local_prompt && memcmp (str, local_prompt, local_prompt_len) == 0) + { + tmp = prompt_physical_chars + wrap_offset; + /* XXX - try to call ourselves recursively with non-prompt portion */ + tmp += _rl_col_width (str, local_prompt_len, end, flags); + return (tmp); + } + while (point < start) { tmp = mbrlen (str + point, max, &ps); diff --git a/lib/readline/doc/fdl.texi b/lib/readline/doc/fdl.texi index 96ce74e..8805f1a 100644 --- a/lib/readline/doc/fdl.texi +++ b/lib/readline/doc/fdl.texi @@ -1,12 +1,12 @@ @c The GNU Free Documentation License. -@center Version 1.2, November 2002 +@center Version 1.3, 3 November 2008 @c This file is intended to be included within another document, @c hence no sectioning command or @node. @display -Copyright @copyright{} 2000,2001,2002 Free Software Foundation, Inc. -51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA +Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. +@uref{http://fsf.org/} Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -111,6 +111,9 @@ formats which do not have any title page as such, ``Title Page'' means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text. +The ``publisher'' means any person or entity that distributes copies +of the Document to the public. + A section ``Entitled XYZ'' means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a @@ -379,13 +382,30 @@ title. @item TERMINATION -You may not copy, modify, sublicense, or distribute the Document except -as expressly provided for under this License. Any other attempt to -copy, modify, sublicense or distribute the Document is void, and will -automatically terminate your rights under this License. However, -parties who have received copies, or rights, from you under this -License will not have their licenses terminated so long as such -parties remain in full compliance. +You may not copy, modify, sublicense, or distribute the Document +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense, or distribute it is void, and +will automatically terminate your rights under this License. + +However, if you cease all violation of this License, then your license +from a particular copyright holder is reinstated (a) provisionally, +unless and until the copyright holder explicitly and finally +terminates your license, and (b) permanently, if the copyright holder +fails to notify you of the violation by some reasonable means prior to +60 days after the cessation. + +Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + +Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, receipt of a copy of some or all of the same material does +not give you any rights to use it. @item FUTURE REVISIONS OF THIS LICENSE @@ -403,7 +423,42 @@ following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not -as a draft) by the Free Software Foundation. +as a draft) by the Free Software Foundation. If the Document +specifies that a proxy can decide which future versions of this +License can be used, that proxy's public statement of acceptance of a +version permanently authorizes you to choose that version for the +Document. + +@item +RELICENSING + +``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any +World Wide Web server that publishes copyrightable works and also +provides prominent facilities for anybody to edit those works. A +public wiki that anybody can edit is an example of such a server. A +``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the +site means any set of copyrightable works thus published on the MMC +site. + +``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0 +license published by Creative Commons Corporation, a not-for-profit +corporation with a principal place of business in San Francisco, +California, as well as future copyleft versions of that license +published by that same organization. + +``Incorporate'' means to publish or republish a Document, in whole or +in part, as part of another Document. + +An MMC is ``eligible for relicensing'' if it is licensed under this +License, and if all works that were first published under this License +somewhere other than this MMC, and subsequently incorporated in whole +or in part into the MMC, (1) had no cover texts or invariant sections, +and (2) were thus incorporated prior to November 1, 2008. + +The operator of an MMC Site may republish an MMC contained in the site +under CC-BY-SA on the same site at any time before August 1, 2009, +provided the MMC is eligible for relicensing. + @end enumerate @page @@ -417,7 +472,7 @@ license notices just after the title page: @group Copyright (C) @var{year} @var{your name}. Permission is granted to copy, distribute and/or modify this document - under the terms of the GNU Free Documentation License, Version 1.2 + 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, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled ``GNU diff --git a/lib/readline/doc/history.texi b/lib/readline/doc/history.texi index 81ee8b1..afdb901 100644 --- a/lib/readline/doc/history.texi +++ b/lib/readline/doc/history.texi @@ -20,7 +20,7 @@ are preserved on all copies. @quotation Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.2 or +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 diff --git a/lib/readline/doc/rlman.texi b/lib/readline/doc/rlman.texi index fa3dd77..be24709 100644 --- a/lib/readline/doc/rlman.texi +++ b/lib/readline/doc/rlman.texi @@ -21,7 +21,7 @@ are preserved on all copies. @quotation Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.2 or +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 diff --git a/lib/readline/doc/rltech.texi b/lib/readline/doc/rltech.texi index c98d3b9..04c8489 100644 --- a/lib/readline/doc/rltech.texi +++ b/lib/readline/doc/rltech.texi @@ -622,7 +622,7 @@ Readline which keymap to use. @deftypefun Keymap rl_make_bare_keymap (void) Returns a new, empty keymap. The space for the keymap is allocated with @code{malloc()}; the caller should free it by calling -@code{rl_discard_keymap()} when done. +@code{rl_free_keymap()} when done. @end deftypefun @deftypefun Keymap rl_copy_keymap (Keymap map) @@ -636,7 +636,13 @@ the Meta digits bound to produce numeric arguments. @end deftypefun @deftypefun void rl_discard_keymap (Keymap keymap) -Free the storage associated with @var{keymap}. +Free the storage associated with the data in @var{keymap}. +The caller should free @var{keymap}. +@end deftypefun + +@deftypefun void rl_free_keymap (Keymap keymap) +Free all storage associated with @var{keymap}. This calls +@code{rl_discard_keymap} to free subordindate keymaps and macros. @end deftypefun Readline has several internal keymaps. These functions allow you to @@ -1722,6 +1728,35 @@ remove any quote characters from the directory name, because its result will be passed directly to @code{opendir()}. @end deftypevar +@ignore +@deftypevar extern 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. + +I'm not happy with how this worksyet, so it's undocumented. +@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 +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, +and @var{fnlen}, its length in bytes. +It must either return its first argument (if no conversion takes place) +or the converted filename in newly-allocated memory. The converted +form is used to compare against the word to be completed, and, if it +matches, is added to the list of matches. Readline will free the +allocated string. +@end deftypevar + @deftypevar {rl_compdisp_func_t *} rl_completion_display_matches_hook If non-zero, then this is the address of a function to call when completing a word would normally display the list of possible matches. diff --git a/lib/readline/doc/rluser.texi b/lib/readline/doc/rluser.texi index 4a367ed..519c0de 100644 --- a/lib/readline/doc/rluser.texi +++ b/lib/readline/doc/rluser.texi @@ -474,12 +474,23 @@ key bindings is used. By default, Readline starts up in Emacs editing mode, where the keystrokes are most similar to Emacs. This variable can be set to either @samp{emacs} or @samp{vi}. +@item echo-control-characters +When set to @samp{on}, on operating systems that indicate they support it, +readline echoes a character corresponding to a signal generated from the +keyboard. The default is @samp{on}. + @item enable-keypad @vindex enable-keypad When set to @samp{on}, Readline will try to enable the application keypad when it is called. Some systems need this to enable the arrow keys. The default is @samp{off}. +@item enable-meta-key +When set to @samp{on}, Readline will try to enable any meta modifier +key the terminal claims to support when it is called. On many terminals, +the meta key is used to send eight-bit characters. +The default is @samp{on}. + @item expand-tilde @vindex expand-tilde If set to @samp{on}, tilde expansion is performed when Readline @@ -606,6 +617,20 @@ a common prefix) cause the matches to be listed immediately instead of ringing the bell. 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 +inserting a single match into the line. It's only active when +performing completion in the middle of a word. If enabled, readline +does not insert characters from the completion that match characters +after point in the word being completed, so portions of the word +following the cursor are not duplicated. +For instance, if this is enabled, attempting completion when the cursor +is after the @samp{e} in @samp{Makefile} will result in @samp{Makefile} +rather than @samp{Makefilefile}, assuming there is a single possible +completion. +The default value is @samp{off}. + @item visible-stats @vindex visible-stats If set to @samp{on}, a character denoting a file's type @@ -1292,6 +1317,11 @@ through the list. This command is intended to be bound to @key{TAB}, but is unbound by default. +@item menu-complete-backward () +Identical to @code{menu-complete}, but moves backward through the list +of possible completions, as if @code{menu-complete} had been given a +negative argument. + @item delete-char-or-list () Deletes the character under the cursor if not at the beginning or end of the line (like @code{delete-char}). @@ -1431,6 +1461,15 @@ A character is read and point is moved to the previous occurrence of that character. A negative count searches for subsequent occurrences. +@item skip-csi-sequence () +Read enough characters to consume a multi-key sequence such as those +defined for keys like Home and End. Such sequences begin with a +Control Sequence Indicator (CSI), usually ESC-[. If this sequence is +bound to "\e[", keys producing such sequences will have no effect +unless explicitly bound to a readline command, instead of inserting +stray characters into the editing buffer. This is unbound by default, +but usually bound to ESC-[. + @item insert-comment (M-#) Without a numeric argument, the value of the @code{comment-begin} variable is inserted at the beginning of the current line. @@ -1574,10 +1613,15 @@ the programmable completion facilities are invoked. First, the command name is identified. If a compspec has been defined for that command, the compspec is used to generate the list of possible completions for the word. +If the command word is the empty string (completion attempted at the +beginning of an empty line), any compspec defined with +the @option{-E} option to @code{complete} is used. If the command word is a full pathname, a compspec for the full pathname is searched for first. If no compspec is found for the full pathname, an attempt is made to find a compspec for the portion following the final slash. +If those searches do not result in a compspec, any compspec defined with +the @option{-D} option to @code{complete} is used as the default. Once a compspec has been found, it is used to generate the list of matching words. @@ -1681,6 +1725,30 @@ to completed names which are symbolic links to directories, subject to the value of the @var{mark-directories} Readline variable, regardless of the setting of the @var{mark-symlinked-directories} Readline variable. +There is some support for dynamically modifying completions. This is +most useful when used in combination with a default completion specified +with @option{-D}. It's possible for shell functions executed as completion +handlers to indicate that completion should be retried by returning an +exit status of 124. If a shell function returns 124, and changes +the compspec associated with the command on which completion is being +attempted (supplied as the first argument when the function is executed), +programmable completion restarts from the beginning, with an +attempt to find a compspec for that command. This allows a set of +completions to be built dynamically as completion is attempted, rather than +being loaded all at once. + +For instance, assuming that there is a library of compspecs, each kept in a +file corresponding to the name of the command, the following default +completion function would load completions dynamically: + +@example +_completion_loader() +@{ + . "/etc/bash_completion.d/$1.sh" >/dev/null 2>&1 && return 124 +@} +complete -D -F _completion_loader +@end example + @node Programmable Completion Builtins @section Programmable Completion Builtins @cindex completion builtins @@ -1716,10 +1784,10 @@ matches were generated. @item complete @btindex complete @example -@code{complete [-abcdefgjksuv] [-o @var{comp-option}] [-E] [-A @var{action}] [-G @var{globpat}] [-W @var{wordlist}] +@code{complete [-abcdefgjksuv] [-o @var{comp-option}] [-DE] [-A @var{action}] [-G @var{globpat}] [-W @var{wordlist}] [-F @var{function}] [-C @var{command}] [-X @var{filterpat}] [-P @var{prefix}] [-S @var{suffix}] @var{name} [@var{name} @dots{}]} -@code{complete -pr [-E] [@var{name} @dots{}]} +@code{complete -pr [-DE] [@var{name} @dots{}]} @end example Specify how arguments to each @var{name} should be completed. @@ -1729,12 +1797,16 @@ reused as input. The @option{-r} option removes a completion specification for each @var{name}, or, if no @var{name}s are supplied, all completion specifications. +The @option{-D} option indicates that the remaining options and actions should +apply to the ``default'' command completion; that is, completion attempted +on a command for which no completion has previously been defined. The @option{-E} option indicates that the remaining options and actions should apply to ``empty'' command completion; that is, completion attempted on a blank line. The process of applying these completion specifications when word completion -is attempted is described above (@pxref{Programmable Completion}). +is attempted is described above (@pxref{Programmable Completion}). The +@option{-D} option takes precedence over @option{-E}. Other options, if specified, have the following meanings. The arguments to the @option{-G}, @option{-W}, and @option{-X} options @@ -1908,7 +1980,7 @@ an error occurs adding a completion specification. @item compopt @btindex compopt @example -@code{compopt} [-o @var{option}] [+o @var{option}] [@var{name}] +@code{compopt} [-o @var{option}] [-DE] [+o @var{option}] [@var{name}] @end example Modify completion options for each @var{name} according to the @var{option}s, or for the currently-execution completion if no @var{name}s @@ -1917,6 +1989,14 @@ If no @var{option}s are given, display the completion options for each @var{name} or the current completion. The possible values of @var{option} are those valid for the @code{complete} builtin described above. +The @option{-D} option indicates that the remaining options should +apply to the ``default'' command completion; that is, completion attempted +on a command for which no completion has previously been defined. +The @option{-E} option indicates that the remaining options should +apply to ``empty'' command completion; that is, completion attempted on a +blank line. + +The @option{-D} option takes precedence over @option{-E}. The return value is true unless an invalid option is supplied, an attempt is made to modify the options for a @var{name} for which no completion diff --git a/lib/readline/doc/rluserman.texi b/lib/readline/doc/rluserman.texi index a473aa2..49d9a2c 100644 --- a/lib/readline/doc/rluserman.texi +++ b/lib/readline/doc/rluserman.texi @@ -20,7 +20,7 @@ are preserved on all copies. @quotation Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.2 or +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 diff --git a/lib/readline/doc/version.texi b/lib/readline/doc/version.texi index 913a62e..823b3ba 100644 --- a/lib/readline/doc/version.texi +++ b/lib/readline/doc/version.texi @@ -2,9 +2,9 @@ Copyright (C) 1988-2009 Free Software Foundation, Inc. @end ignore -@set EDITION 6.0 -@set VERSION 6.0 -@set UPDATED 28 October 2008 -@set UPDATED-MONTH October 2008 +@set EDITION 6.1 +@set VERSION 6.1 +@set UPDATED 9 October 2009 +@set UPDATED-MONTH October 2009 -@set LASTCHANGE Tue Oct 28 11:25:24 EDT 2008 +@set LASTCHANGE Fri Oct 9 12:57:58 EDT 2009 diff --git a/lib/readline/funmap.c b/lib/readline/funmap.c index 06d2b92..cccddb6 100644 --- a/lib/readline/funmap.c +++ b/lib/readline/funmap.c @@ -105,11 +105,13 @@ static const FUNMAP default_funmap[] = { { "kill-region", rl_kill_region }, { "kill-word", rl_kill_word }, { "menu-complete", rl_menu_complete }, + { "menu-complete-backward", rl_backward_menu_complete }, { "next-history", rl_get_next_history }, { "non-incremental-forward-search-history", rl_noninc_forward_search }, { "non-incremental-reverse-search-history", rl_noninc_reverse_search }, { "non-incremental-forward-search-history-again", rl_noninc_forward_search_again }, { "non-incremental-reverse-search-history-again", rl_noninc_reverse_search_again }, + { "old-menu-complete", rl_old_menu_complete }, { "overwrite-mode", rl_overwrite_mode }, #ifdef __CYGWIN__ { "paste-from-clipboard", rl_paste_from_clipboard }, @@ -123,6 +125,7 @@ static const FUNMAP default_funmap[] = { { "revert-line", rl_revert_line }, { "self-insert", rl_insert }, { "set-mark", rl_set_mark }, + { "skip-csi-sequence", rl_skip_csi_sequence }, { "start-kbd-macro", rl_start_kbd_macro }, { "tab-insert", rl_tab_insert }, { "tilde-expand", rl_tilde_expand }, diff --git a/lib/readline/histexpand.c b/lib/readline/histexpand.c index bf5ac0e..42498d2 100644 --- a/lib/readline/histexpand.c +++ b/lib/readline/histexpand.c @@ -305,16 +305,20 @@ get_history_event (string, caller_index, delimiting_quote) /* Extract the contents of STRING as if it is enclosed in single quotes. SINDEX, when passed in, is the offset of the character immediately following the opening single quote; on exit, SINDEX is left pointing - to the closing single quote. */ + to the closing single quote. FLAGS currently used to allow backslash + to escape a single quote (e.g., for bash $'...'). */ static void -hist_string_extract_single_quoted (string, sindex) +hist_string_extract_single_quoted (string, sindex, flags) char *string; - int *sindex; + int *sindex, flags; { register int i; for (i = *sindex; string[i] && string[i] != '\''; i++) - ; + { + if ((flags & 1) && string[i] == '\\' && string[i+1]) + i++; + } *sindex = i; } @@ -924,7 +928,7 @@ history_expand (hstring, output) char **output; { register int j; - int i, r, l, passc, cc, modified, eindex, only_printing, dquote; + int i, r, l, passc, cc, modified, eindex, only_printing, dquote, flag; char *string; /* The output string, and its length. */ @@ -1044,8 +1048,9 @@ history_expand (hstring, output) else if (dquote == 0 && history_quotes_inhibit_expansion && string[i] == '\'') { /* If this is bash, single quotes inhibit history expansion. */ + flag = (i > 0 && string[i - 1] == '$'); i++; - hist_string_extract_single_quoted (string, &i); + hist_string_extract_single_quoted (string, &i, flag); } else if (history_quotes_inhibit_expansion && string[i] == '\\') { @@ -1096,7 +1101,7 @@ history_expand (hstring, output) if (strlen (mb) > 1) { ADD_STRING (mb); - break; + continue; } } #endif /* HANDLE_MULTIBYTE */ @@ -1130,8 +1135,9 @@ history_expand (hstring, output) { int quote, slen; + flag = (i > 0 && string[i - 1] == '$'); quote = i++; - hist_string_extract_single_quoted (string, &i); + hist_string_extract_single_quoted (string, &i, flag); slen = i - quote + 2; temp = (char *)xmalloc (slen); @@ -1435,17 +1441,21 @@ history_tokenize_word (string, ind) i += 2; return i; } - else + else if ((peek == '&' && (string[i] == '>' || string[i] == '<')) || + (peek == '>' && string[i] == '&') || + (peek == '(' && (string[i] == '>' || string[i] == '<')) || /* ) */ + (peek == '(' && string[i] == '$')) /* ) */ { - if ((peek == '&' && (string[i] == '>' || string[i] == '<')) || - (peek == '>' && string[i] == '&') || - (peek == '(' && (string[i] == '>' || string[i] == '<')) || /* ) */ - (peek == '(' && string[i] == '$')) /* ) */ - { - i += 2; - return i; - } + i += 2; + return i; } +#if 0 + else if (peek == '\'' && string[i] == '$') + { + i += 2; /* XXX */ + return i; + } +#endif if (string[i] != '$') { diff --git a/lib/readline/input.c b/lib/readline/input.c index 320c4bc..b5876da 100644 --- a/lib/readline/input.c +++ b/lib/readline/input.c @@ -45,14 +45,7 @@ # include "ansi_stdlib.h" #endif /* HAVE_STDLIB_H */ -#if defined (HAVE_SELECT) -# if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX) -# include <sys/time.h> -# endif -#endif /* HAVE_SELECT */ -#if defined (HAVE_SYS_SELECT_H) -# include <sys/select.h> -#endif +#include "posixselect.h" #if defined (FIONREAD_IN_SYS_IOCTL) # include <sys/ioctl.h> @@ -190,8 +183,7 @@ rl_gather_tyi () FD_ZERO (&exceptfds); FD_SET (tty, &readfds); FD_SET (tty, &exceptfds); - timeout.tv_sec = 0; - timeout.tv_usec = _keyboard_input_timeout; + USEC_TO_TIMEVAL (_keyboard_input_timeout, timeout); result = select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout); if (result <= 0) return 0; /* Nothing to read. */ diff --git a/lib/readline/keymaps.c b/lib/readline/keymaps.c index a033d5e..9379dec 100644 --- a/lib/readline/keymaps.c +++ b/lib/readline/keymaps.c @@ -57,8 +57,9 @@ Keymap rl_make_bare_keymap () { register int i; - Keymap keymap = (Keymap)xmalloc (KEYMAP_SIZE * sizeof (KEYMAP_ENTRY)); + Keymap keymap; + keymap = (Keymap)xmalloc (KEYMAP_SIZE * sizeof (KEYMAP_ENTRY)); for (i = 0; i < KEYMAP_SIZE; i++) { keymap[i].type = ISFUNC; @@ -76,7 +77,8 @@ rl_make_bare_keymap () return (keymap); } -/* Return a new keymap which is a copy of MAP. */ +/* Return a new keymap which is a copy of MAP. Just copies pointers, does + not copy text of macros or descend into child keymaps. */ Keymap rl_copy_keymap (map) Keymap map; @@ -128,7 +130,7 @@ rl_discard_keymap (map) { int i; - if (!map) + if (map == 0) return; for (i = 0; i < KEYMAP_SIZE; i++) @@ -140,6 +142,7 @@ rl_discard_keymap (map) case ISKMAP: rl_discard_keymap ((Keymap)map[i].function); + free ((char *)map[i].function); break; case ISMACR: @@ -148,3 +151,12 @@ rl_discard_keymap (map) } } } + +/* Convenience function that discards, then frees, MAP. */ +void +rl_free_keymap (map) + Keymap map; +{ + rl_discard_keymap (map); + free ((char *)map); +} diff --git a/lib/readline/mbutil.c b/lib/readline/mbutil.c index 858842e..eeb7e55 100644 --- a/lib/readline/mbutil.c +++ b/lib/readline/mbutil.c @@ -77,7 +77,7 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero) char *string; int seed, count, find_non_zero; { - size_t tmp; + size_t tmp, len; mbstate_t ps; int point; wchar_t wc; @@ -99,7 +99,10 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero) while (count > 0) { - tmp = mbrtowc (&wc, string+point, strlen(string + point), &ps); + len = strlen (string + point); + if (len == 0) + break; + tmp = mbrtowc (&wc, string+point, len, &ps); if (MB_INVALIDCH ((size_t)tmp)) { /* invalid bytes. assume a byte represents a character */ diff --git a/lib/readline/parens.c b/lib/readline/parens.c index f15d26f..9c98488 100644 --- a/lib/readline/parens.c +++ b/lib/readline/parens.c @@ -38,16 +38,7 @@ # include <unistd.h> #endif -#if defined (FD_SET) && !defined (HAVE_SELECT) -# define HAVE_SELECT -#endif - -#if defined (HAVE_SELECT) -# include <sys/time.h> -#endif /* HAVE_SELECT */ -#if defined (HAVE_SYS_SELECT_H) -# include <sys/select.h> -#endif +#include "posixselect.h" #if defined (HAVE_STRING_H) # include <string.h> @@ -130,8 +121,7 @@ rl_insert_close (count, invoking_key) FD_ZERO (&readfds); FD_SET (fileno (rl_instream), &readfds); - timer.tv_sec = 0; - timer.tv_usec = _paren_blink_usec; + USEC_TO_TIMEVAL (_paren_blink_usec, timer); orig_point = rl_point; rl_point = match_point; diff --git a/lib/readline/readline.c b/lib/readline/readline.c index 3550b35..c0e78d4 100644 --- a/lib/readline/readline.c +++ b/lib/readline/readline.c @@ -275,6 +275,10 @@ int _rl_bind_stty_chars = 1; its initial state. */ int _rl_revert_all_at_newline = 0; +/* Non-zero means to honor the termios ECHOCTL bit and echo control + characters corresponding to keyboard-generated signals. */ +int _rl_echo_control_chars = 1; + /* **************************************************************** */ /* */ /* Top Level Functions */ @@ -686,7 +690,8 @@ _rl_dispatch_callback (cxt) r = cxt->childval; /* For now */ - r = _rl_subseq_result (r, cxt->oldmap, cxt->okey, (cxt->flags & KSEQ_SUBSEQ)); + if (r != -3) /* don't do this if we indicate there will be other matches */ + r = _rl_subseq_result (r, cxt->oldmap, cxt->okey, (cxt->flags & KSEQ_SUBSEQ)); RL_CHECK_SIGNALS (); if (r == 0) /* success! */ @@ -831,7 +836,7 @@ _rl_dispatch_subseq (key, map, got_subseq) { /* Return 0 only the first time, to indicate success to _rl_callback_read_char. The rest of the time, we're called - from _rl_dispatch_callback, so we return 3 to indicate + from _rl_dispatch_callback, so we return -3 to indicate special handling is necessary. */ r = RL_ISSTATE (RL_STATE_MULTIKEY) ? -3 : 0; cxt = _rl_keyseq_cxt_alloc (); @@ -895,7 +900,7 @@ _rl_subseq_result (r, map, key, got_subseq) Keymap m; int type, nt; rl_command_func_t *func, *nf; - + if (r == -2) /* We didn't match anything, and the keymap we're indexed into shadowed a function previously bound to that prefix. Call @@ -1169,6 +1174,10 @@ bind_arrow_keys () #if defined (VI_MODE) bind_arrow_keys_internal (vi_movement_keymap); + /* Unbind vi_movement_keymap[ESC] to allow users to repeatedly hit ESC + in vi command mode while still allowing the arrow keys to work. */ + if (vi_movement_keymap[ESC].type == ISKMAP) + rl_bind_keyseq_in_map ("\033", (rl_command_func_t *)NULL, vi_movement_keymap); bind_arrow_keys_internal (vi_insertion_keymap); #endif } diff --git a/lib/readline/readline.h b/lib/readline/readline.h index fa02dec..7a4ffaa 100644 --- a/lib/readline/readline.h +++ b/lib/readline/readline.h @@ -95,6 +95,7 @@ extern int rl_forward_word PARAMS((int, int)); extern int rl_backward_word PARAMS((int, int)); extern int rl_refresh_line PARAMS((int, int)); extern int rl_clear_screen PARAMS((int, int)); +extern int rl_skip_csi_sequence PARAMS((int, int)); extern int rl_arrow_keys PARAMS((int, int)); /* Bindable commands for inserting and deleting text. */ @@ -150,7 +151,9 @@ extern int rl_dump_variables PARAMS((int, int)); extern int rl_complete PARAMS((int, int)); extern int rl_possible_completions PARAMS((int, int)); extern int rl_insert_completions PARAMS((int, int)); +extern int rl_old_menu_complete PARAMS((int, int)); extern int rl_menu_complete PARAMS((int, int)); +extern int rl_backward_menu_complete PARAMS((int, int)); /* Bindable commands for killing and yanking text, and managing the kill ring. */ extern int rl_kill_word PARAMS((int, int)); @@ -675,6 +678,17 @@ extern rl_icppfunc_t *rl_directory_completion_hook; yet, so it's undocumented. */ extern rl_icppfunc_t *rl_directory_rewrite_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 + either return its first argument (if no conversion takes place) or + newly-allocated memory. This can, for instance, convert filenames + between character sets for comparison against what's typed at the + keyboard. The returned value is what is added to the list of + matches. The second argument is the length of the filename to be + converted. */ +extern rl_dequote_func_t *rl_filename_rewrite_hook; + /* Backwards compatibility with previous versions of readline. */ #define rl_symbolic_link_hook rl_directory_completion_hook diff --git a/lib/readline/rlprivate.h b/lib/readline/rlprivate.h index f575c14..819f127 100644 --- a/lib/readline/rlprivate.h +++ b/lib/readline/rlprivate.h @@ -300,6 +300,8 @@ extern void _rl_signal_handler PARAMS((int)); extern void _rl_block_sigint PARAMS((void)); extern void _rl_release_sigint PARAMS((void)); +extern void _rl_block_sigwinch PARAMS((void)); +extern void _rl_release_sigwinch PARAMS((void)); /* terminal.c */ extern void _rl_get_screen_size PARAMS((int, int)); @@ -347,6 +349,7 @@ extern void _rl_trace (); extern int _rl_tropen PARAMS((void)); extern int _rl_abort_internal PARAMS((void)); +extern int _rl_null_function PARAMS((int, int)); extern char *_rl_strindex PARAMS((const char *, const char *)); extern int _rl_qsort_string_compare PARAMS((char **, char **)); extern int (_rl_uppercase_p) PARAMS((int)); @@ -386,6 +389,7 @@ extern int _rl_print_completions_horizontally; extern int _rl_completion_case_fold; extern int _rl_match_hidden_files; extern int _rl_page_completions; +extern int _rl_skip_completed_text; /* display.c */ extern int _rl_vis_botlin; @@ -417,6 +421,7 @@ extern int _rl_convert_meta_chars_to_ascii; 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 char *_rl_comment_begin; extern unsigned char _rl_parsing_conditionalized_out; extern Keymap _rl_keymap; diff --git a/lib/readline/rltty.c b/lib/readline/rltty.c index 61f9103..0dd5d10 100644 --- a/lib/readline/rltty.c +++ b/lib/readline/rltty.c @@ -517,7 +517,9 @@ prepare_terminal_settings (meta_flag, oldtio, tiop) TIOTYPE oldtio, *tiop; { _rl_echoing_p = (oldtio.c_lflag & ECHO); +#if defined (ECHOCTL) _rl_echoctl = (oldtio.c_lflag & ECHOCTL); +#endif tiop->c_lflag &= ~(ICANON | ECHO); diff --git a/lib/readline/signals.c b/lib/readline/signals.c index 325ae8c..4fbc019 100644 --- a/lib/readline/signals.c +++ b/lib/readline/signals.c @@ -101,7 +101,8 @@ int rl_catch_sigwinch = 0; /* for the readline state struct in readline.c */ int _rl_interrupt_immediately = 0; int volatile _rl_caught_signal = 0; /* should be sig_atomic_t, but that requires including <signal.h> everywhere */ -/* If non-zero, print characters corresponding to received signals. */ +/* If non-zero, print characters corresponding to received signals as long as + the user has indicated his desire to do so (_rl_echo_control_chars). */ int _rl_echoctl = 0; int _rl_intr_char = 0; @@ -141,13 +142,14 @@ static RETSIGTYPE rl_signal_handler (sig) int sig; { - if (_rl_interrupt_immediately) + if (_rl_interrupt_immediately || RL_ISSTATE(RL_STATE_CALLBACK)) { _rl_interrupt_immediately = 0; _rl_handle_signal (sig); } + else + _rl_caught_signal = sig; - _rl_caught_signal = sig; SIGHANDLER_RETURN; } @@ -518,13 +520,16 @@ rl_free_line_state () #if defined (HAVE_POSIX_SIGNALS) static sigset_t sigint_set, sigint_oset; +static sigset_t sigwinch_set, sigwinch_oset; #else /* !HAVE_POSIX_SIGNALS */ # if defined (HAVE_BSD_SIGNALS) static int sigint_oldmask; +static int sigwinch_oldmask; # endif /* HAVE_BSD_SIGNALS */ #endif /* !HAVE_POSIX_SIGNALS */ static int sigint_blocked; +static int sigwinch_blocked; /* Cause SIGINT to not be delivered until the corresponding call to release_sigint(). */ @@ -574,6 +579,54 @@ _rl_release_sigint () sigint_blocked = 0; } +/* Cause SIGWINCH to not be delivered until the corresponding call to + release_sigwinch(). */ +void +_rl_block_sigwinch () +{ + if (sigwinch_blocked) + return; + +#if defined (HAVE_POSIX_SIGNALS) + sigemptyset (&sigwinch_set); + sigemptyset (&sigwinch_oset); + sigaddset (&sigwinch_set, SIGWINCH); + sigprocmask (SIG_BLOCK, &sigwinch_set, &sigwinch_oset); +#else /* !HAVE_POSIX_SIGNALS */ +# if defined (HAVE_BSD_SIGNALS) + sigwinch_oldmask = sigblock (sigmask (SIGWINCH)); +# else /* !HAVE_BSD_SIGNALS */ +# if defined (HAVE_USG_SIGHOLD) + sighold (SIGWINCH); +# endif /* HAVE_USG_SIGHOLD */ +# endif /* !HAVE_BSD_SIGNALS */ +#endif /* !HAVE_POSIX_SIGNALS */ + + sigwinch_blocked = 1; +} + +/* Allow SIGWINCH to be delivered. */ +void +_rl_release_sigwinch () +{ + if (sigwinch_blocked == 0) + return; + +#if defined (HAVE_POSIX_SIGNALS) + sigprocmask (SIG_SETMASK, &sigwinch_oset, (sigset_t *)NULL); +#else +# if defined (HAVE_BSD_SIGNALS) + sigsetmask (sigwinch_oldmask); +# else /* !HAVE_BSD_SIGNALS */ +# if defined (HAVE_USG_SIGHOLD) + sigrelse (SIGWINCH); +# endif /* HAVE_USG_SIGHOLD */ +# endif /* !HAVE_BSD_SIGNALS */ +#endif /* !HAVE_POSIX_SIGNALS */ + + sigwinch_blocked = 0; +} + /* **************************************************************** */ /* */ /* Echoing special control characters */ @@ -586,14 +639,18 @@ rl_echo_signal_char (sig) char cstr[3]; int cslen, c; - if (_rl_echoctl == 0) + if (_rl_echoctl == 0 || _rl_echo_control_chars == 0) return; switch (sig) { case SIGINT: c = _rl_intr_char; break; +#if defined (SIGQUIT) case SIGQUIT: c = _rl_quit_char; break; +#endif +#if defined (SIGTSTP) case SIGTSTP: c = _rl_susp_char; break; +#endif default: return; } diff --git a/lib/readline/terminal.c b/lib/readline/terminal.c index 768ec9b..ee13092 100644 --- a/lib/readline/terminal.c +++ b/lib/readline/terminal.c @@ -528,8 +528,8 @@ _rl_init_terminal_io (terminal_name) /* Check to see if this terminal has a meta key and clear the capability variables if there is none. */ - term_has_meta = (tgetflag ("km") || tgetflag ("MT")); - if (!term_has_meta) + term_has_meta = tgetflag ("km") != 0; + if (term_has_meta == 0) _rl_term_mm = _rl_term_mo = (char *)NULL; /* Attempt to find and bind the arrow keys. Do not override already diff --git a/lib/readline/text.c b/lib/readline/text.c index 652b306..fc39189 100644 --- a/lib/readline/text.c +++ b/lib/readline/text.c @@ -67,6 +67,10 @@ static int _rl_insert_next_callback PARAMS((_rl_callback_generic_arg *)); static int _rl_char_search_callback PARAMS((_rl_callback_generic_arg *)); #endif +/* The largest chunk of text that can be inserted in one call to + rl_insert_text. Text blocks larger than this are divided. */ +#define TEXT_COUNT_MAX 1024 + /* **************************************************************** */ /* */ /* Insert and Delete */ @@ -185,10 +189,13 @@ _rl_replace_text (text, start, end) { int n; + n = 0; rl_begin_undo_group (); - rl_delete_text (start, end + 1); + if (start <= end) + rl_delete_text (start, end + 1); rl_point = start; - n = rl_insert_text (text); + if (*text) + n = rl_insert_text (text); rl_end_undo_group (); return n; @@ -571,6 +578,21 @@ rl_clear_screen (count, key) } int +rl_skip_csi_sequence (count, key) + int count, key; +{ + int ch; + + RL_SETSTATE (RL_STATE_MOREINPUT); + do + ch = rl_read_key (); + while (ch >= 0x20 && ch < 0x40); + RL_UNSETSTATE (RL_STATE_MOREINPUT); + + return 0; +} + +int rl_arrow_keys (count, c) int count, c; { @@ -707,7 +729,7 @@ _rl_insert_char (count, c) /* If we can optimize, then do it. But don't let people crash readline because of extra large arguments. */ - if (count > 1 && count <= 1024) + if (count > 1 && count <= TEXT_COUNT_MAX) { #if defined (HANDLE_MULTIBYTE) string_size = count * incoming_length; @@ -735,11 +757,11 @@ _rl_insert_char (count, c) return 0; } - if (count > 1024) + if (count > TEXT_COUNT_MAX) { int decreaser; #if defined (HANDLE_MULTIBYTE) - string_size = incoming_length * 1024; + string_size = incoming_length * TEXT_COUNT_MAX; string = (char *)xmalloc (1 + string_size); i = 0; @@ -751,7 +773,7 @@ _rl_insert_char (count, c) while (count) { - decreaser = (count > 1024) ? 1024 : count; + decreaser = (count > TEXT_COUNT_MAX) ? TEXT_COUNT_MAX : count; string[decreaser*incoming_length] = '\0'; rl_insert_text (string); count -= decreaser; @@ -761,14 +783,14 @@ _rl_insert_char (count, c) incoming_length = 0; stored_count = 0; #else /* !HANDLE_MULTIBYTE */ - char str[1024+1]; + char str[TEXT_COUNT_MAX+1]; - for (i = 0; i < 1024; i++) + for (i = 0; i < TEXT_COUNT_MAX; i++) str[i] = c; while (count) { - decreaser = (count > 1024 ? 1024 : count); + decreaser = (count > TEXT_COUNT_MAX ? TEXT_COUNT_MAX : count); str[decreaser] = '\0'; rl_insert_text (str); count -= decreaser; @@ -1129,7 +1151,7 @@ int rl_delete_horizontal_space (count, ignore) int count, ignore; { - int start = rl_point; + int start; while (rl_point && whitespace (rl_line_buffer[rl_point - 1])) rl_point--; @@ -1247,6 +1269,7 @@ rl_change_case (count, op) wchar_t wc, nwc; char mb[MB_LEN_MAX+1]; int mlen; + size_t m; mbstate_t mps; #endif @@ -1299,7 +1322,11 @@ rl_change_case (count, op) #if defined (HANDLE_MULTIBYTE) else { - mbrtowc (&wc, rl_line_buffer + start, end - start, &mps); + m = mbrtowc (&wc, rl_line_buffer + start, end - start, &mps); + if (MB_INVALIDCH (m)) + wc = (wchar_t)rl_line_buffer[start]; + else if (MB_NULLWCH (m)) + wc = L'\0'; nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc); if (nwc != wc) /* just skip unchanged characters */ { diff --git a/lib/readline/undo.c b/lib/readline/undo.c index c0ba631..eb042b2 100644 --- a/lib/readline/undo.c +++ b/lib/readline/undo.c @@ -139,6 +139,9 @@ _rl_copy_undo_list (head) { UNDO_LIST *list, *new, *roving, *c; + if (head == 0) + return head; + list = head; new = 0; while (list) diff --git a/lib/readline/util.c b/lib/readline/util.c index 3a3e91e..6bb64c2 100644 --- a/lib/readline/util.c +++ b/lib/readline/util.c @@ -81,8 +81,7 @@ rl_alphabetic (c) #if defined (HANDLE_MULTIBYTE) int -_rl_walphabetic (wc) - wchar_t wc; +_rl_walphabetic (wchar_t wc) { int c; @@ -121,6 +120,13 @@ rl_abort (count, key) } int +_rl_null_function (count, key) + int count, key; +{ + return 0; +} + +int rl_tty_status (count, key) int count, key; { diff --git a/lib/readline/vi_keymap.c b/lib/readline/vi_keymap.c index 3663173..ba5a27b 100644 --- a/lib/readline/vi_keymap.c +++ b/lib/readline/vi_keymap.c @@ -326,9 +326,9 @@ KEYMAP_ENTRY_ARRAY vi_insertion_keymap = { { ISFUNC, rl_insert }, /* Control-k */ { ISFUNC, rl_insert }, /* Control-l */ { ISFUNC, rl_newline }, /* Control-m */ - { ISFUNC, rl_insert }, /* Control-n */ + { ISFUNC, rl_menu_complete}, /* Control-n */ { ISFUNC, rl_insert }, /* Control-o */ - { ISFUNC, rl_insert }, /* Control-p */ + { ISFUNC, rl_backward_menu_complete }, /* Control-p */ { ISFUNC, rl_insert }, /* Control-q */ { ISFUNC, rl_reverse_search_history }, /* Control-r */ { ISFUNC, rl_forward_search_history }, /* Control-s */ diff --git a/lib/readline/vi_mode.c b/lib/readline/vi_mode.c index 5f35cf0..2a120c0 100644 --- a/lib/readline/vi_mode.c +++ b/lib/readline/vi_mode.c @@ -131,9 +131,10 @@ static int _rl_vi_callback_char_search PARAMS((_rl_callback_generic_arg *)); void _rl_vi_initialize_line () { - register int i; + register int i, n; - for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++) + n = sizeof (vi_mark_chars) / sizeof (vi_mark_chars[0]); + for (i = 0; i < n; i++) vi_mark_chars[i] = -1; RL_UNSETSTATE(RL_STATE_VICMDONCE); @@ -768,6 +769,7 @@ _rl_vi_change_mbchar_case (count) wchar_t wc; char mb[MB_LEN_MAX+1]; int mlen, p; + size_t m; mbstate_t ps; memset (&ps, 0, sizeof (mbstate_t)); @@ -775,7 +777,11 @@ _rl_vi_change_mbchar_case (count) count--; while (count-- && rl_point < rl_end) { - mbrtowc (&wc, rl_line_buffer + rl_point, rl_end - rl_point, &ps); + m = mbrtowc (&wc, rl_line_buffer + rl_point, rl_end - rl_point, &ps); + if (MB_INVALIDCH (m)) + wc = (wchar_t)rl_line_buffer[rl_point]; + else if (MB_NULLWCH (m)) + wc = L'\0'; if (iswupper (wc)) wc = towlower (wc); else if (iswlower (wc)) diff --git a/lib/sh/Makefile.in b/lib/sh/Makefile.in index c8db3a5..80f6cc5 100644 --- a/lib/sh/Makefile.in +++ b/lib/sh/Makefile.in @@ -86,12 +86,12 @@ CSOURCES = clktck.c clock.c getcwd.c getenv.c oslib.c setlinebuf.c \ vprint.c itos.c rename.c zread.c zwrite.c shtty.c \ inet_aton.c netconn.c netopen.c strpbrk.c timeval.c makepath.c \ pathcanon.c pathphys.c tmpfile.c stringlist.c stringvec.c spell.c \ - shquote.c strtrans.c strindex.c snprintf.c mailstat.c \ + shquote.c strtrans.c strcasestr.c snprintf.c mailstat.c \ fmtulong.c fmtullong.c fmtumax.c shmatch.c strnlen.c \ strtoll.c strtoull.c strtoimax.c strtoumax.c memset.c strstr.c \ - mktime.c strftime.c xstrchr.c zcatfd.c zmapfd.c winsize.c eaccess.c \ + mktime.c strftime.c mbschr.c zcatfd.c zmapfd.c winsize.c eaccess.c \ wcsdup.c fpurge.c zgetline.c mbscmp.c uconvert.c ufuncs.c \ - casemod.c fdprintf.c input_avail.c + casemod.c fdprintf.c input_avail.c mbscasecmp.c fnxform.c # The header files for this library. HSOURCES = @@ -102,10 +102,10 @@ OBJECTS = clktck.o clock.o getenv.o oslib.o setlinebuf.o strnlen.o \ itos.o zread.o zwrite.o shtty.o shmatch.o eaccess.o \ netconn.o netopen.o timeval.o makepath.o pathcanon.o \ pathphys.o tmpfile.o stringlist.o stringvec.o spell.o shquote.o \ - strtrans.o strindex.o snprintf.o mailstat.o fmtulong.o \ - fmtullong.o fmtumax.o xstrchr.o zcatfd.o zmapfd.o winsize.o wcsdup.o \ + strtrans.o snprintf.o mailstat.o fmtulong.o \ + fmtullong.o fmtumax.o zcatfd.o zmapfd.o winsize.o wcsdup.o \ fpurge.o zgetline.o mbscmp.o uconvert.o ufuncs.o casemod.o \ - fdprintf.o input_avail.o ${LIBOBJS} + fdprintf.o input_avail.o mbscasecmp.o fnxform.o ${LIBOBJS} SUPPORT = Makefile @@ -136,6 +136,9 @@ mostlyclean: clean ${BUILD_DIR}/version.h: ${BUILD_DIR}/config.h ${BUILD_DIR}/Makefile Makefile -( cd ${BUILD_DIR} && ${MAKE} ${MFLAGS} version.h ) +${BUILD_DIR}/pathnames.h: ${BUILD_DIR}/config.h ${BUILD_DIR}/Makefile Makefile + -( cd ${BUILD_DIR} && ${MAKE} ${MFLAGS} pathnames.h ) + # rules for losing makes, like SunOS casemod.o: casemod.c clktck.o: clktck.c @@ -145,6 +148,7 @@ fdprintf.o: fdprintf.c fmtullong.o: fmtullong.c fmtulong.o: fmtulong.c fmtumax.o: fmtumax.c +fnxform.o: fnxform.c fpurge.o: fpurge.c getcwd.o: getcwd.c getenv.o: getenv.c @@ -153,6 +157,7 @@ input_avail.o: input_avail.c itos.o: itos.c mailstat.o: mailstat.c makepath.o: makepath.c +mbscasecmp.o: mbscasecmp.c mbscmp.o: mbscmp.c memset.o: memset.c mktime.o: mktime.c @@ -170,7 +175,7 @@ spell.o: spell.c strcasecmp.o: strcasecmp.c strerror.o: strerror.c strftime.o: strftime.c -strindex.o: strindex.c +strcasestr.o: strcasestr.c stringlist.o: stringlist.c stringvec.o: stringvec.c strnlen.o: strnlen.c @@ -190,7 +195,7 @@ uconvert.o: uconvert.c ufuncs.o: ufuncs.c vprint.o: vprint.c wcsdup.o: wcsdup.c -xstrchr.o: xstrchr.c +mbschr.o: mbschr.c zcatfd.o: zcatfd.c zmapfd.o: zmapfd.c zgetline.o: zgetline.c @@ -213,6 +218,7 @@ fdprintf.o: ${BUILD_DIR}/config.h fmtullong.o: ${BUILD_DIR}/config.h fmtulong.o: ${BUILD_DIR}/config.h fmtumax.o: ${BUILD_DIR}/config.h +fnxform.o: ${BUILD_DIR}/config.h fpurge.o: ${BUILD_DIR}/config.h getcwd.o: ${BUILD_DIR}/config.h getenv.o: ${BUILD_DIR}/config.h @@ -221,6 +227,7 @@ input_avail.o: ${BUILD_DIR}/config.h itos.o: ${BUILD_DIR}/config.h mailstat.o: ${BUILD_DIR}/config.h makepath.o: ${BUILD_DIR}/config.h +mbscasecmp.o: ${BUILD_DIR}/config.h mbscmp.o: ${BUILD_DIR}/config.h memset.o: ${BUILD_DIR}/config.h mktime.o: ${BUILD_DIR}/config.h @@ -238,7 +245,7 @@ spell.o: ${BUILD_DIR}/config.h strcasecmp.o: ${BUILD_DIR}/config.h strerror.o: ${BUILD_DIR}/config.h strftime.o: ${BUILD_DIR}/config.h -strindex.o: ${BUILD_DIR}/config.h +strcasestr.o: ${BUILD_DIR}/config.h stringlist.o: ${BUILD_DIR}/config.h stringvec.o: ${BUILD_DIR}/config.h strnlen.o: ${BUILD_DIR}/config.h @@ -258,7 +265,7 @@ uconvert.o: ${BUILD_DIR}/config.h ufuncs.o: ${BUILD_DIR}/config.h vprint.o: ${BUILD_DIR}/config.h wcsdup.o: ${BUILD_DIR}/config.h -xstrchr.o: ${BUILD_DIR}/config.h +mbschr.o: ${BUILD_DIR}/config.h zcatfd.o: ${BUILD_DIR}/config.h zgetline.o: ${BUILD_DIR}/config.h zmapfd.o: ${BUILD_DIR}/config.h @@ -393,8 +400,8 @@ strerror.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h strerror.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h strerror.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h -strindex.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h -strindex.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +strcasestr.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h +strcasestr.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h stringlist.o: ${topdir}/bashansi.h stringlist.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h @@ -498,15 +505,19 @@ wcsdup.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h wcsdup.o: ${BASHINCDIR}/stdc.h wcsdup.o: ${topdir}/xmalloc.h -xstrchr.o: ${topdir}/bashansi.h -xstrchr.o: ${BASHINCDIR}/ansi_stdlib.h -xstrchr.o: ${BASHINCDIR}/shmbutil.h +mbschr.o: ${topdir}/bashansi.h +mbschr.o: ${BASHINCDIR}/ansi_stdlib.h +mbschr.o: ${BASHINCDIR}/shmbutil.h zgetline.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h zgetline.o: ${BASHINCDIR}/stdc.h zgetline.o: ${topdir}/xmalloc.h zgetline.o: ${topdir}/bashtypes.h +mbscasecmp.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +mbscasecmp.o: ${BASHINCDIR}/stdc.h +mbscasecmp.o: ${topdir}/xmalloc.h + mbscmp.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h mbscmp.o: ${BASHINCDIR}/stdc.h mbscmp.o: ${topdir}/xmalloc.h @@ -522,5 +533,12 @@ fdprintf.o: ${BASHINCDIR}/stdc.h input_avail.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h input_avail.o: ${BASHINCDIR}/stdc.h -input_avail.o: ${topdir}/xmalloc.h +input_avail.o: ${topdir}/xmalloc.h ${BASHINCDIR}/posixselect.h + +mktime.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +mktime.o: ${BASHINCDIR}/stdc.h +fnxform.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +fnxform.o: ${BASHINCDIR}/stdc.h +fnxform.o: ${topdir}/bashtypes.h +fnxform.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h diff --git a/lib/sh/casemod.c b/lib/sh/casemod.c index b7e0850..d85549a 100644 --- a/lib/sh/casemod.c +++ b/lib/sh/casemod.c @@ -107,6 +107,7 @@ sh_modcase (string, pat, flags) wchar_t nwc; char mb[MB_LEN_MAX+1]; int mlen; + size_t m; mbstate_t state; #endif @@ -210,7 +211,11 @@ sh_modcase (string, pat, flags) #if defined (HANDLE_MULTIBYTE) else { - mbrtowc (&wc, string + start, end - start, &state); + m = mbrtowc (&wc, string + start, end - start, &state); + if (MB_INVALIDCH (m)) + wc = (wchar_t)string[start]; + else if (MB_NULLWCH (m)) + wc = L'\0'; switch (nop) { default: diff --git a/lib/sh/fpurge.c b/lib/sh/fpurge.c index fd093b8..f9e1b9d 100644 --- a/lib/sh/fpurge.c +++ b/lib/sh/fpurge.c @@ -31,7 +31,7 @@ #endif extern int fpurge __P((FILE *stream)); -#if HAVE___FPURGE /* glibc >= 2.2, Solaris >= 7 */ +#if HAVE___FPURGE /* glibc >= 2.2, Haiku, Solaris >= 7 */ # include <stdio_ext.h> #endif #include <stdlib.h> @@ -39,13 +39,13 @@ extern int fpurge __P((FILE *stream)); int fpurge (FILE *fp) { -#if HAVE___FPURGE /* glibc >= 2.2, Solaris >= 7 */ +#if HAVE___FPURGE /* glibc >= 2.2, Haiku, Solaris >= 7 */ __fpurge (fp); /* The __fpurge function does not have a return value. */ return 0; -#elif HAVE_FPURGE /* FreeBSD, NetBSD, OpenBSD, MacOS X */ +#elif HAVE_FPURGE /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X */ /* Call the system's fpurge function. */ # undef fpurge @@ -53,7 +53,7 @@ fpurge (FILE *fp) extern int fpurge (FILE *); # endif int result = fpurge (fp); -# if defined __sferror /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */ +# if defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */ if (result == 0) /* Correct the invariants that fpurge broke. <stdio.h> on BSD systems says: @@ -71,7 +71,7 @@ fpurge (FILE *fp) /* Most systems provide FILE as a struct and the necessary bitmask in <stdio.h>, because they need it for implementing getc() and putc() as fast macros. */ -# if defined _IO_ferror_unlocked /* GNU libc, BeOS */ +# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ fp->_IO_read_end = fp->_IO_read_ptr; fp->_IO_write_ptr = fp->_IO_write_base; /* Avoid memory leak when there is an active ungetc buffer. */ @@ -81,28 +81,27 @@ fpurge (FILE *fp) fp->_IO_save_base = NULL; } return 0; -# elif defined __sferror /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */ - fp->_p = fp->_bf._base; - fp->_r = 0; - fp->_w = ((fp->_flags & (__SLBF | __SNBF | __SRD)) == 0 /* fully buffered and not currently reading? */ - ? fp->_bf._size - : 0); +# elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */ + fp_->_p = fp_->_bf._base; + fp_->_r = 0; + fp_->_w = ((fp_->_flags & (__SLBF | __SNBF | __SRD)) == 0 /* fully buffered and not currently reading? */ + ? fp_->_bf._size + : 0); /* Avoid memory leak when there is an active ungetc buffer. */ -# if defined __NetBSD__ || defined __OpenBSD__ /* NetBSD, OpenBSD */ - /* See <http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> - and <http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> */ -# define fp_ub ((struct { struct __sbuf _ub; } *) fp->_ext._base)->_ub -# else /* FreeBSD, MacOS X, Cygwin */ -# define fp_ub fp->_ub -# endif if (fp_ub._base != NULL) { - if (fp_ub._base != fp->_ubuf) + if (fp_ub._base != fp_->_ubuf) free (fp_ub._base); fp_ub._base = NULL; } return 0; -# elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, mingw */ +# elif defined __EMX__ /* emx+gcc */ + fp->_ptr = fp->_buffer; + fp->_rcount = 0; + fp->_wcount = 0; + fp->_ungetc_count = 0; + return 0; +# elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw */ fp->_ptr = fp->_base; if (fp->_ptr != NULL) fp->_cnt = 0; @@ -115,8 +114,34 @@ fpurge (FILE *fp) fp->__bufpos = fp->__bufread; # endif return 0; +# elif defined __QNX__ /* QNX */ + fp->_Rback = fp->_Back + sizeof (fp->_Back); + fp->_Rsave = NULL; + if (fp->_Mode & 0x2000 /* _MWRITE */) + /* fp->_Buf <= fp->_Next <= fp->_Wend */ + fp->_Next = fp->_Buf; + else + /* fp->_Buf <= fp->_Next <= fp->_Rend */ + fp->_Rend = fp->_Next; + return 0; +# elif defined __MINT__ /* Atari FreeMiNT */ + if (fp->__pushed_back) + { + fp->__bufp = fp->__pushback_bufp; + fp->__pushed_back = 0; + } + /* Preserve the current file position. */ + if (fp->__target != -1) + fp->__target += fp->__bufp - fp->__buffer; + fp->__bufp = fp->__buffer; + /* Nothing in the buffer, next getc is nontrivial. */ + fp->__get_limit = fp->__bufp; + /* Nothing in the buffer, next putc is nontrivial. */ + fp->__put_limit = fp->__buffer; + return 0; # else - #error "Please port gnulib fpurge.c to your platform! Look at the definitions of fflush, setvbuf and ungetc on your system, then report this to bug-gnulib." +# warning "Please port gnulib fpurge.c to your platform! Look at the definitions of fflush, setvbuf and ungetc on your system, then report this to bug-gnulib." + return 0; # endif #endif diff --git a/lib/sh/getcwd.c b/lib/sh/getcwd.c index 84799bb..07eb817 100644 --- a/lib/sh/getcwd.c +++ b/lib/sh/getcwd.c @@ -48,6 +48,12 @@ #include <bashansi.h> +#if defined (BROKEN_DIRENT_D_INO) +# include "command.h" +# include "general.h" +# include "externs.h" +#endif + #include <xmalloc.h> #if !defined (errno) diff --git a/lib/sh/input_avail.c b/lib/sh/input_avail.c index 5e01f8f..ac157a9 100644 --- a/lib/sh/input_avail.c +++ b/lib/sh/input_avail.c @@ -39,14 +39,7 @@ #include "bashansi.h" -#if defined (HAVE_SELECT) -# if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX) -# include <sys/time.h> -# endif -#endif /* HAVE_SELECT */ -#if defined (HAVE_SYS_SELECT_H) -# include <sys/select.h> -#endif +#include "posixselect.h" #if defined (FIONREAD_IN_SYS_IOCTL) # include <sys/ioctl.h> diff --git a/lib/sh/mbscmp.c b/lib/sh/mbscmp.c index ea01c27..e0eae5d 100644 --- a/lib/sh/mbscmp.c +++ b/lib/sh/mbscmp.c @@ -24,6 +24,7 @@ #include <stdlib.h> #include <stddef.h> +#include <string.h> /* Compare MBS1 and MBS2. */ int @@ -40,16 +41,25 @@ mbscmp (mbs1, mbs2) do { - len1 = mbtowc ((wchar_t *) &c1, mbs1, MB_CUR_MAX); - len2 = mbtowc ((wchar_t *) &c2, mbs2, MB_CUR_MAX); + len1 = mbtowc (&c1, mbs1, MB_CUR_MAX); + len2 = mbtowc (&c2, mbs2, MB_CUR_MAX); if (len1 == 0) return len2 == 0 ? 0 : -1; - if (len2 == 0) + else if (len2 == 0) return 1; - if (len1 < 0 || len2 < 0) - /* FIXME: an illegal character appears. What to do? */ - return c1 - c2; + else if (len1 > 0 && len2 < 0) + return -1; + else if (len1 < 0 && len2 > 0) + return 1; + else if (len1 < 0 && len2 < 0) + { + len1 = strlen (mbs1); + len2 = strlen (mbs2); + return (len1 == len2 ? memcmp (mbs1, mbs2, len1) + : ((len1 < len2) ? (memcmp (mbs1, mbs2, len1) > 0 ? 1 : -1) + : (memcmp (mbs1, mbs2, len2) >= 0 ? 1 : -1))); + } mbs1 += len1; mbs2 += len2; diff --git a/lib/sh/snprintf.c b/lib/sh/snprintf.c index c406d4a..d681b16 100644 --- a/lib/sh/snprintf.c +++ b/lib/sh/snprintf.c @@ -61,9 +61,13 @@ # include <config.h> #endif -#if defined(DEBUG) +/* GCC 4.2 on Snow Leopard doesn't like the snprintf prototype */ +#if defined(DEBUG) && !defined (MACOSX) # undef HAVE_SNPRINTF # undef HAVE_ASPRINTF + +# define HAVE_SNPRINTF 0 +# define HAVE_ASPRINTF 0 #endif #if defined(DRIVER) && !defined(HAVE_CONFIG_H) @@ -82,7 +86,7 @@ #define intmax_t long #endif -#if !defined (HAVE_SNPRINTF) || !defined (HAVE_ASPRINTF) +#if !HAVE_SNPRINTF || !HAVE_ASPRINTF #include <bashtypes.h> @@ -299,6 +303,13 @@ static void dfallback __P((struct DATA *, const char *, const char *, double)); static char *groupnum __P((char *)); +#ifndef HAVE_ISINF_IN_LIBC +static int isinf __P((double)); +#endif +#ifndef HAVE_ISNAN_IN_LIBC +static int isnan __P((double)); +#endif + #ifdef DRIVER static void memory_error_and_abort (); static void *xmalloc __P((size_t)); @@ -1640,7 +1651,7 @@ dfallback (data, fs, fe, d) } #endif /* FLOATING_POINT */ -#ifndef HAVE_SNPRINTF +#if !HAVE_SNPRINTF int #if defined (__STDC__) @@ -1690,7 +1701,7 @@ snprintf(string, length, format, va_alist) #endif /* HAVE_SNPRINTF */ -#ifndef HAVE_ASPRINTF +#if !HAVE_ASPRINTF int #if defined (__STDC__) @@ -1735,9 +1746,9 @@ asprintf(stringp, format, va_alist) return rval; } -#endif +#endif /* !HAVE_ASPRINTF */ -#endif +#endif /* !HAVE_SNPRINTF || !HAVE_ASPRINTF */ #ifdef DRIVER diff --git a/lib/sh/strtoimax.c b/lib/sh/strtoimax.c index 373f66a..a4170f0 100644 --- a/lib/sh/strtoimax.c +++ b/lib/sh/strtoimax.c @@ -1,6 +1,6 @@ /* strtoimax - convert string representation of a number into an intmax_t value. */ -/* Copyright 1999-2005 Free Software Foundation, Inc. +/* Copyright 1999-2009 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -28,6 +28,10 @@ # include <inttypes.h> #endif +#if HAVE_STDINT_H +# include <stdint.h> +#endif + #if HAVE_STDLIB_H # include <stdlib.h> #endif diff --git a/lib/sh/strtoumax.c b/lib/sh/strtoumax.c index 3652b1e..09423ad 100644 --- a/lib/sh/strtoumax.c +++ b/lib/sh/strtoumax.c @@ -1,6 +1,6 @@ /* strtoumax - convert string representation of a number into an uintmax_t value. */ -/* Copyright 1999-2005 Free Software Foundation, Inc. +/* Copyright 1999-2009 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License along with Bash. If not, see <http://www.gnu.org/licenses/>. */ + /* Written by Paul Eggert. Modified by Chet Ramey for Bash. */ #if HAVE_CONFIG_H @@ -27,6 +28,10 @@ # include <inttypes.h> #endif +#if HAVE_STDINT_H +# include <stdint.h> +#endif + #if HAVE_STDLIB_H # include <stdlib.h> #endif diff --git a/lib/sh/uconvert.c b/lib/sh/uconvert.c index 1009565..3d656df 100644 --- a/lib/sh/uconvert.c +++ b/lib/sh/uconvert.c @@ -92,7 +92,7 @@ uconvert(s, ip, up) ipart = (ipart * 10) + (*p - '0'); } - if (*p == 0) + if (p == 0 || *p == 0) /* callers ensure p can never be 0; this is to shut up clang */ RETURN(1); if (*p == DECIMAL) |