Re: param expansion with single-character special vars in the environment

2016-05-02 Thread Dan Douglas
On Mon, May 2, 2016 at 1:59 PM, Grisha Levit  wrote:
>
> On Mon, May 2, 2016 at 2:48 PM, Chet Ramey  wrote:
>>
>> and this one throws away the nameref attribute:
>>
>> typeset -n foo ; typeset -i foo ; foo=7*6 ; typeset -p foo
>
>
> I think it's important to note that the nameref attribute is thrown away at
> the `typeset -i foo' step, which makes some sense since `typeset -n -i' does
> not seem to be valid in ksh.

ksh93 stores integer variables as actual integers internally so
there's no opportunity for storing the expression, and the nameref
attribute just wouldn't make sense.

Bash stores a string that gets coerced as necessary when performing
arithmetic. That's why ksh is so much faster than bash when you
declare integers, and an integer will wrap around while a string will
get converted back and fourth via pretty much the same rules bash
uses.

 ~ $ ksh -c 'integer n=$(getconf LONG_MAX); typeset m=$n; ((m++,n++));
typeset -p n m'
typeset -l -i n=-9223372036854775808
m=9.22337203685477581e+18

The only effect of -i in bash is to modify the way += assignments work.



Re: param expansion with single-character special vars in the environment

2016-05-02 Thread Chet Ramey
On 5/2/16 2:59 PM, Grisha Levit wrote:
> 
> On Mon, May 2, 2016 at 2:48 PM, Chet Ramey  > wrote:
> 
> and this one throws away the nameref attribute:
> 
> typeset -n foo ; typeset -i foo ; foo=7*6 ; typeset -p foo
> 
> 
> I think it's important to note that the nameref attribute is thrown away at
> the `typeset -i foo' step, which makes some sense since `typeset -n -i'
> does not seem to be valid in ksh.

Yes.  It's just that it's undocumented and done without a warning.


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



IFS as the control variable in a for loop

2016-05-02 Thread Grisha Levit
When in a non-interactive shell, IFS, when modified as the control variable
in a for loop does not change splitting behavior.
$ bash -c 'for IFS in .; do printf "%s\n" "$IFS" "$*"; done' bash x x
.
x x

$ bash -ic 'for IFS in .; do printf "%s\n" "$IFS" "$*"; done' bash x x
.
x.x


Re: param expansion with single-character special vars in the environment

2016-05-02 Thread Grisha Levit
On Mon, May 2, 2016 at 2:48 PM, Chet Ramey  wrote:

> and this one throws away the nameref attribute:
>
> typeset -n foo ; typeset -i foo ; foo=7*6 ; typeset -p foo
>

I think it's important to note that the nameref attribute is thrown away at
the `typeset -i foo' step, which makes some sense since `typeset -n -i'
does not seem to be valid in ksh.


Re: param expansion with single-character special vars in the environment

2016-05-02 Thread Chet Ramey
On 4/27/16 8:36 PM, Grisha Levit wrote:
> 
> On Wed, Apr 27, 2016 at 6:47 PM, Piotr Grzybowski  > wrote:
> 
> + if (v == 0 && onref || ( onref && !legal_identifier(value)))
> 
> 
> Shouldn't this (and the other patch) check valid_array_reference as well to
> support declare -n ref=a[x] ?

I ended up writing a new function: valid_nameref_value(name, flags) which
I can customize to serve this purpose.

-- 
``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: param expansion with single-character special vars in the environment

2016-05-02 Thread Chet Ramey
On 4/27/16 7:37 PM, Piotr Grzybowski wrote:
> 
>  sorry for the spam concerning the patch: it needs merging with what Eduardo 
> posted (excluding the `declare -n r; declare -n r;' regression bug), and what 
> is in #ifdef 0 in declare.def; I just found out that it is exactly what it 
> intends to do.
>  I am sure we need to forbid the illegal identifiers during declare -n and in 
> later assignments to the nameref variable.

Yes, among other things.


-- 
``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 [-+]n behavior on existing (chained) namerefs

2016-05-02 Thread Piotr Grzybowski
Hi,

 I hope the attached patch does not break to much; it addresses the masking:

> declare -nt r=a; f() { declare a; declare -n r=a; declare -p a r; }; f

as per Grisha's report; it tries to enlighten make_local_variable to the 
existence of nameref by returning existing local nameref in scope (declare -n 
r=PATH; declare -n r; returns r with value of PATH) and by (hopefully) 
correctly making existing nameref take precedence over the dereferenced value.

 Would you please consider it?

cheers,
pg





masking_nameref_with_local_vars.patch
Description: Binary data


On 29 Apr 2016, at 03:49, Grisha Levit wrote:

> There is also an issue when doing something like `declare -n r=a' in a 
> function if the same has been done in a higher scope.  Instead of creating a 
> new variable r in the function's scope, it modifies the local `a' to be a 
> self-referencing nameref..
> 
> $ declare -nt r=a; f() { declare a; declare -n r=a; declare -p a r; }; f
> declare -n a="a"# ??
> declare -nt r="a"   # note the -t.  this is the outer $r, a new one was not 
> created
> 
> In a slightly different version, with `declare -n r; r=a', the function exits 
> with code 1 after the `r=a' statement:
> 
> $ declare -nt r=a; f() { declare a; declare -n r; r=a; declare -p a r; }; f; 
> echo $?
> 1



Re: param expansion with single-character special vars in the environment

2016-05-02 Thread Chet Ramey
On 4/27/16 4:07 PM, Eduardo A. Bustamante López wrote:

> The 'mapfile' one is interesting, because it drops the nameref attribute from
> the 'r' variable.

Array variables can't have the nameref attribute.  The process of creating
and clearing the array with the name supplied as an argument clears that
attribute.  Maybe it should display a warning.

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/



Array expansions in scalar assignments

2016-05-02 Thread Dan Douglas
Hi, it looks like these expansions still aren't quite being delimited
by IFS consistently. Probably strangest of these is a4 where `$*`
doesn't agree with `${a[*]}`, and a3 vs. a4 where quoting modifies the
result. I would think bash should look like the ksh output with all
@'s space-separated and all *'s comma-separated.

This was essentially the same bug, though I didn't test typeset vs
plain assignments or quoting variations back then:
https://lists.gnu.org/archive/html/bug-bash/2013-01/msg00167.html

+smorgbox bash-build # cat ~ormaaj/doc/projects/bash/testcases/peflattening2
shopt -s extglob
{ for sh in /bin/bash?(-*) ~ormaaj/doc/programs/bash-build/bash ksh
mksh; do "$sh" /dev/fd/3; done; } 3<<\EOF
function f {
   typeset -a a
   a=("$@")
   typeset IFS=,
   typeset a1="${a[@]} ${a[*]} $@ $*"
   typeset a2=${a[@]}\ ${a[*]}\ $@\ $* a3 a4
   a3="${a[@]} ${a[*]} $@ $*"
   a4=${a[@]}\ ${a[*]}\ $@\ $*
   unset -v IFS
   printf '%s\n' "${BASH_VERSION:-${KSH_VERSION}}:" "a1=$a1" "a2=$a2"
"a3=$a3" "a4=$a4"
}

echo
f a b c
# vim: ft=sh et
EOF

+smorgbox bash-build # bash ~ormaaj/doc/projects/bash/testcases/peflattening2

4.3.42(1)-release:
a1=a,b,c a,b,c a,b,c a,b,c
a2=a,b,c a,b,c a,b,c a,b,c
a3=a b c a,b,c a b c a,b,c
a4=a b c a,b,c a b c a b c

4.4.0(1)-rc2:
a1=a,b,c a,b,c a,b,c a,b,c
a2=a,b,c a,b,c a,b,c a,b,c
a3=a b c a,b,c a b c a,b,c
a4=a b c a,b,c a b c a b c

Version ABIJM 93v- 2014-12-24:
a1=a b c a,b,c a b c a,b,c
a2=a b c a,b,c a b c a,b,c
a3=a b c a,b,c a b c a,b,c
a4=a b c a,b,c a b c a,b,c

@(#)MIRBSD KSH R52 2016/04/09:
a1=a b c a,b,c a b c a,b,c
a2=a b c a,b,c a b c a,b,c
a3=a b c a,b,c a b c a,b,c
a4=a b c a,b,c a b c a,b,c



Re: param expansion with single-character special vars in the environment

2016-05-02 Thread Chet Ramey
On 4/27/16 8:41 AM, Grisha Levit wrote:
> On Wed, Apr 27, 2016 at 7:37 AM, Piotr Grzybowski  > wrote:
> 
>  It seems to me that creating the reference should be allowed, but the
> access to the referenced variable should honor its attributes.
> 
> Once you convert the variable to a reference, you can control its value by
> modifying the value of a different variable with the name that corresponds
> to the value of the readonly variable, so “access to the referenced
> variable should honor its attributes” probably won’t do much (If I
> understand your suggestion correctly).

I agree; `declare' should not allow attempts to add the nameref attribute
to an existing readonly variable.  I will make this change before bash-4.4
is released.

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: [patch] /* XXX - possibly run Coproc->name through word expansion? */

2016-05-02 Thread Piotr Grzybowski
Hi,

On 2 May 2016, at 10:26, Dan Douglas wrote:

> FWIW, something like this works currently. This pattern is useful in a
> bunch of situations where the shell wants to assign to a fixed
> variable name. (getopts being another). [..]

 thanks for the hint, of course I like it with the patch better:

for i in {a..f}; do coproc $i { body; }; done;
 
 Chet promised to consider it for submission, so I stand by his statement ;-)

 in current devel something must have got fixed, with your example I am getting:

bash: wait: `': not a pid or valid job spec

in every iteration after the first, so it would seem that storing another 
element in the coproc fd table is problematic, I guess that the length of this 
table is 2 in last for loop in mkProcs, after every other iteration (i have not 
checked it). That could be easily added, so that the last element of the table 
gets the pid automatically in coproc allocation routine.
 In order to promote the patch I should propose another, to forbid adding 
nameref to identifiers that are well-defined, not only readonly ;-)

cheers,
pg


> 
> ~ $ bash /dev/fd/9 9<<\EOF
> function mkProcs {
>   typeset -n COPROC ref=$1
>   set -- "${ref[@]}"
>   for COPROC; do
>   coproc {
>   typeset status=$((RANDOM%255))
>   echo "${!COPROC} status: $status"
>   return "$status"
>   }
>   COPROC[2]=$COPROC_PID
>   done
>   for COPROC; do
>   echo "${!COPROC}: $(cat <&"${COPROC[0]}"; wait "${COPROC[2]}") $?"
>   done
> 
> }
> 
> typeset -a coprocs=({a..f}) "${coprocs[@]}"
> mkProcs coprocs
> EOF
> 
> /dev/fd/9: line 4: warning: execute_coproc: coproc [7768:COPROC] still exists
> /dev/fd/9: line 4: warning: execute_coproc: coproc [7769:COPROC] still exists
> /dev/fd/9: line 4: warning: execute_coproc: coproc [7770:COPROC] still exists
> /dev/fd/9: line 4: warning: execute_coproc: coproc [7771:COPROC] still exists
> /dev/fd/9: line 4: warning: execute_coproc: coproc [7772:COPROC] still exists
> a: a status: 216 216
> b: b status: 90 90
> c: c status: 196 196
> d: d status: 87 87
> e: e status: 191 191
> /dev/fd/9: line 13: "${COPROC[0]}": Bad file descriptor
> f:  154
> 
> ... Not sure why that last iteration always fails. I might want to
> experiment with reducing the limitation that makes this only work
> within a function on for loops over positional parameters. I know
> that's how it is in ksh but I've never found that it's necessary.




Re: [patch] /* XXX - possibly run Coproc->name through word expansion? */

2016-05-02 Thread Dan Douglas
FWIW, something like this works currently. This pattern is useful in a
bunch of situations where the shell wants to assign to a fixed
variable name. (getopts being another).

 ~ $ bash /dev/fd/9 9<<\EOF
function mkProcs {
   typeset -n COPROC ref=$1
   set -- "${ref[@]}"
   for COPROC; do
   coproc {
   typeset status=$((RANDOM%255))
   echo "${!COPROC} status: $status"
   return "$status"
   }
   COPROC[2]=$COPROC_PID
   done
   for COPROC; do
   echo "${!COPROC}: $(cat <&"${COPROC[0]}"; wait "${COPROC[2]}") $?"
   done

}

typeset -a coprocs=({a..f}) "${coprocs[@]}"
mkProcs coprocs
EOF

/dev/fd/9: line 4: warning: execute_coproc: coproc [7768:COPROC] still exists
/dev/fd/9: line 4: warning: execute_coproc: coproc [7769:COPROC] still exists
/dev/fd/9: line 4: warning: execute_coproc: coproc [7770:COPROC] still exists
/dev/fd/9: line 4: warning: execute_coproc: coproc [7771:COPROC] still exists
/dev/fd/9: line 4: warning: execute_coproc: coproc [7772:COPROC] still exists
a: a status: 216 216
b: b status: 90 90
c: c status: 196 196
d: d status: 87 87
e: e status: 191 191
/dev/fd/9: line 13: "${COPROC[0]}": Bad file descriptor
f:  154

... Not sure why that last iteration always fails. I might want to
experiment with reducing the limitation that makes this only work
within a function on for loops over positional parameters. I know
that's how it is in ksh but I've never found that it's necessary.