Re: Multiline editing breaks if the previous output doesn't end in newline

2022-10-29 Thread Koichi Murase
2022年10月29日(土) 15:44 Albert Vaca Cintora :
> On Sat, Oct 29, 2022 at 7:28 AM Koichi Murase  wrote:
> > shopt -s checkwinsize
> > { ! type -t tput || tput xenl || tput xn; } &>/dev/null; 
> > _prompt_xenl_offset=$?
> > _prompt_newline() { (:); printf '\e[m%-*s\r\e[K'
> > "$((COLUMNS-_prompt_xenl_offset))" '[EOF]'; }
> > PROMPT_COMMAND+=(_prompt_newline)
>
> It would be great if this got fixed in bash itself, but in the
> meantime this workaround will help, thanks :)
>
> I've noted that it creates some artifacts when you resize the terminal
> after a command that ends without a newline, though.

Isn't that the same for zsh and fish?

> Would you mind explaining the code a bit? Eg: why is  "(:);" in there,

To make Bash update COLUMNS. The manual (see below) says `external
command', but a subshell () works as well.

>From Bash Reference Manual
:
> checkwinsize
>
> If set, Bash checks the window size after each external (non-builtin)
> command and, if necessary, updates the values of LINES and COLUMNS.
> This option is enabled by default.

> or why do we need $_prompt_xenl_offset ?

Because the behavior depends on the terminal capability
"eat_newline_glitch" ("xenl" in terminfo name / "xn" in termcap name).
In a terminal without "eat_newline_glitch", when there are as many
characters in the line as the columns, the cursor automatically moves
to the next line:

$ printf '%*s\rY' "$COLUMNS" X
|  ... X|
|Y  |

But in a terminal with "eat_newline_glitch", the cursor stays at the
last column with an intermediate state:

$ printf '%*s\rY' "$COLUMNS" X
|Y ... X|

VT and XTerm behave in the latter way, and the recent terminals
emulate VT/XTerm, but some terminals/consoles behave in the former
way. To support both types of terminals, one needs to adjust the
number of characters in the line. If you only use the VT terminal
emulators, you can just drop the processing related to
"_prompt_xenl_offset" and just write it like

PROMPT_COMMAND+=('(:); printf "\e[m%-${COLUMNS}s\r\e[K" "[EOF]"')



Re: Multiline editing breaks if the previous output doesn't end in newline

2022-10-29 Thread Koichi Murase
> $ printf '%*s\rY' "$COLUMNS" X
> |  ... X|
> |Y  |

P.S. Here I used `|' to represent the left and right boundaries of the
terminal display area.



Re: bash "extglob" needs to upgrade at least like zsh "kshglob"

2022-10-29 Thread Greg Wooledge
On Sat, Oct 29, 2022 at 04:50:00PM +1100, Martin D Kealey wrote:
> This seems like a good reason to simply translate extglobs into regexes,
> which should run in linear time, rather than put effort into building and
> debugging a parallel implementation.

This isn't straightforward, because of the !(list) feature of extglob.
There's no analogous construct for that in standard regexes.



Remove unnecessary checks before calls of the function “free”

2022-10-29 Thread Markus Elfring
Hello,

The function “free” is documented in the way that no action shall occur for
a passed null pointer. It is therefore not needed that a function caller
repeats a corresponding check.
https://stackoverflow.com/questions/18775608/free-a-null-pointer-anyway-or-check-first

This issue can be fixed also by using the software “Coccinelle 1.1.1”.

Regards,
Markus
diff --git a/bashline.c b/bashline.c
index c85b05b6..81010b68 100644
--- a/bashline.c
+++ b/bashline.c
@@ -1670,8 +1670,7 @@ attempt_shell_completion (text, start, end)
   char *n;
 
   /* XXX - don't free the members */
-  if (prog_complete_matches)
-	free (prog_complete_matches);
+  free (prog_complete_matches);
   prog_complete_matches = (char **)NULL;
 
   os = start;
@@ -1991,8 +1990,7 @@ command_word_completion_function (hint_text, state)
 
   if (dequoted_hint && dequoted_hint != hint)
 	free (dequoted_hint);
-  if (hint)
-	free (hint);
+  free (hint);
 
   mapping_over = searching_path = 0;
   hint_is_dir = CMD_IS_DIR (hint_text);
@@ -2056,8 +2054,7 @@ command_word_completion_function (hint_text, state)
 	}
 	  hint_len = strlen (hint);
 
-	  if (filename_hint)
-	free (filename_hint);
+	  free (filename_hint);
 
 	  fnhint = filename_hint = savestring (hint);
 
@@ -2093,14 +2090,12 @@ command_word_completion_function (hint_text, state)
   /* Initialize the variables for each type of command word. */
   local_index = 0;
 
-  if (varlist)
-	free (varlist);
+  free (varlist);
 
   varlist = all_visible_functions ();
 
 #if defined (ALIAS)
-  if (alias_list)
-	free (alias_list);
+  free (alias_list);
 
   alias_list = all_aliases ();
 #endif /* ALIAS */
@@ -2273,8 +2268,7 @@ globword:
 
   if (fnhint && fnhint != filename_hint)
 	free (fnhint);
-  if (filename_hint)
-	free (filename_hint);
+  free (filename_hint);
 
   filename_hint = sh_makepath (current_path, hint, 0);
   /* Need a quoted version (though it doesn't matter much in most
@@ -2409,8 +2403,7 @@ command_subst_completion_function (text, state)
 
   if (state == 0)
 {
-  if (filename_text)
-	free (filename_text);
+  free (filename_text);
   orig_start = text;
   if (*text == '`')
 	text++;
@@ -2421,8 +2414,7 @@ command_subst_completion_function (text, state)
   rl_completion_suppress_quote = 1;
   start_len = text - orig_start;
   filename_text = savestring (text);
-  if (matches)
-	free (matches);
+  free (matches);
 
   /*
* At this point we can entertain the idea of re-parsing
@@ -2491,8 +2483,7 @@ variable_completion_function (text, state)
 
   if (!state)
 {
-  if (varname)
-	free (varname);
+  free (varname);
 
   first_char_loc = 0;
   first_char = text[0];
diff --git a/builtins/common.c b/builtins/common.c
index 19b00c4d..b047c44d 100644
--- a/builtins/common.c
+++ b/builtins/common.c
@@ -434,8 +434,7 @@ shift_args (times)
 
   while (times-- > 0)
 {
-  if (dollar_vars[1])
-	free (dollar_vars[1]);
+  free (dollar_vars[1]);
 
   for (count = 1; count < 9; count++)
 	dollar_vars[count] = dollar_vars[count + 1];
diff --git a/builtins/mkbuiltins.c b/builtins/mkbuiltins.c
index f505ebde..350d8bbd 100644
--- a/builtins/mkbuiltins.c
+++ b/builtins/mkbuiltins.c
@@ -261,8 +261,7 @@ main (argc, argv)
 	{
 	  int len;
 
-	  if (error_directory)
-	free (error_directory);
+	  free (error_directory);
 
 	  error_directory = xmalloc (2 + strlen (argv[arg_index]));
 	  strcpy (error_directory, argv[arg_index]);
@@ -448,9 +447,7 @@ void
 array_free (array)
  ARRAY *array;
 {
-  if (array->array)
-free (array->array);
-
+  free (array->array);
   free (array);
 }
 
@@ -695,8 +692,7 @@ free_defs (defs)
   register int i;
   register BUILTIN_DESC *builtin;
 
-  if (defs->production)
-free (defs->production);
+  free (defs->production);
 
   if (defs->lines)
 array_free (defs->lines);
diff --git a/examples/loadables/csv.c b/examples/loadables/csv.c
index 75b37725..de7564a2 100644
--- a/examples/loadables/csv.c
+++ b/examples/loadables/csv.c
@@ -96,8 +96,7 @@ csvsplit (csv, line, dstring)
 }
   while (delim == *dstring);
 
-  if (xbuf)
-free (xbuf);
+  free (xbuf);
 
   return (rval = ind);/* number of fields */
 }
diff --git a/examples/loadables/dsv.c b/examples/loadables/dsv.c
index 70e59cbc..187ef685 100644
--- a/examples/loadables/dsv.c
+++ b/examples/loadables/dsv.c
@@ -156,8 +156,7 @@ dsvsplit (dsv, line, dstring, flags)
 }
   while (delim == *dstring);
 
-  if (xbuf)
-free (xbuf);
+  free (xbuf);
 
   return (rval = ind);/* number of fields */
 }
diff --git a/execute_cmd.c b/execute_cmd.c
index e5c6b9ab..b3b0aa31 100644
--- a/execute_cmd.c
+++ b/execute_cmd.c
@@ -5527,8 +5527,7 @@ execute_builtin_or_function (words, builtin, var, redirects,
   nfifo = num_fifos ();
   if (nfifo > ofifo)
 close_new_fifos (ofifo_list, osize);
-  if (ofifo_list)
-free (of

Re: Subsequent Here Doc/String Never Evaluated in Process Substitution

2022-10-29 Thread Martin D Kealey
On Fri, 28 Oct 2022 at 20:37,  wrote:

> Thank you for the awesome shell.  I noticed the following after upgrading
> from 5.1.16-3 to 5.2.2-2 on Fedora.  It actually resulted in a minor
> amount
> of data loss.


After fixing the attached file to remove the carriage returns, I was able
to reproduce the fault using Bash v5.2.0 rc2

Running with « bash-5.2.0-r2 -x ConsecutiveHereDocStringBug », it appears
that the "cat" on the line following the assignment to uS is subsumed into
it, and then the redirection on the assignment is ignored.

(I discovered this when I attempted to insert « printf HERE\\n >&2 »
between the assignment and the cat, only to then see HERE\n: command not
found.)

Indeed, it appears that the command following the "do" always absorbs the
first word from the second command, despite the line break between them.

This does seem like a fairly serious issue if it's present in the 5.2.0
release.

-Martin


Re: Multiline editing breaks if the previous output doesn't end in newline

2022-10-29 Thread Martin D Kealey
This sounds like a bug in whatever is producing the output. POSIX text
files have a newline terminating every line; that description includes
streams going through pipes and tty devices if they purport to be text.

It's fairly simple to fix this by adding this to the end of your .bashrc
(or the system /etc/bashrc):

 PS1='\[\e[1;7;31m\e[K<<\e[$((COLUMNS-8))C<<\r\e[m\e[2K\]'"$PS1"

or you might prefer this version:

 _MissingEOL='<<< missing EOL ' # your choice of text here
 for (( t = COLUMNS<250 ? 1000 : COLUMNS*4; ${#_MissingEOL} < t ;)) do
_MissingEOL=$_MissingEOL$_MissingEOL ; done
 PS1='\[\e[1;7;31m${_MissingEOL:0:COLUMNS}\r\e[m\e[2K\]'"$PS1"

These will mark an incomplete line with a red chevron to highlight the
erroneous output, and move the cursor to the correct position on the next
line. If this makes copying and pasting just slightly awkward, that would
prompt me to fix the broken program, or to remember to add «; echo» when
running it.

(You might want to make this contingent on TERM being a known
ANSI-compatible terminal type, or verifying the output of tput.)

Sadly, there is an increasing number of common new utilities that don't
honour the POSIX requirements for a text stream, such as 'jq' in its
"brief" mode; if you come across these, please file bug reports on them. If
the maintainers push back, please point them at the POSIX standard.

-Martin