Implement the @R parameter transformation to reverse the order of
list-valued parameter expansions.

This applies to array and positional parameter expansions such as
${param[@]@R}, ${param[*]@R}, ${@@R}, and ${*@R}.

The transformation preserves existing quoting, joining, and word-splitting
semantics for each expansion form. Scalar parameter expansions are
unchanged.
---
 subst.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/subst.c b/subst.c
index dd5d57b..2532713 100644
--- a/subst.c
+++ b/subst.c
@@ -8771,6 +8771,9 @@ string_transform (int xc, SHELL_VAR *v, char *s)
       case 'Q':
        ret = sh_quote_reusable (s, 0);
        break;
+      case 'R':
+       ret = savestring (s);
+       break;
       case 'U':
        ret = sh_modcase (s, 0, CASE_UPPER);
        break;
@@ -8802,7 +8805,11 @@ list_transform (int xc, SHELL_VAR *v, WORD_LIST *list, 
int itype, int quoted)
       w->word = tword ? tword : savestring ("");       /* XXX */
       new = make_word_list (w, new);
     }
-  l = REVERSE_LIST (new, WORD_LIST *);
+
+  /* ${name[@]@R} and ${name[*]@R}: keep the list in the reverse
+     order produced by prepending above. Other transformations preserve
+     the original order by reversing NEW back. */
+  l = (xc == 'R') ? new : REVERSE_LIST (new, WORD_LIST *);
 
   qflags = quoted;
   /* If we are expanding in a context where word splitting will not be
@@ -8910,6 +8917,7 @@ valid_parameter_transform (const char *xform)
     case 'E':          /* expand like $'...' */
     case 'P':          /* expand like prompt string */
     case 'Q':          /* quote reusably */
+    case 'R':          /* reverse array or positional parameter order */
     case 'U':          /* transform to uppercase */
     case 'u':          /* transform by capitalizing */
     case 'L':          /* transform to lowercase */
-- 
2.53.0


Reply via email to