Re: Difference between assignment via nameref vs `printf -v`?

2014-09-01 Thread Chet Ramey
On 8/31/14, 12:20 AM, lolilolicon wrote:
> Assignment to a subscripted array variable behaves differently for
> nameref vs `printf -v`, as shown below.
[...]
> Is subscripted array variable allowed as argument to `declare -p` in bash?
> A quick test seems to suggest it's not -- consistent with the `printf
> -v` behavior.
> 
> Is there a legitimate explanation for this?

It's a bug that results in `arr[0]' being created as a shell variable.
I've attached a patch for people who want to experiment with it.

Chet
-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
*** ../bash-4.3-patched/subst.h	2014-01-11 21:02:27.0 -0500
--- subst.h	2014-09-01 12:16:56.0 -0400
***
*** 48,51 
--- 48,52 
  #define ASS_MKGLOBAL	0x0008	/* force global assignment */
  #define ASS_NAMEREF	0x0010	/* assigning to nameref variable */
+ #define ASS_FROMREF	0x0020	/* assigning from value of nameref variable */
  
  /* Flags for the string extraction functions. */
*** ../bash-4.3-patched/variables.c	2014-05-15 08:26:50.0 -0400
--- variables.c	2014-09-01 14:37:44.0 -0400
***
*** 2504,2511 
   int hflags, aflags;
  {
!   char *newval;
SHELL_VAR *entry;
  
entry = (hflags & HASH_NOSRCH) ? (SHELL_VAR *)NULL : hash_lookup (name, table);
/* Follow the nameref chain here if this is the global variables table */
if (entry && nameref_p (entry) && (invisible_p (entry) == 0) && table == global_variables->table)
--- 2566,2590 
   int hflags, aflags;
  {
!   char *newname, *newval;
SHELL_VAR *entry;
+ #if defined (ARRAY_VARS)
+   arrayind_t ind;
+   char *subp;
+   int sublen;
+ #endif
  
+   newname = 0;
+ #if defined (ARRAY_VARS)
+   if ((aflags & ASS_FROMREF) && (hflags & HASH_NOSRCH) == 0 && valid_array_reference (name))
+ {
+   newname = array_variable_name (name, &subp, &sublen);
+   if (newname == 0)
+ 	return (SHELL_VAR *)NULL;	/* XXX */
+   entry = hash_lookup (newname, table);
+ }
+   else
+ #endif
entry = (hflags & HASH_NOSRCH) ? (SHELL_VAR *)NULL : hash_lookup (name, table);
+ 
/* Follow the nameref chain here if this is the global variables table */
if (entry && nameref_p (entry) && (invisible_p (entry) == 0) && table == global_variables->table)
***
*** 2538,2541 
--- 2617,2630 
}
  }
+ #if defined (ARRAY_VARS)
+   else if (entry == 0 && newname)
+ {
+   entry = make_new_array_variable (newname, table);	/* indexed array by default */
+   if (entry == 0)
+ 	return entry;
+   ind = array_expand_index (name, subp, sublen);
+   bind_array_element (entry, ind, value, aflags);
+ }
+ #endif
else if (entry == 0)
  {
***
*** 2658,2662 
  		  if (nameref_cell (nv) == 0)
  			return (bind_variable_internal (nv->name, value, nvc->table, 0, flags));
! 		  return (bind_variable_internal (nameref_cell (nv), value, nvc->table, 0, flags));
  		}
  		  else
--- 2747,2752 
  		  if (nameref_cell (nv) == 0)
  			return (bind_variable_internal (nv->name, value, nvc->table, 0, flags));
! 		  /* XXX - bug here with ref=array[index] */
! 		  return (bind_variable_internal (nameref_cell (nv), value, nvc->table, 0, flags|ASS_FROMREF));
  		}
  		  else


Re: Difference between assignment via nameref vs `printf -v`?

2014-09-01 Thread lolilolicon
On Tue, Sep 2, 2014 at 9:02 AM, Chet Ramey  wrote:
> It's a bug that results in `arr[0]' being created as a shell variable.
> I've attached a patch for people who want to experiment with it.

I applied it against 4.3.24 but it failed to build... Am I missing some
patch in between?

variables.c:2560:15: error: too many arguments to function
‘make_new_array_variable’
   entry = make_new_array_variable (newname, table); /* indexed
   array by default */