]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
fix for displaying `local -'; fix for trap and POSIX interp 1602; fix for readline...
authorChet Ramey <chet.ramey@case.edu>
Mon, 7 Nov 2022 15:25:28 +0000 (10:25 -0500)
committerChet Ramey <chet.ramey@case.edu>
Mon, 7 Nov 2022 15:25:28 +0000 (10:25 -0500)
14 files changed:
CWRU/CWRU.chlog
builtins/caller.def
builtins/common.c
builtins/setattr.def
execute_cmd.c
jobs.c
lib/readline/display.c
lib/sh/tmpfile.c
po/hr.gmo
po/hr.po
subst.c
tests/trap6.sub
trap.c
trap.h

index 824325bc8190bdce4ab9ca7e9b0b2332f15a97d4..d5f4ad42af7d62df3c908a5ec69344b7de9ee0fc 100644 (file)
@@ -4291,3 +4291,49 @@ lib/readline/isearch.c
 
 lib/readline/misc.c
        - rl_digit_argument: call _rl_del_executing_keyseq after rl_execute_next
+
+                                  11/3
+                                  ----
+builtins/setattr.def
+       - show_localname_attributes: special-case "-" local variable, since
+         there is no `declare -' equivalent.
+         Reported by Emanuele Torre <torreemanuele6@gmail.com>.
+
+                                  11/4
+                                  ----
+lib/sh/tmpfile.c
+       - sh_mktmpname,sh_mktmpfd: use get_urandom32() instead of random() if
+         we're not using mktemp or mkstemp and the system provides the
+         appropriate support
+
+trap.c
+       - trap_variable_context: new variable, set to variable_context every
+         time a trap string runs (that is, every time running_trap is set to
+         a value > 0) in _run_trap_internal, run_exit_trap, run_pending_traps
+
+trap.h
+       - trap_variable_context: extern declaration
+
+builtins/common.c
+       - get_exitstat: if the `return' builtin is running, we are running a
+         trap (but not the DEBUG trap), and the return would cause the trap
+         string to complete (variable_context == trap_variable_context, so
+         we haven't executed another shell function), use the last command
+         exit value as the return status. POSIX interp 1602, from
+         https://www.austingroupbugs.net/view.php?id=1602
+
+                                  11/4
+                                  ----
+
+lib/readline/display.c
+       - local_prompt_invis_chars: new array variable, similar to
+         local_prompt_newlines, that keeps track of the number of invisible
+         characters on each line of the prompt string. Use in WRAP_OFFSET
+         macro with eye to using in W_OFFSET as well. Used for the case where
+         the last line of the prompt is not the last line with invisible
+         characters. Can use this in more calculations replacing wrap_offset
+         and prompt_invis_chars_first_line going forward. Inspired by report
+         from https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1018851
+       - update_line: use local_prompt_invis_chars to set _rl_last_c_pos
+         correctly when on a non-terminal prompt line that contains
+         invisible characters
index 1000979dd90b60aba6e6ce83dc8962edcb57f881..57746a299a918660a87defafc3d0c9abb7010238 100644 (file)
@@ -140,7 +140,12 @@ N_("Returns the context of the current subroutine call.\n\
     provide a stack trace.\n\
     \n\
     The value of EXPR indicates how many call frames to go back before the\n\
-    current one; the top frame is frame 0."),
+    current one; the top frame is frame 0.\n\
+    \n\
+    Exit Status:\n\
+    Returns 0 unless the shell is not executing a shell function or EXPR\n\
+    is invalid."
+),
   (char *)NULL
 };
 
index 19b00c4d04f2437f019907ffca5fb201eb5f95a9..b9705c02d6aaabcb31c51bd10c58e7726a5c408e 100644 (file)
@@ -564,13 +564,16 @@ get_exitstat (list)
 
   if (list == 0)
     {
-      /* If we're not running the DEBUG trap, the return builtin, when not
-        given any arguments, uses the value of $? before the trap ran.  If
-        given an argument, return uses it.  This means that the trap can't
-        change $?.  The DEBUG trap gets to change $?, though, since that is
-        part of its reason for existing, and because the extended debug mode
-        does things with the return value. */
-      if (this_shell_builtin == return_builtin && running_trap > 0 && running_trap != DEBUG_TRAP+1)
+      /* If we're not running the DEBUG trap, and haven't executed a shell
+        function from the trap action, the return builtin, when not given
+        any arguments, uses the value of $? before the trap ran. The business
+        about executing a shell function from the trap action is from POSIX
+        interp 1602 (10/2022). If given an argument, return uses it
+        unconditionally. This means that the trap can't change $?. The DEBUG
+        trap gets to change $?, though, since that is part of its reason for
+        existing, and because the extended debug mode does things with the
+        return value. */
+      if (this_shell_builtin == return_builtin && running_trap > 0 && running_trap != DEBUG_TRAP+1 && variable_context == trap_variable_context)
        return (trap_saved_exit_value);
       return (last_command_exit_value);
     }
index 50c8edf6834fd3c80f92b638034de7aa88412c9b..43d4313829d41cebdb24ec9aee047875c56d77f6 100644 (file)
@@ -38,16 +38,16 @@ $PRODUCES setattr.c
 #include "../flags.h"
 #include "common.h"
 #include "bashgetopt.h"
+#include "builtext.h"
 
 extern sh_builtin_func_t *this_shell_builtin;
 
-#ifdef ARRAY_VARS
-extern int declare_builtin PARAMS((WORD_LIST *));
-#endif
-
 #define READONLY_OR_EXPORT \
   (this_shell_builtin == readonly_builtin || this_shell_builtin == export_builtin)
 
+#define SPECIAL_LOCAL(n) \
+  (this_shell_builtin == local_builtin && n[0] == '-' && n[1] == 0)
+
 $BUILTIN export
 $FUNCTION export_builtin
 $SHORT_DOC export [-fn] [name[=value] ...] or export -p
@@ -561,7 +561,11 @@ show_localname_attributes (name, nodefs)
 
   if (var && local_p (var) && var->context == variable_context)        /* show every variable with attributes, even unset ones */
     {
-      show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
+      /* There is no equivalent `declare -'. */
+      if (STREQ (var->name, "-"))
+       printf ("local -\n");
+      else
+       show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
       return (0);
     }
   else
index a7f4217523f74ce7b7082cefe20ce8a17aa5fb08..b99c972b320ad98473eadd530e11b64747c70001 100644 (file)
@@ -1676,8 +1676,8 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
       dispose_redirects (command->redirects);
       command->redirects = (REDIRECT *)NULL;
 #if 0
-      /* TAG: bash-5.3 kre 10/24/2022 */
 #if defined (PROCESS_SUBSTITUTION) && defined (JOB_CONTROL)
+      /* TAG: bash-5.3 kre 10/24/2022 */
       if (user_subshell && command->type == cm_subshell)
        {
          procsub_clear ();
@@ -1685,7 +1685,7 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
        }
 #endif
 #endif
-      }
+    }
 
   if (command->type == cm_subshell)
     tcom = command->value.Subshell->command;
diff --git a/jobs.c b/jobs.c
index 859a0ff5f976445c671e32f1f71ebb7d8487d8f2..03a9605302668a13cf99e68f07f8e99ae2570171 100644 (file)
--- a/jobs.c
+++ b/jobs.c
@@ -2712,7 +2712,7 @@ wait_for_background_pids (ps)
     procsub_waitpid (last_procsub_child->pid);
   reap_procsubs ();    /* closes fd */
 #endif
-      
+
   /* POSIX.2 says the shell can discard the statuses of all completed jobs if
      `wait' is called with no arguments. */
   mark_dead_jobs_as_notified (1);
index df9d74925772f1835783a8a438dce98ffaca9e73..f7ffd465cb82d78d60022431dbb5f1df6e8b7b67 100644 (file)
@@ -282,6 +282,10 @@ static int prompt_physical_chars;
    characters in the prompt or use heuristics about where they are. */
 static int *local_prompt_newlines;
 
+/* An array saying how many invisible characters are in each line of the
+   prompt. */
+static int *local_prompt_invis_chars;
+
 /* set to a non-zero value by rl_redisplay if we are marking modified history
    lines and the current line is so marked. */
 static int modmark;
@@ -295,6 +299,7 @@ static int line_totbytes;
 static char *saved_local_prompt;
 static char *saved_local_prefix;
 static int *saved_local_prompt_newlines;
+static int *saved_local_prompt_invis_chars;
 
 static int saved_last_invisible;
 static int saved_visible_length;
@@ -356,7 +361,7 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp)
 {
   char *r, *ret, *p, *igstart, *nprompt, *ms;
   int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars;
-  int mlen, newlines, newlines_guess, bound, can_add_invis;
+  int mlen, newlines, newlines_guess, bound, can_add_invis, lastinvis;
   int mb_cur_max;
 
   /* We only expand the mode string for the last line of a multiline prompt
@@ -399,7 +404,8 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp)
            *vlp = l;
 
          local_prompt_newlines = (int *) xrealloc (local_prompt_newlines, sizeof (int) * 2);
-         local_prompt_newlines[0] = 0;
+         local_prompt_invis_chars = (int *) xrealloc (local_prompt_invis_chars, sizeof (int) * 2);
+         local_prompt_newlines[0] = local_prompt_invis_chars[0] = 0;
          local_prompt_newlines[1] = -1;
 
          return r;
@@ -414,15 +420,20 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp)
   newlines_guess = (_rl_screenwidth > 0) ? APPROX_DIV(l,  _rl_screenwidth) : APPROX_DIV(l, 80);
   local_prompt_newlines = (int *) xrealloc (local_prompt_newlines, sizeof (int) * (newlines_guess + 1));
   local_prompt_newlines[newlines = 0] = 0;
+  local_prompt_invis_chars = (int *) xrealloc (local_prompt_invis_chars, sizeof (int) * (newlines_guess + 1));
+  local_prompt_invis_chars[0] = 0;
   for (rl = 1; rl <= newlines_guess; rl++)
-    local_prompt_newlines[rl] = -1;
+    {
+      local_prompt_newlines[rl] = -1;
+      local_prompt_invis_chars[rl] = 0;
+    }
 
   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 */
   igstart = 0;         /* we're not ignoring any characters yet */
 
-  for (ignoring = last = ninvis = 0, p = nprompt; p && *p; p++)
+  for (ignoring = last = ninvis = lastinvis = 0, p = nprompt; p && *p; p++)
     {
       /* This code strips the invisible character string markers
         RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
@@ -447,6 +458,8 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp)
                 counter. */
              if (invflset && newlines == 1)
                invfl = ninvis;
+             local_prompt_invis_chars[newlines - 1] = ninvis - lastinvis;
+             lastinvis = ninvis;
            }
          if (p != (igstart + 1))
            last = r - ret - 1;
@@ -511,6 +524,8 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp)
              else
                new = r - ret;
              local_prompt_newlines[++newlines] = new;
+             local_prompt_invis_chars[newlines - 1] = ninvis - lastinvis;
+             lastinvis = ninvis;
            }
 
          /* What if a physical character of width >= 2 is split? There is
@@ -525,6 +540,9 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp)
   if (rl <= _rl_screenwidth)
     invfl = ninvis;
 
+  /* Make sure we account for invisible characters on the last line. */
+  local_prompt_invis_chars[newlines] = ninvis - lastinvis;
+
   *r = '\0';
   if (lp)
     *lp = rl;
@@ -964,6 +982,9 @@ rl_redisplay (void)
      in the first physical line of the prompt.
      wrap_offset - prompt_invis_chars_first_line is usually the number of
      invis chars on the second (or, more generally, last) line. */
+  /* XXX - There is code that assumes that all the invisible characters occur
+     on the first and last prompt lines; change that to use
+     local_prompt_invis_chars */
 
   /* This is zero-based, used to set the newlines */
   prompt_lines_estimate = lpos / _rl_screenwidth;
@@ -982,6 +1003,7 @@ rl_redisplay (void)
        }  
 
       /* Now set lpos from the last newline */
+      /* XXX - change to use local_prompt_invis_chars[] */
       if (mb_cur_max > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
         lpos = _rl_col_width (local_prompt, temp, local_prompt_len, 1) - (wrap_offset - prompt_invis_chars_first_line);
       else
@@ -1249,10 +1271,9 @@ rl_redisplay (void)
             second and subsequent lines start at inv_lbreaks[N], offset by
             OFFSET (which has already been calculated above).  */
 
-#define INVIS_FIRST()  (prompt_physical_chars > _rl_screenwidth ? prompt_invis_chars_first_line : wrap_offset)
-#define WRAP_OFFSET(line, offset)  ((line == 0) \
-                                       ? (offset ? INVIS_FIRST() : 0) \
-                                       : ((line == prompt_last_screen_line) ? wrap_offset-prompt_invis_chars_first_line : 0))
+#define INVIS_FIRST()  (local_prompt_invis_chars[0])
+#define WRAP_OFFSET(line, offset)  ((line <= prompt_last_screen_line) ? local_prompt_invis_chars[line] : 0)
+
 #define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
 #define VIS_LLEN(l)    ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
 #define INV_LLEN(l)    (inv_lbreaks[l+1] - inv_lbreaks[l])
@@ -1263,6 +1284,9 @@ rl_redisplay (void)
 #define INV_LINE(line) (invisible_line + inv_lbreaks[line])
 #define INV_LINE_FACE(line) (inv_face + inv_lbreaks[line])
 
+#define INV_CHARS_CURRENT_PROMPT_LINE(line) \
+       (local_prompt_invis_chars[line] > 0)
+
 #define OLD_CPOS_IN_PROMPT() (cpos_adjusted == 0 && \
                        _rl_last_c_pos != o_cpos && \
                        _rl_last_c_pos > wrap_offset && \
@@ -1319,6 +1343,7 @@ rl_redisplay (void)
                   between the first and last lines of the prompt, if the 
                   prompt consumes more than two lines. It's usually right */
                /* XXX - not sure this is ever executed */
+               /* XXX - use local_prompt_invis_chars[linenum] */
                _rl_last_c_pos -= (wrap_offset-prompt_invis_chars_first_line);
 
              /* If this is the line with the prompt, we might need to
@@ -1413,6 +1438,7 @@ rl_redisplay (void)
             only need to reprint it if the cursor is before the last
             invisible character in the prompt string. */
          /* XXX - why not use local_prompt_len? */
+         /* XXX - This is right only if the prompt is a single line. */
          nleft = prompt_visible_length + wrap_offset;
          if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
              _rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt)
@@ -1895,6 +1921,8 @@ update_line (char *old, char *old_face, char *new, char *new_face, int current_l
       /* See comments at dumb_update: for an explanation of this heuristic */
       if (nmax < omax)
        goto clear_rest_of_line;
+      /* XXX - need to use WRAP_OFFSET(current_line, wrap_offset) instead of
+        W_OFFSET - XXX */
       else if ((nmax - W_OFFSET(current_line, wrap_offset)) < (omax - W_OFFSET (current_line, visible_wrap_offset)))
        goto clear_rest_of_line;
       else
@@ -2076,7 +2104,7 @@ update_line (char *old, char *old_face, char *new, char *new_face, int current_l
     }
 
   /* count of invisible characters in the current invisible line. */
-  current_invis_chars = W_OFFSET (current_line, wrap_offset);
+  current_invis_chars = WRAP_OFFSET (current_line, wrap_offset);
   if (_rl_last_v_pos != current_line)
     {
       _rl_move_vert (current_line);
@@ -2140,6 +2168,7 @@ update_line (char *old, char *old_face, char *new, char *new_face, int current_l
          else
            /* We take wrap_offset into account here so we can pass correct
               information to _rl_move_cursor_relative. */
+           /* XXX - can use local_prompt_invis_chars[0] instead of wrap_offset */
            _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff, 1) - wrap_offset + modmark;
          cpos_adjusted = 1;
        }
@@ -2183,6 +2212,7 @@ dumb_update:
                        wrap_offset-prompt_invis_chars_first_line
                     on the assumption that this is the number of invisible
                     characters in the last line of the prompt. */
+                 /* XXX - CHANGE THIS USING local_prompt_invis_chars[current_line] */
                  if (wrap_offset > prompt_invis_chars_first_line &&
                      current_line == prompt_last_screen_line &&
                      prompt_physical_chars > _rl_screenwidth &&
@@ -2201,6 +2231,20 @@ dumb_update:
                           wrap_offset >= prompt_invis_chars_first_line &&
                           _rl_horizontal_scroll_mode == 0)
                    ADJUST_CPOS (prompt_invis_chars_first_line);
+                 /* XXX - This is experimental. It's a start at supporting
+                    prompts where a non-terminal line contains the last
+                    invisible characters. We assume that we can use the
+                    local_prompt_invis_chars array and that the current line
+                    is completely filled with characters to _rl_screenwidth,
+                    so we can either adjust by the number of bytes in the
+                    current line or just go straight to _rl_screenwidth */
+                 else if (current_line > 0 && current_line < prompt_last_screen_line &&
+                          INV_CHARS_CURRENT_PROMPT_LINE(current_line) &&
+                          _rl_horizontal_scroll_mode == 0)
+                   {
+                     _rl_last_c_pos = _rl_screenwidth;
+                     cpos_adjusted = 1;
+                   }
                }
              else
                _rl_last_c_pos += temp;
@@ -2212,6 +2256,8 @@ dumb_update:
             know for sure, so we use another heuristic calclulation below. */
          if (nmax < omax)
            goto clear_rest_of_line;    /* XXX */
+         /* XXX - use WRAP_OFFSET(current_line, wrap_offset) here instead of
+            W_OFFSET since current_line == 0 */
          else if ((nmax - W_OFFSET(current_line, wrap_offset)) < (omax - W_OFFSET (current_line, visible_wrap_offset)))
            goto clear_rest_of_line;
          else
@@ -3099,10 +3145,12 @@ rl_save_prompt (void)
   saved_invis_chars_first_line = prompt_invis_chars_first_line;
   saved_physical_chars = prompt_physical_chars;
   saved_local_prompt_newlines = local_prompt_newlines;
+  saved_local_prompt_invis_chars = local_prompt_invis_chars;
 
   local_prompt = local_prompt_prefix = (char *)0;
   local_prompt_len = 0;
   local_prompt_newlines = (int *)0;
+  local_prompt_invis_chars = (int *)0;
 
   prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0;
   prompt_invis_chars_first_line = prompt_physical_chars = 0;
@@ -3114,11 +3162,13 @@ rl_restore_prompt (void)
   FREE (local_prompt);
   FREE (local_prompt_prefix);
   FREE (local_prompt_newlines);
+  FREE (local_prompt_invis_chars);
 
   local_prompt = saved_local_prompt;
   local_prompt_prefix = saved_local_prefix;
   local_prompt_len = saved_local_length;
   local_prompt_newlines = saved_local_prompt_newlines;
+  local_prompt_invis_chars = saved_local_prompt_invis_chars;
 
   prompt_prefix_length = saved_prefix_length;
   prompt_last_invisible = saved_last_invisible;
@@ -3131,7 +3181,7 @@ rl_restore_prompt (void)
   saved_local_length = 0;
   saved_last_invisible = saved_visible_length = saved_prefix_length = 0;
   saved_invis_chars_first_line = saved_physical_chars = 0;
-  saved_local_prompt_newlines = 0;
+  saved_local_prompt_newlines = saved_local_prompt_invis_chars = 0;
 }
 
 char *
index ef8b067bec7d4896c2ae6a86e9b9ed6b65ce125f..d107e745c3e0ef51fe74e1cc6f77ed34dfc365d1 100644 (file)
 extern int errno;
 #endif
 
+#if defined (HAVE_GETRANDOM) || defined (HAVE_ARC4RANDOM) || defined (HAVE_GETENTROPY)
+#  define USE_URANDOM32
+#endif
+
 #define BASEOPENFLAGS  (O_CREAT | O_TRUNC | O_EXCL | O_BINARY)
 
 #define DEFAULT_TMPDIR         "."     /* bogus default, should be changed */
@@ -163,13 +167,21 @@ sh_mktmpname (nameroot, flags)
       filename = NULL;
     }
 #else  /* !USE_MKTEMP */
+#ifndef USE_URANDOM32
   sh_seedrand ();
+#endif
   while (1)
     {
+      unsigned long x;
+#ifdef USE_URANDOM32
+      x = (unsigned long) ((flags & MT_USERANDOM) ? get_urandom32 () : ntmpfiles++);
+#else
+      x = (unsigned long) ((flags & MT_USERANDOM) ? random () : ntmpfiles++);
+#endif
       filenum = (filenum << 1) ^
                (unsigned long) time ((time_t *)0) ^
                (unsigned long) dollar_dollar_pid ^
-               (unsigned long) ((flags & MT_USERANDOM) ? random () : ntmpfiles++);
+               x;
       sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum);
       if (tmpnamelen > 0 && tmpnamelen < 32)
        filename[tdlen + 1 + tmpnamelen] = '\0';
@@ -221,13 +233,21 @@ sh_mktmpfd (nameroot, flags, namep)
     *namep = filename;
   return fd;
 #else /* !USE_MKSTEMP */
+#ifndef USE_URANDOM32
   sh_seedrand ();
+#endif
   do
     {
+      unsigned long x;
+#ifdef USE_URANDOM32
+      x = (unsigned long) ((flags & MT_USERANDOM) ? get_urandom32 () : ntmpfiles++);
+#else
+      x = (unsigned long) ((flags & MT_USERANDOM) ? random () : ntmpfiles++);
+#endif
       filenum = (filenum << 1) ^
                (unsigned long) time ((time_t *)0) ^
                (unsigned long) dollar_dollar_pid ^
-               (unsigned long) ((flags & MT_USERANDOM) ? random () : ntmpfiles++);
+               x;
       sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum);
       if (tmpnamelen > 0 && tmpnamelen < 32)
        filename[tdlen + 1 + tmpnamelen] = '\0';
index 228b369eecd208f14b7da572944d2bd3c66110c3..2ac09d9668627399041b601ef76378d982538276 100644 (file)
Binary files a/po/hr.gmo and b/po/hr.gmo differ
index 624e0d0104d28f87e3bae4fae2c3c91a1d54d7a3..9b34f029dbc451039929831a6e7d138e98748543 100644 (file)
--- a/po/hr.po
+++ b/po/hr.po
@@ -228,7 +228,7 @@ msgstr "nevaljan heksadecimalni broj"
 
 #: builtins/common.c:244 expr.c:1574
 msgid "invalid number"
-msgstr "nevaljan broj"
+msgstr "nevaljani broj"
 
 #: builtins/common.c:252
 #, c-format
@@ -315,7 +315,7 @@ msgstr "%s: greška u određivanju trenutnog direktorija: %s: %s\n"
 #: builtins/common.c:708 builtins/common.c:710
 #, c-format
 msgid "%s: ambiguous job spec"
-msgstr "%s: oznaka posla nije jednoznačna"
+msgstr "%s: dvosmislena oznaka posla"
 
 #: builtins/common.c:971
 msgid "help not available in this version"
@@ -508,7 +508,7 @@ msgstr "posao %d započet je bez upravljanja poslovima"
 #: builtins/getopt.c:110
 #, c-format
 msgid "%s: illegal option -- %c\n"
-msgstr "%s: neispravna opcija -- %c\n"
+msgstr "%s: nelegalna opcija -- %c\n"
 
 #: builtins/getopt.c:111
 #, c-format
@@ -995,7 +995,7 @@ msgstr "nepoznata greška naredbe"
 
 #: error.c:489
 msgid "bad command type"
-msgstr "loša vrsta naredbe"
+msgstr "loš tip naredbe"
 
 #: error.c:490
 msgid "bad connector"
@@ -1098,7 +1098,7 @@ msgstr "podlijevanje stȏga rekurzija (prazni stȏg)"
 
 #: expr.c:478
 msgid "syntax error in expression"
-msgstr "sintaktička greška u izrazu"
+msgstr "sintaktična greška u izrazu"
 
 #: expr.c:522
 msgid "attempted assignment to non-variable"
@@ -1106,7 +1106,7 @@ msgstr "pokušaj dodjeljivanja ne-varijabli (objektu koji nije varijabla)"
 
 #: expr.c:531
 msgid "syntax error in variable assignment"
-msgstr "sintaktička greška u dodjeljivanju varijabli"
+msgstr "sintaktična greška u dodjeljivanju varijabli"
 
 #: expr.c:545 expr.c:912
 msgid "division by 0"
@@ -1134,11 +1134,11 @@ msgstr "nedostaje „)“"
 
 #: expr.c:1108 expr.c:1492
 msgid "syntax error: operand expected"
-msgstr "sintaktička greška: očekivan je operand"
+msgstr "sintaktična greška: očekivan je operand"
 
 #: expr.c:1494
 msgid "syntax error: invalid arithmetic operator"
-msgstr "sintaktička greška: nevaljan aritmetički operator"
+msgstr "sintaktična greška: nevaljan aritmetički operator"
 
 #: expr.c:1518
 #, c-format
@@ -1254,7 +1254,7 @@ msgstr "Nepoznata izlazna vrijednost (izlazni kȏd)Nepoznato"
 #: jobs.c:1990
 #, c-format
 msgid "(core dumped) "
-msgstr "(snimka (core dump) memorije je spremljena!) "
+msgstr "(ispis memorije je spremljen!) "
 
 #: jobs.c:2009
 #, c-format
@@ -1308,7 +1308,7 @@ msgstr "%s: redak %d: "
 #: jobs.c:4321 nojobs.c:921
 #, c-format
 msgid " (core dumped)"
-msgstr " (snimka (core dump) memorije je spremljena!)"
+msgstr " (ispis memorije je spremljen!)"
 
 #: jobs.c:4333 jobs.c:4346
 #, c-format
@@ -1471,21 +1471,21 @@ msgstr "Pošta u %s je već pročitana\n"
 
 #: make_cmd.c:314
 msgid "syntax error: arithmetic expression required"
-msgstr "sintaktička greška: nužan je aritmetički izraz"
+msgstr "sintaktična greška: nužan je aritmetički izraz"
 
 #: make_cmd.c:316
 msgid "syntax error: `;' unexpected"
-msgstr "sintaktička greška: neočekivan „;“ znak"
+msgstr "sintaktična greška: neočekivan „;“ znak"
 
 #: make_cmd.c:317
 #, c-format
 msgid "syntax error: `((%s))'"
-msgstr "sintaktička greška: „((%s))“"
+msgstr "sintaktična greška: „((%s))“"
 
 #: make_cmd.c:569
 #, c-format
 msgid "make_here_document: bad instruction type %d"
-msgstr "make_here_document(): loša vrsta instrukcije %d"
+msgstr "make_here_document(): loš tip instrukcije %d"
 
 #: make_cmd.c:668
 #, c-format
@@ -1520,11 +1520,11 @@ msgstr "neočekivan kraj datoteke (EOF) pri traženju „]]“"
 #: parse.y:4457
 #, c-format
 msgid "syntax error in conditional expression: unexpected token `%s'"
-msgstr "sintaktička greška u uvjetnom izrazu: neočekivan simbol „%s“"
+msgstr "sintaktična greška u uvjetnom izrazu: neočekivan simbol „%s“"
 
 #: parse.y:4461
 msgid "syntax error in conditional expression"
-msgstr "sintaktička greška u uvjetnom izrazu"
+msgstr "sintaktična greška u uvjetnom izrazu"
 
 #: parse.y:4539
 #, c-format
@@ -1580,20 +1580,20 @@ msgstr "neočekivan simbol %d u uvjetnoj naredbi"
 #: parse.y:6118
 #, c-format
 msgid "syntax error near unexpected token `%s'"
-msgstr "sintaktička greška blizu neočekivanog simbola „%s“"
+msgstr "sintaktična greška blizu neočekivanog simbola „%s“"
 
 #: parse.y:6137
 #, c-format
 msgid "syntax error near `%s'"
-msgstr "sintaktička greška blizu „%s“"
+msgstr "sintaktična greška blizu „%s“"
 
 #: parse.y:6151
 msgid "syntax error: unexpected end of file"
-msgstr "sintaktička greška: neočekivani kraj datoteke"
+msgstr "sintaktična greška: neočekivani kraj datoteke"
 
 #: parse.y:6151
 msgid "syntax error"
-msgstr "sintaktička greška"
+msgstr "sintaktična greška"
 
 #: parse.y:6216
 #, c-format
@@ -1650,7 +1650,7 @@ msgstr "deskriptor datoteke je izvan raspona"
 #: redir.c:205
 #, c-format
 msgid "%s: ambiguous redirect"
-msgstr "%s: preusmjeravanje nije jednoznačno"
+msgstr "%s: dvosmisleno preusmjeravanje"
 
 #: redir.c:209
 #, c-format
@@ -1714,7 +1714,7 @@ msgstr "nije moguće pokrenuti debugger; dijagnostika je onemogućena"
 #: shell.c:1658
 #, c-format
 msgid "%s: Is a directory"
-msgstr "%s: to je direktorij"
+msgstr "%s: Je direktorij"
 
 #: shell.c:1907
 msgid "I have no name!"
@@ -1801,7 +1801,7 @@ msgstr "Završi"
 
 #: siglist.c:63
 msgid "Illegal instruction"
-msgstr "Nedopuštena instrukcija"
+msgstr "nelegalna instrukcija"
 
 #: siglist.c:67
 msgid "BPT trace/trap"
@@ -1833,7 +1833,7 @@ msgstr "Segmentacijska greška"
 
 #: siglist.c:99
 msgid "Bad system call"
-msgstr "Loš sustavski poziv"
+msgstr "Loš sustavni poziv"
 
 #: siglist.c:103
 msgid "Broken pipe"
@@ -1893,7 +1893,7 @@ msgstr "Alarm (profil)"
 
 #: siglist.c:167
 msgid "Window changed"
-msgstr "Prozor je promijenjen"
+msgstr "Prozor promijenjen"
 
 #: siglist.c:171
 msgid "Record lock"
@@ -1941,7 +1941,7 @@ msgstr "HFT sekvencija zvukova je završena"
 
 #: siglist.c:215
 msgid "Information request"
-msgstr "Zahtjev za obavijestima"
+msgstr "Zahtjev za informacijama"
 
 #: siglist.c:223 siglist.c:225
 #, c-format
@@ -2086,7 +2086,7 @@ msgstr "nedostaje „]“"
 #: test.c:914
 #, c-format
 msgid "syntax error: `%s' unexpected"
-msgstr "sintaktička greška: neočekivan „%s“"
+msgstr "sintaktična greška: neočekivan „%s“"
 
 #: trap.c:220
 msgid "invalid signal number"
@@ -2134,7 +2134,7 @@ msgstr "%s: varijabli se ne može dodijeliti vrijednost"
 #: variables.c:2818 variables.c:2874
 #, c-format
 msgid "%s: cannot inherit value from incompatible type"
-msgstr "%s: nije moguće naslijediti vrijednost od nekompatibilne vrste"
+msgstr "%s: nije moguće naslijediti vrijednost nekompatibilnog tipa"
 
 #: variables.c:3459
 #, c-format
@@ -2908,8 +2908,8 @@ msgstr ""
 "    Opcije:\n"
 "      -p   rabi zadanu vrijednost za PATH kao garanciju\n"
 "             pronalaženja svih standardnih programa\n"
-"      -v   pokaže ime naredbe koja bi se izvršila\n"
-"      -V   == „-v” ali opširnije\n"
+"      -v   pokaže ime naredbe koja bi se izvršila similar to the „type“ builtin\n"
+"      -V   == kao „-v” ali opširnije\n"
 "\n"
 "    Završi s izlaznim kȏdom NAREDBE\n"
 "    ili s 1 ako NAREDBA nije pronađena."
@@ -4441,7 +4441,7 @@ msgid ""
 "    Exit Status:\n"
 "    Returns success if all of the NAMEs are found; fails if any are not found."
 msgstr ""
-"Prikaže informacije o vrsti naredbe.\n"
+"Prikaže informacije o tipu naredbe.\n"
 "\n"
 "    Pokaže, kako bi se interpretiralo svako dano IME kad bi se IME koristilo\n"
 "    kao naredba.\n"
@@ -5056,7 +5056,7 @@ msgstr ""
 "    HISTSIZE      maksimalni broj redaka koje trenutna ljuska može dosegnuti\n"
 "    HOME          puni naziv staze do vašega vlastitog direktorija\n"
 "    HOSTNAME      ime računala na kojem se izvršava „bash“\n"
-"    HOSTTYPE      vrsta CPU-a na kojem se izvršava „bash“\n"
+"    HOSTTYPE      tip CPU-a na kojem se izvršava „bash“\n"
 "    IGNOREEOF     broj zanemarenih Ctrl-D (EOF) prije zatvaranja ljuske\n"
 "    MACHTYPE      vrsta računala na kojem se izvršava „bash“\n"
 "    MAILCHECK     kako često (u sekundama) „bash“ gleda ima li nove pošte\n"
@@ -5068,7 +5068,7 @@ msgstr ""
 "    PS2           string koji opisuje sekundarni prompt (zadano, „>“)\n"
 "    PWD           puni naziv staze trenutnog radnog direktorija\n"
 "    SHELLOPTS     popis svih omogućenih opcija ljuske\n"
-"    TERM          naziv vrste trenutnog terminala\n"
+"    TERM          naziv tipa trenutnog terminala\n"
 "    TIMEFORMAT    pravilo za format ispisa „time“ statistika\n"
 "    auto_resume   ako nije prazan, učini da se naredbena riječ na naredbenom\n"
 "                    retku prvo potraži na popisu zaustavljenih poslova,\n"
diff --git a/subst.c b/subst.c
index c4fb7732af710a2a14edf59dcee30125682007f4..a72711e7b8c5070efcacabb3d4e58b435f7c162b 100644 (file)
--- a/subst.c
+++ b/subst.c
@@ -3058,7 +3058,12 @@ string_list_pos_params (pchar, list, quoted, pflags)
     {
       tlist = quote_list (list);
       word_list_remove_quoted_nulls (tlist);
+#if 0
       ret = string_list (tlist);
+#else
+      /* TAG:bash-5.3 Aloxaf Yin 9/1/2022 */
+      ret = string_list_dollar_star (tlist, 0, 0);
+#endif
     }
   else if (pchar == '*' && quoted == 0 && ifs_is_null) /* XXX */
     ret = expand_no_split_dollar_star ? string_list_dollar_star (list, quoted, 0) : string_list_dollar_at (list, quoted, 0);   /* Posix interp 888 */
@@ -10367,7 +10372,12 @@ param_expand (string, sindex, quoted, expanded_something,
             quote the whole string, including the separators.  If IFS
             is unset, the parameters are separated by ' '; if $IFS is
             null, the parameters are concatenated. */
+#if 0
          temp = (quoted & (Q_DOUBLE_QUOTES|Q_PATQUOTE)) ? string_list_dollar_star (list, quoted, 0) : string_list (list);
+#else
+         /* TAG:bash-5.3 Aloxaf Yin 9/1/2022 */
+         temp = string_list_dollar_star (list, quoted, 0);
+#endif
          if (temp)
            {
              temp1 = (quoted & Q_DOUBLE_QUOTES) ? quote_string (temp) : temp;
index 72685580d20fe989f5e120f54fbd8023bc673596..9dbb0d6dce95e8014203b1b9b683526a7eb38a79 100644 (file)
@@ -26,3 +26,14 @@ fn
 echo after 2
 
 unset -f fn
+
+# since this sets the exit trap, it has to go last
+
+set +o functrace
+# posix interp 1602
+ReturnFalse()
+{
+       false ; return
+}
+
+trap 'ReturnFalse && echo "woops"' EXIT
diff --git a/trap.c b/trap.c
index dd0245e6dd881fbb33afe1d5ce11448034450188..9cedf7ebb35f5e0db8f526c0001ca27f8c4cbff6 100644 (file)
--- a/trap.c
+++ b/trap.c
@@ -113,6 +113,10 @@ int pending_traps[NSIG];
    trap command (e.g., when `return' is executed in the trap command). */
 int running_trap;
 
+/* The variable context (function execution level) when we began running
+   this trap command. */
+int trap_variable_context;
+
 /* Set to last_command_exit_value before running a trap. */
 int trap_saved_exit_value;
 
@@ -298,7 +302,7 @@ run_pending_traps ()
 {
   register int sig;
   int x;
-  volatile int old_exit_value, old_running;
+  volatile int old_exit_value, old_running, old_context;
   WORD_LIST *save_subst_varlist;
   HASH_TABLE *save_tempenv;
   sh_parser_state_t pstate;
@@ -336,6 +340,7 @@ run_pending_traps ()
   ps = save_pipestatus_array ();
 #endif
   old_running = running_trap;
+  old_context = trap_variable_context;
 
   for (sig = 1; sig < NSIG; sig++)
     {
@@ -345,6 +350,7 @@ run_pending_traps ()
        {
          /* XXX - set last_command_exit_value = trap_saved_exit_value here? */
          running_trap = sig + 1;
+         trap_variable_context = variable_context;
 
          if (sig == SIGINT)
            {
@@ -465,6 +471,7 @@ run_pending_traps ()
                  if (function_code)
                    {
                      running_trap = old_running;               /* XXX */
+                     trap_variable_context = old_context;
                      /* caller will set last_command_exit_value */
                      sh_longjmp (return_catch, 1);
                    }
@@ -473,6 +480,7 @@ run_pending_traps ()
 
          pending_traps[sig] = 0;       /* XXX - move before evalstring? */
          running_trap = old_running;
+         trap_variable_context = old_context;
        }
     }
 
@@ -992,6 +1000,7 @@ run_exit_trap ()
 
       retval = trap_saved_exit_value;
       running_trap = 1;
+      trap_variable_context = variable_context;
 
       code = setjmp_nosigs (top_level);
 
@@ -1047,7 +1056,7 @@ _run_trap_internal (sig, tag)
   char *trap_command, *old_trap;
   int trap_exit_value;
   volatile int save_return_catch_flag, function_code;
-  int old_modes, old_running, old_int;
+  int old_modes, old_running, old_int, old_context;
   int flags;
   procenv_t save_return_catch;
   WORD_LIST *save_subst_varlist;
@@ -1057,7 +1066,7 @@ _run_trap_internal (sig, tag)
   ARRAY *ps;
 #endif
 
-  old_modes = old_running = -1;
+  old_modes = old_running = old_context = -1;
 
   trap_exit_value = function_code = 0;
   trap_saved_exit_value = last_command_exit_value;
@@ -1076,12 +1085,14 @@ _run_trap_internal (sig, tag)
       old_trap = trap_list[sig];
       old_modes = sigmodes[sig];
       old_running = running_trap;
+      old_context = trap_variable_context;
 
       sigmodes[sig] |= SIG_INPROGRESS;
       sigmodes[sig] &= ~SIG_CHANGED;           /* just to be sure */
       trap_command =  savestring (old_trap);
 
       running_trap = sig + 1;
+      trap_variable_context = variable_context;
 
       old_int = interrupt_state;       /* temporarily suppress pending interrupts */
       CLRINTERRUPT;
@@ -1141,6 +1152,7 @@ _run_trap_internal (sig, tag)
 
       running_trap = old_running;
       interrupt_state = old_int;
+      trap_variable_context = old_context;
 
       if (sigmodes[sig] & SIG_CHANGED)
        {
diff --git a/trap.h b/trap.h
index 89402a1bcbd4b60c97b659c64dd11375744e913a..518113c990bbfa941519aae8a2bfda609710c31e 100644 (file)
--- a/trap.h
+++ b/trap.h
@@ -63,6 +63,7 @@ extern char *trap_list[];
 extern int trapped_signal_received;
 extern int wait_signal_received;
 extern int running_trap;
+extern int trap_variable_context;
 extern int trap_saved_exit_value;
 extern int suppress_debug_trap_verbose;