Re: declare in a function makes a variable unable to be found with declare -p in some cases

2015-02-19 Thread Chet Ramey
On 2/16/15 3:38 PM, SN wrote:
 Hello all,
 
 I have found a problem with the declare builtin.
 
 Patch Level: 33
 Release Status: release
 
 Description:
 Apparently, there is a problem with how bash interprets some
 variable assignments.
 It only happens in a function (probably related to `declare'
 making variables local).

Yes, that's part of it.

 Repeat-By:
 # OK
 $ x() { declare -a var=(); declare -p var; }; x
 declare -a var='()'
 # not OK
 $ y() { declare -a var='()'; declare -p var; }; y
 bash: declare: var: not found
 
 Note that the format used in y is what `declare -p' displays.

Yes. The issue is that the assignment doesn't make the variable visible,
when it clearly should.  I've attached a patch that will fix that.

The next version of bash will do things differently, as noted in a couple
of followups to this message.  The proposal that prompted the changes is
part of a long thread from December:

http://lists.gnu.org/archive/html/bug-bash/2014-12/msg00115.html

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/
*** /usr/src/local/bash/bash-4.3-patched/arrayfunc.c	2014-10-01 13:08:48.0 -0400
--- arrayfunc.c	2015-02-19 14:33:05.0 -0500
***
*** 405,408 
--- 405,411 
  else
array_insert (a, i, l-word-word);
+ 
+   VUNSETATTR (var, att_invisible);	/* no longer invisible */
+ 
return var;
  }
***
*** 635,638 
--- 638,645 
if (nlist)
  dispose_words (nlist);
+ 
+   if (var)
+ VUNSETATTR (var, att_invisible);	/* no longer invisible */
+ 
return (var);
  }


Re: declare in a function makes a variable unable to be found with declare -p in some cases

2015-02-19 Thread Chet Ramey
On 2/16/15 3:38 PM, SN wrote:

 By the way, empty arrays seem to be reported as not set.
 a=(); test -v a || echo not set
 This might be related (or not), but consider that the return
 status of `test -v'
 is different on a bash version unaffected by the bug that I have
 tried (4.2.37).

References to an array without a subscript always reference element 0.
There's not really a clean way to check whether an array has been
declared but explicitly assigned an empty list, and it's not clear whether
or not an array without at least one assigned subscript should count as
`set' at all.

If you want to see whether or not an array has been assigned at least one
element, you can check whether ${#a[@]}  0.

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/



Re: declare in a function makes a variable unable to be found with declare -p in some cases

2015-02-19 Thread Chet Ramey
On 2/18/15 2:30 PM, SN wrote:

 Thanks for checking it on various versions! In 4.4.0(1)-devel this test
 passes for a few variations I tried. For example:
 
 $ f() { declare -a a=(); eval declare -p a; printf [%s]\n
 ${a[@]}; }; f
 declare -a a=([0]=())
 [()]
 
 and
 
 $ f() { declare -a a=(); eval declare -p a; printf [%s]\n ${a[@]};
 }; f
 declare -a a=()
 []
 
 so it's good.

That's one of the changes to bash-4.4 that isn't backwards compatible.
Right now, you have to set the shell compatibility level to get bash-4.3
behavior; I'm considering changing bash-4.4 to have compatible behavior
when using quoted compound array assignment, but with a warning about
the syntax being deprecated.  What do folks on the list think?

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/



Re: declare in a function makes a variable unable to be found with declare -p in some cases

2015-02-19 Thread Chet Ramey
On 2/18/15 2:44 PM, Eduardo A. Bustamante López wrote:

 Let's wait to see what Chet has to say on that matter. Changes on the devel
 branch are not documented, so he's the only one that knows what's going on.

All changes are in the changelog (CWRU/CWRU.chlog or CWRU/changelog).  A
typical change entry includes the date, source file, affected function(s),
a description of the change, and a reference to the bug report that
prompted the fix, if appropriate.

-- 
``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/



Bugs in ERR and RETURN traps

2015-02-19 Thread Paul Donohue
I posted bug reports at https://savannah.gnu.org/support/index.php?108738 and 
https://savannah.gnu.org/support/index.php?108749 but there seems to be very 
little activity (or none at all?) on the issue tracker, so I figured it might 
be a good idea to post to the mailing list too.

I'm using bash 4.3.30(1) in Ubuntu, and have run across two odd behaviors in 
ERR and RETURN traps that I think are bugs.



First:

When an ERR trap is called, ${BASH_SOURCE[0]}, ${FUNCNAME[0]}, and $LINENO 
normally indicate the file/function/line which called the command that returned 
a non-zero status. This is good.

However, if an ERR trap is called because a function returned a non-zero 
status, then ${BASH_SOURCE[0]} and ${FUNCNAME[0]} still indicate the 
file/function which called the function that returned a non-zero status, but 
$LINENO indicates the line number of the last command in the function that was 
called, and the line number of the call to the function is not available.  This 
doesn't really make sense.

Example:
$ cat 'END' script1
test_fun() {
return 1
}
END
$ cat 'END' script2
#!/bin/bash
# Some blank lines to adjust the line numbers relative to script1

source script1
trap 'echo error at: ${BASH_SOURCE[0]} ${FUNCNAME[0]} $LINENO 
${BASH_LINENO[@]}' ERR
false # Trigger the ERR trap with a command on line 6
test_fun # Trigger the ERR trap with a function on line 7
END
$ chmod 755 script2
$ ./script2
error at: ./script2 main 6 0
error at: ./script2 main 2 0
$

This seems like a bug. I would expect one of two behaviors here:
1) In the ERR trap on function return, $LINENO should point to the line which 
called the function (just as ${BASH_SOURCE[0]} and ${FUNCNAME[0]} point to the 
file/function which called the function that returned a non-zero status).
2) In the ERR trap on function return, ${BASH_SOURCE[0]}, ${FUNCNAME[0]}, and 
$LINENO should point to the last command executed within the function, and 
${BASH_SOURCE[1]} ${FUNCNAME[1]} ${BASH_LINENO[0]} should point to the caller 
of the function.



Second:

The RETURN trap does not see the exit status of 'return', but rather the exit 
status of the last command before 'return' was called.

Example:
$ test_fun()
{
trap 'echo returned $?' RETURN
false # exit status is 1
return 2
}
$ test_fun
returned 1
$

I intuitively expected the above to print 2 instead of 1.

The bash man page states Any command associated with the RETURN trap is 
executed before execution resumes after the function or script. This is a bit 
vague, but it seems to imply that the RETURN trap should run after the `return` 
command is complete (since the `return` command is part of the function and the 
RETURN trap runs after the function), which would imply that $? should be set 
to the exit status of the return command in the RETURN trap. So, the 
documentation seems to back up my intuition here...

The problem I was actually trying to solve was to write a trap that ran only if 
the function returned an error. An ERR trap would have been run if any command 
within the function returned an error, which was not what I wanted. So, I 
simply wrote a RETURN trap which checked $?, but $? did not give me the return 
status of the function, so this didn't work.



Thoughts on these?  Is there a reason for the current behavior?

Thanks!



Re: array subscripts act differently for integers(ie. let)

2015-02-19 Thread Chet Ramey
On 2/18/15 7:57 PM, Eduardo A. Bustamante López wrote:
 On Wed, Feb 18, 2015 at 10:14:10PM +0100, emanuelczi...@cryptolab.net wrote:
 That segfault though:
 
 I confirm that the segmentation fault is in the latest devel version.

Here's the patch I applied, very similar to yours.

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-20150206/variables.c	2015-01-23 20:39:27.0 -0500
--- variables.c	2015-02-19 13:56:12.0 -0500
***
*** 2873,2880 
  v = bind_variable (lhs, rhs, 0);
  
!   if (v  isint)
! VSETATTR (v, att_integer);
! 
!   VUNSETATTR (v, att_invisible);
  
return (v);
--- 2873,2882 
  v = bind_variable (lhs, rhs, 0);
  
!   if (v)
! {
!   if (isint)
! 	VSETATTR (v, att_integer);
!   VUNSETATTR (v, att_invisible);
! }
  
return (v);


Re: array subscripts act differently for integers(ie. let)

2015-02-19 Thread Chet Ramey
On 2/18/15 4:14 PM, emanuelczi...@cryptolab.net wrote:
 tl;dr: thanks! no reply needed;
 
 Thanks guys. I had a hard time accepting that this is how it's supposed to
 work.
 I accepted it now. :)

Yeah.  The expression between (( and )) is word expanded, since (( ... ))
is supposed to be exactly equivalent to let 

The real issue is that assignment statements in arithmetic expressions
that contain array references are also word expanded, almost as if they
were executed in an assignment statement context.  This is how bash has
always behaved, though; backwards compatibility is a concern.

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/