From 90af86f6ec04050b2adbe9bb7d81c31359d49c50 Mon Sep 17 00:00:00 2001
From: Piotr Grzybowski <merlin@narsil.org.pl>
Date: Wed, 4 May 2016 18:00:53 +0200
Subject: [PATCH] export -r reference

---
 builtins/common.h    |  2 +-
 builtins/setattr.def | 33 +++++++++++++++++++++++----------
 variables.c          |  7 ++++++-
 3 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/builtins/common.h b/builtins/common.h
index ed85230..5a5b566 100644
--- a/builtins/common.h
+++ b/builtins/common.h
@@ -188,7 +188,7 @@ extern int show_all_var_attributes __P((int, int));
 extern int show_var_attributes __P((SHELL_VAR *, int, int));
 extern int show_name_attributes __P((char *, int));
 extern int show_func_attributes __P((char *, int));
-extern void set_var_attribute __P((char *, int, int));
+extern void set_var_attribute __P((char *, int, int, int));
 extern int var_attribute_string __P((SHELL_VAR *, int, char *));
 
 /* Functions from pushd.def */
diff --git a/builtins/setattr.def b/builtins/setattr.def
index 9e9309f..65321ac 100644
--- a/builtins/setattr.def
+++ b/builtins/setattr.def
@@ -52,13 +52,14 @@ extern int declare_builtin __P((WORD_LIST *));
 
 $BUILTIN export
 $FUNCTION export_builtin
-$SHORT_DOC export [-fn] [name[=value] ...] or export -p
+$SHORT_DOC export [-rfn] [name[=value] ...] or export -p
 Set export attribute for shell variables.
 
 Marks each NAME for automatic export to the environment of subsequently
 executed commands.  If VALUE is supplied, assign VALUE before exporting.
 
 Options:
+  -r	follow the namref and export the variable pointed to
   -f	refer to shell functions
   -n	remove the export property from each NAME
   -p	display a list of all exported variables and functions
@@ -113,9 +114,9 @@ readonly_builtin (list)
 }
 
 #if defined (ARRAY_VARS)
-#  define ATTROPTS	"aAfnp"
+#  define ATTROPTS	"aArfnp"
 #else
-#  define ATTROPTS	"fnp"
+#  define ATTROPTS	"rfnp"
 #endif
 
 /* For each variable name in LIST, make that variable have the specified
@@ -128,7 +129,7 @@ set_or_show_attributes (list, attribute, nodefs)
 {
   register SHELL_VAR *var;
   int assign, undo, any_failed, assign_error, opt;
-  int functions_only, arrays_only, assoc_only;
+  int functions_only, arrays_only, assoc_only, follow_references;
   int aflags;
   char *name;
 #if defined (ARRAY_VARS)
@@ -138,7 +139,7 @@ set_or_show_attributes (list, attribute, nodefs)
   int opti;
 #endif
 
-  functions_only = arrays_only = assoc_only = 0;
+  follow_references = functions_only = arrays_only = assoc_only = 0;
   undo = any_failed = assign_error = 0;
   /* Read arguments from the front of the list. */
   reset_internal_getopt ();
@@ -162,6 +163,9 @@ set_or_show_attributes (list, attribute, nodefs)
 #endif
 	  case 'p':
 	    break;
+	  case 'r':
+	    follow_references = 1;
+	    break;
 	  CASE_HELPOPT;
 	  default:
 	    builtin_usage ();
@@ -278,7 +282,7 @@ set_or_show_attributes (list, attribute, nodefs)
 		name[assign - 1] = '\0';
 	    }
 
-	  set_var_attribute (name, attribute, undo);
+	  set_var_attribute (name, attribute, undo, follow_references);
 	  list = list->next;
 	}
     }
@@ -534,13 +538,14 @@ show_func_attributes (name, nodefs)
 }
 
 void
-set_var_attribute (name, attribute, undo)
+set_var_attribute (name, attribute, undo, follow_references)
      char *name;
-     int attribute, undo;
+     int attribute, undo, follow_references;
 {
-  SHELL_VAR *var, *tv, *v;
+  SHELL_VAR *var, *tv, *v, *nameref;
   char *tvalue;
 
+  nameref=find_variable_noref(name);
   if (undo)
     var = find_variable (name);
   else
@@ -589,9 +594,17 @@ set_var_attribute (name, attribute, undo)
 	}
     }
 
-  if (var)
+  if (var && follow_references)
     SETVARATTR (var, attribute, undo);
 
+  if (attribute & att_exported)
+    {
+      if (nameref && nameref_p(nameref))
+        {
+          SETVARATTR (nameref, att_exported, undo);
+        }
+    }
+
   if (var && (exported_p (var) || (attribute & att_exported)))
     array_needs_making++;	/* XXX */
 }
diff --git a/variables.c b/variables.c
index 69ed170..b4926b8 100644
--- a/variables.c
+++ b/variables.c
@@ -4112,8 +4112,13 @@ make_env_array_from_var_list (vars)
 	continue;	/* XXX associative array vars cannot yet be exported */
 #  endif
 #endif
-      else
+      else {
 	value = value_cell (var);
+       if (nameref_p(var) && legal_identifier(value))
+         {
+           value=find_variable(value)->value;
+         }
+      }
 
       if (value)
 	{
-- 
2.7.0

