diff options
| author | Chet Ramey <chet.ramey@case.edu> | 2017-02-22 11:09:11 -0500 |
|---|---|---|
| committer | Chet Ramey <chet.ramey@case.edu> | 2017-02-22 11:09:11 -0500 |
| commit | ac495185aab17ef6030a02ddc0be33380a27a94d (patch) | |
| tree | 3016c147c550e606b2a44f086784ffe0afba1128 | |
| parent | 7e92fb358bb54f5acd5e71ef2d8f5e841c5d4320 (diff) | |
| download | bash-ac495185aab17ef6030a02ddc0be33380a27a94d.tar.gz | |
commit bash-20170210 snapshot
| -rw-r--r-- | CWRU/CWRU.chlog | 50 | ||||
| -rw-r--r-- | MANIFEST | 1 | ||||
| -rw-r--r-- | doc/bash.1 | 10 | ||||
| -rw-r--r-- | doc/bashref.texi | 2 | ||||
| -rw-r--r-- | doc/version.texi | 4 | ||||
| -rw-r--r-- | eval.c | 41 | ||||
| -rw-r--r-- | execute_cmd.c | 2 | ||||
| -rw-r--r-- | externs.h | 1 | ||||
| -rw-r--r-- | jobs.c | 11 | ||||
| -rw-r--r-- | lib/readline/display.c | 100 | ||||
| -rw-r--r-- | lib/readline/mbutil.c | 11 | ||||
| -rw-r--r-- | parse.y | 2 | ||||
| -rw-r--r-- | shell.c | 11 | ||||
| -rwxr-xr-x | tests/RUN-ONE-TEST | 2 | ||||
| -rw-r--r-- | tests/comsub.right | 7 | ||||
| -rw-r--r-- | tests/comsub.tests | 1 | ||||
| -rw-r--r-- | tests/comsub4.sub | 27 |
17 files changed, 211 insertions, 72 deletions
diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 0c79193..5ab464e 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -13115,3 +13115,53 @@ lib/readline/input.c the next character as an unsigned char, so we handle multibyte character sequences correctly. Report and fix from Grisha Levit <grishalevit@gmail.com> + + 2/6 + --- +shell.c + - --pretty-print: new invocation option, currently undocumented, dumps + a pretty-printed version of a shell script given as an argument to + stdout + - main: call pretty_print_loop() if we're in pretty-printing mode in + a non-interactive shell + +eval.c + - pretty_print_loop: new function, similar to reader_loop, reads + commands and prints them by displaying the result from + make_command_string() + +externs.h + - pretty_print_loop: new extern declaration + + 2/9 + --- +doc/{bash.1,bashref.texi} + - here strings: correct documentation to note they do not undergo + brace expansion. Report from Conor McCarthy <mr.spuratic@gmail.com> + + 2/9 + --- +lib/readline/display.c + - expand_prompt: instead of recomputing the line break offsets for + prompts that span multiple screen lines on every call to rl_redisplay, + do it here. Manage a local array local_prompt_newlines; set an offset + every time `physchars' hits a multiple of the screen width. Inspired + by https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=843819 + - rl_redisplay: don't calculate multi-line prompt line break indices + here; use the values calculated by expand_prompt + - rl_{save,restore}_prompt: save and restore local_prompt_newlines + + 2/11 + ---- +lib/readline/mbutil.c + - _rl_find_prev_mbchar_internal: since we're traversing the string + from the beginning, shortcut non-multibyte characters in a UTF-8 + locale + +parse.y + - parse_comsub: if we are parsing a here document with a quoted + delimiter (LEX_QUOTEDDOC), we should not remove <backslash><newline> + pairs from the body of the here document. Need to add LEX_QUOTEDDOC + to the values in tflags when calling shell_getc. Fixes bug reported + by Michael Homer <michael.homer@ecs.vuw.ac.nz>, patch was originally + contributed by Geir Hauge <geir.hauge@gmail.com> @@ -899,6 +899,7 @@ tests/comsub.right f tests/comsub1.sub f tests/comsub2.sub f tests/comsub3.sub f +tests/comsub4.sub f tests/comsub-eof.tests f tests/comsub-eof0.sub f tests/comsub-eof1.sub f @@ -5,12 +5,12 @@ .\" Case Western Reserve University .\" chet.ramey@case.edu .\" -.\" Last Change: Fri Feb 3 16:01:50 EST 2017 +.\" Last Change: Thu Feb 9 15:46:36 EST 2017 .\" .\" bash_builtins, strip all but Built-Ins section .if \n(zZ=1 .ig zZ .if \n(zY=1 .ig zY -.TH BASH 1 "2017 February 3" "GNU Bash 4.4" +.TH BASH 1 "2017 February 9" "GNU Bash 4.4" .\" .\" There's some problem with having a `@' .\" in a tagged paragraph with the BSD man macros. @@ -50,8 +50,8 @@ bash \- GNU Bourne-Again SHell [options] [command_string | file] .SH COPYRIGHT -.if n Bash is Copyright (C) 1989-2016 by the Free Software Foundation, Inc. -.if t Bash is Copyright \(co 1989-2016 by the Free Software Foundation, Inc. +.if n Bash is Copyright (C) 1989-2017 by the Free Software Foundation, Inc. +.if t Bash is Copyright \(co 1989-2017 by the Free Software Foundation, Inc. .SH DESCRIPTION .B Bash is an \fBsh\fR-compatible command language interpreter that @@ -4017,7 +4017,7 @@ A variant of here documents, the format is: .RE .PP The \fIword\fP undergoes -brace expansion, tilde expansion, parameter and variable expansion, +tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal. Pathname expansion and word splitting are not performed. The result is supplied as a single string, with a newline appended, diff --git a/doc/bashref.texi b/doc/bashref.texi index 287abf0..fb15067 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -2773,7 +2773,7 @@ A variant of here documents, the format is: @end example The @var{word} undergoes -brace expansion, tilde expansion, parameter and variable expansion, +tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal. Pathname expansion and word splitting are not performed. The result is supplied as a single string, diff --git a/doc/version.texi b/doc/version.texi index 3e05e24..96373ff 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -2,10 +2,10 @@ Copyright (C) 1988-2017 Free Software Foundation, Inc. @end ignore -@set LASTCHANGE Wed Feb 1 09:09:18 EST 2017 +@set LASTCHANGE Thu Feb 9 15:46:16 EST 2017 @set EDITION 4.4 @set VERSION 4.4 -@set UPDATED 1 February 2017 +@set UPDATED 9 February 2017 @set UPDATED-MONTH February 2017 @@ -193,6 +193,47 @@ reader_loop () return (last_command_exit_value); } +/* Pretty print shell scripts */ +int +pretty_print_loop () +{ + COMMAND *current_command; + char *command_to_print; + int code; + int global_posix_mode, last_was_newline; + + global_posix_mode = posixly_correct; + last_was_newline = 0; + while (EOF_Reached == 0) + { + code = setjmp_nosigs (top_level); + if (code) + return (EXECUTION_FAILURE); + if (read_command() == 0) + { + current_command = global_command; + global_command = 0; + posixly_correct = 1; /* print posix-conformant */ + if (current_command && (command_to_print = make_command_string (current_command))) + { + printf ("%s\n", command_to_print); /* for now */ + last_was_newline = 0; + } + else if (last_was_newline == 0) + { + printf ("\n"); + last_was_newline = 1; + } + posixly_correct = global_posix_mode; + dispose_command (current_command); + } + else + return (EXECUTION_FAILURE); + } + + return (EXECUTION_SUCCESS); +} + static sighandler alrm_catcher(i) int i; diff --git a/execute_cmd.c b/execute_cmd.c index feccf7c..3074fa2 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -271,6 +271,8 @@ static int function_line_number; report the correct line number. Kind of a hack. */ static int showing_function_line; +static int connection_count; + /* $LINENO ($BASH_LINENO) for use by an ERR trap. Global so parse_and_execute can save and restore it. */ int line_number_for_err_trap; @@ -94,6 +94,7 @@ extern void get_current_user_info __P((void)); /* Functions from eval.c. */ extern int reader_loop __P((void)); +extern int pretty_print_loop __P((void)); extern int parse_command __P((void)); extern int read_command __P((void)); @@ -848,8 +848,15 @@ bgp_delete (pid) /* Search chain using hash to find bucket in pidstat_table */ for (psi = *(pshash_getbucket (pid)); psi != NO_PIDSTAT; psi = bgpids.storage[psi].bucket_next) - if (bgpids.storage[psi].pid == pid) - break; + { + if (bgpids.storage[psi].pid == pid) + break; + if (psi == bgpids.storage[psi].bucket_next) /* catch reported bug */ + { + internal_warning ("bgp_delete: BUG: psi (%d) == storage[psi].bucket_next", psi); + return 0; + } + } if (psi == NO_PIDSTAT) return 0; /* not found */ diff --git a/lib/readline/display.c b/lib/readline/display.c index 0e0d44c..50a8688 100644 --- a/lib/readline/display.c +++ b/lib/readline/display.c @@ -251,6 +251,8 @@ static int modmark; static char *saved_local_prompt; static char *saved_local_prefix; +static int *saved_local_prompt_newlines; + static int saved_last_invisible; static int saved_visible_length; static int saved_prefix_length; @@ -303,6 +305,8 @@ prompt_modestr (lenp) PMT_MULTILINE caller indicates that this is part of a multiline prompt */ +static int *local_prompt_newlines; + static char * expand_prompt (pmt, flags, lp, lip, niflp, vlp) char *pmt; @@ -311,7 +315,7 @@ expand_prompt (pmt, flags, lp, lip, niflp, vlp) { char *r, *ret, *p, *igstart, *nprompt, *ms; int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars; - int mlen; + int mlen, newlines, newlines_guess, bound; /* We only expand the mode string for the last line of a multiline prompt (a prompt with embedded newlines). */ @@ -345,6 +349,12 @@ expand_prompt (pmt, flags, lp, lip, niflp, vlp) l = strlen (nprompt); /* XXX */ r = ret = (char *)xmalloc (l + 1); + newlines_guess = (l / _rl_screenwidth) + 1; + local_prompt_newlines = (int *) xrealloc (local_prompt_newlines, sizeof (int) * (newlines_guess + 1)); + local_prompt_newlines[newlines = 0] = 0; + for (rl = 1; rl <= newlines_guess; rl++) + local_prompt_newlines[rl] = -1; + rl = physchars = 0; /* mode string now part of nprompt */ invfl = 0; /* invisible chars in first line of prompt */ invflset = 0; /* we only want to set invfl once */ @@ -404,11 +414,25 @@ expand_prompt (pmt, flags, lp, lip, niflp, vlp) ninvis++; /* invisible chars byte counter */ } - if (invflset == 0 && rl >= _rl_screenwidth) + if (invflset == 0 && physchars >= _rl_screenwidth) { invfl = ninvis; invflset = 1; } +#if 0 + if (physchars >= ((newlines + 1) * _rl_screenwidth) && local_prompt_newlines[newlines+1] == -1) + local_prompt_newlines[++newlines] = r - ret; +#else + if (physchars >= (bound = (newlines + 1) * _rl_screenwidth) && local_prompt_newlines[newlines+1] == -1) + { + int new; + if (physchars > bound) /* should rarely happen */ + new = _rl_find_prev_mbchar (r, r - ret, MB_FIND_ANY); + else + new = r - ret; + local_prompt_newlines[++newlines] = new; + } +#endif } } @@ -759,18 +783,9 @@ rl_redisplay () /* what if lpos is already >= _rl_screenwidth before we start drawing the contents of the command line? */ - while (lpos >= _rl_screenwidth) + if (lpos >= _rl_screenwidth) { - int z, p; - int nocorrect, wadjust; - - nocorrect = 0; - /* Adjust depending on the invisible characters in the line. We use a - heuristic based on experience: invisible characters nearly always - appear in the first and last lines of the prompt */ - wadjust = (newlines == 0) - ? prompt_invis_chars_first_line - : ((newlines == prompt_lines_estimate) ? wrap_offset : prompt_invis_chars_first_line); + temp = 0; /* fix from Darin Johnson <darin@acuson.com> for prompt string with invisible characters that is longer than the screen width. The @@ -779,55 +794,18 @@ rl_redisplay () probably too much work for the benefit gained. How many people have prompts that exceed two physical lines? Additional logic fix from Edward Catmur <ed@catmur.co.uk> */ -#if defined (HANDLE_MULTIBYTE) - if (mb_cur_max > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0) + /* first copy the linebreaks array we computed in expand_prompt */ + while (local_prompt_newlines[newlines+1] != -1) { - nocorrect = 1; - n0 = num; - temp = local_prompt_len; - while (num < temp) - { - /* This has to take invisible characters in the prompt into - account. */ - z = _rl_col_width (local_prompt, n0, num, 1) - wadjust; - if (z > _rl_screenwidth) - { - num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY); - break; - } - else if (z == _rl_screenwidth) - { - /* If we are in the middle or at the end of a multibyte - character, we want to move to the start, then find out - where it ends so we know where to insert the newline. - If this isn't a multibyte character, its the same as num++ */ - p = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY); - num = _rl_find_next_mbchar (local_prompt, p, 1, MB_FIND_ANY); - break; - } - num++; - } - temp = num; - } - else -#endif /* !HANDLE_MULTIBYTE */ - temp = ((newlines + 1) * _rl_screenwidth); - - /* 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. */ - if (nocorrect == 0) - temp += wadjust; + temp = local_prompt_newlines[newlines+1]; + inv_lbreaks[++newlines] = temp; + } - inv_lbreaks[++newlines] = temp; -#if defined (HANDLE_MULTIBYTE) - /* lpos is a physical cursor position, so it needs to take the invisible - characters into account. */ + /* Now set lpos from the last newline */ if (mb_cur_max > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0) - lpos -= _rl_col_width (local_prompt, n0, num, 1) - wadjust; + lpos = _rl_col_width (local_prompt, temp, local_prompt_len, 1) - (wrap_offset - prompt_invis_chars_first_line); else -#endif - lpos -= _rl_screenwidth; /* all physical cursor positions */ + lpos -= (_rl_screenwidth * newlines); } prompt_last_screen_line = newlines; @@ -2561,9 +2539,12 @@ rl_save_prompt () saved_visible_length = prompt_visible_length; saved_invis_chars_first_line = prompt_invis_chars_first_line; saved_physical_chars = prompt_physical_chars; + saved_local_prompt_newlines = local_prompt_newlines; local_prompt = local_prompt_prefix = (char *)0; local_prompt_len = 0; + local_prompt_newlines = (int *)0; + prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0; prompt_invis_chars_first_line = prompt_physical_chars = 0; } @@ -2573,10 +2554,13 @@ rl_restore_prompt () { FREE (local_prompt); FREE (local_prompt_prefix); + FREE (local_prompt_newlines); local_prompt = saved_local_prompt; local_prompt_prefix = saved_local_prefix; local_prompt_len = saved_local_length; + local_prompt_newlines = saved_local_prompt_newlines; + prompt_prefix_length = saved_prefix_length; prompt_last_invisible = saved_last_invisible; prompt_visible_length = saved_visible_length; diff --git a/lib/readline/mbutil.c b/lib/readline/mbutil.c index df1c484..6485278 100644 --- a/lib/readline/mbutil.c +++ b/lib/readline/mbutil.c @@ -1,6 +1,6 @@ /* mbutil.c -- readline multibyte character utility functions */ -/* Copyright (C) 2001-2015 Free Software Foundation, Inc. +/* Copyright (C) 2001-2017 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. @@ -173,7 +173,14 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero) prev = non_zero_prev = point = 0; while (point < seed) { - tmp = mbrtowc (&wc, string + point, length - point, &ps); + if (_rl_utf8locale && UTF8_SINGLEBYTE(string[point])) + { + tmp = 1; + wc = (wchar_t) string[point]; + memset(&ps, 0, sizeof(mbstate_t)); + } + else + tmp = mbrtowc (&wc, string + point, length - point, &ps); if (MB_INVALIDCH ((size_t)tmp)) { /* in this case, bytes are invalid or too short to compose @@ -3757,7 +3757,7 @@ parse_comsub (qc, open, close, lenp, flags) while (count) { comsub_readchar: - ch = shell_getc (qc != '\'' && (tflags & (LEX_INCOMMENT|LEX_PASSNEXT)) == 0); + ch = shell_getc (qc != '\'' && (tflags & (LEX_INCOMMENT|LEX_PASSNEXT|LEX_QUOTEDDOC)) == 0); if (ch == EOF) { @@ -223,6 +223,8 @@ int dump_po_strings; /* Dump strings in $"..." in po format */ int wordexp_only = 0; /* Do word expansion only */ int protected_mode = 0; /* No command substitution with --wordexp */ +int pretty_print_mode = 0; /* pretty-print a shell script */ + #if defined (STRICT_POSIX) int posixly_correct = 1; /* Non-zero means posix.2 superset. */ #else @@ -251,6 +253,7 @@ static const struct { { "noprofile", Int, &no_profile, (char **)0x0 }, { "norc", Int, &no_rc, (char **)0x0 }, { "posix", Int, &posixly_correct, (char **)0x0 }, + { "pretty-print", Int, &pretty_print_mode, (char **)0x0 }, #if defined (WORDEXP_OPTION) { "protected", Int, &protected_mode, (char **)0x0 }, #endif @@ -779,6 +782,14 @@ main (argc, argv, env) shell_initialized = 1; + if (pretty_print_mode && interactive_shell) + { + internal_warning (_("pretty-printing mode ignored in interactive shells")); + pretty_print_mode = 0; + } + if (pretty_print_mode) + exit_shell (pretty_print_loop ()); + /* Read commands until exit condition. */ reader_loop (); exit_shell (last_command_exit_value); diff --git a/tests/RUN-ONE-TEST b/tests/RUN-ONE-TEST index 58c375b..554f3d6 100755 --- a/tests/RUN-ONE-TEST +++ b/tests/RUN-ONE-TEST @@ -1,4 +1,4 @@ -BUILD_DIR=/usr/local/build/chet/bash/bash-current +BUILD_DIR=/usr/local/build/bash/bash-current THIS_SH=$BUILD_DIR/bash PATH=$PATH:$BUILD_DIR diff --git a/tests/comsub.right b/tests/comsub.right index 09518aa..71bb205 100644 --- a/tests/comsub.right +++ b/tests/comsub.right @@ -28,6 +28,7 @@ ok 4 ok 5 ok 6 xyz +ok 7 \/tmp\/foo\/bar /tmp/foo/bar /tmp/foo/bar @@ -48,3 +49,9 @@ b c 1 2 +d \ +g +d \ +g +d \ +g diff --git a/tests/comsub.tests b/tests/comsub.tests index 4defc31..e8fab71 100644 --- a/tests/comsub.tests +++ b/tests/comsub.tests @@ -47,3 +47,4 @@ echo ${foo:-$(echo a{b,c})} >/dev/null ${THIS_SH} ./comsub1.sub ${THIS_SH} ./comsub2.sub ${THIS_SH} ./comsub3.sub +${THIS_SH} ./comsub4.sub diff --git a/tests/comsub4.sub b/tests/comsub4.sub new file mode 100644 index 0000000..461a9ad --- /dev/null +++ b/tests/comsub4.sub @@ -0,0 +1,27 @@ +x=$(cat <<'EOT' +d \ +g +EOT +) + +echo "$x" +unset x + +x=$( cat <<\EOT\ +4 +d \ +g +EOT4 +) + +echo "$x" +unset x + +x=$( cat <<\EOT +d \ +g +EOT +) + +echo "$x" + |
