bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Clearer: monatonicly increasing whitespace in fn


From: linguist
Subject: Clearer: monatonicly increasing whitespace in fn
Date: 1 Jul 2002 04:43:58 -0000

Configuration Information [Automatically generated, do not change]:
Machine: i686
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='i686' 
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i686-pc-linux-gnu' 
-DCONF_VENDOR='pc' -DSHELL -DHAVE_CONFIG_H   -I.  -I../src -I../src/include 
-I../src/lib -g -O2
uname output: Linux monster 2.4.17-SMPs #10 SMP Sun May 12 08:47:19 EDT 2002 
i686 unknown
Machine Type: i686-pc-linux-gnu

Bash Version: 2.05a
Patch Level: 0
Release Status: release

Description:
        This is an improved report on the increasing whitespace problem.  I have
        changed it by exporting the function, and instead of using eval 
"$(declare
        -f foo)", I just recursively run the script.  For clarity, I pipe each 
run
        through another instance of sed 's/^/|/', so there will be a bar 
preceding
        each line of output for each level of recursion.

        You will see that with no help from me ( and no possibility of 
misquoting,
        since I'm using the native export ) the function still gains a '" ' 
before
        and a ' "' after the $#<0.

        This is not only an annoyance for the application that I am using (the
        ability to interactively edit functions using something akin to
                declare -f funky > /tmp/funky.$$ && 
                        vi /tmp/funky.$$ && 
                        eval "$(cat /tmp/funky.$$)"
        ), but will also be a problem on machines with limited environment
        space.

Repeat-By:

-- cut here --
#!/bin/bash

if [ -z "$DONE_SHLVL" ]; then
        foo () 
        { 
        if (($#)); then
                echo true;
            fi
        }
        export -f foo;
        let DONE_SHLVL=$SHLVL+4
        export DONE_SHLVL
fi
echo "shell level: $SHLVL"
echo "recursion limit: $DONE_SHLVL"
echo "function foo defined as:"
declare -f foo
echo
echo
if (($SHLVL < $DONE_SHLVL)) ; then
        echo "running subshell"
        "$0" 2>&1 | sed 's/^/|/'
        echo "back to shell level: $SHLVL"
        echo "foo has returned to: "
        declare -f foo
        echo "exiting"
fi
-- cut here --

results:
-- cut here --
shell level: 4
recursion limit: 8
function foo defined as:
foo () 
{ 
    if (( "$#" )); then
        echo true;
    fi
}


running subshell
|shell level: 5
|recursion limit: 8
|function foo defined as:
|foo () 
|{ 
|    if (( " "$#" " )); then
|        echo true;
|    fi
|}
|
|
|running subshell
||shell level: 6
||recursion limit: 8
||function foo defined as:
||foo () 
||{ 
||    if (( " " "$#" " " )); then
||        echo true;
||    fi
||}
||
||
||running subshell
|||shell level: 7
|||recursion limit: 8
|||function foo defined as:
|||foo () 
|||{ 
|||    if (( " " " "$#" " " " )); then
|||        echo true;
|||    fi
|||}
|||
|||
|||running subshell
||||shell level: 8
||||recursion limit: 8
||||function foo defined as:
||||foo () 
||||{ 
||||    if (( " " " " "$#" " " " " )); then
||||        echo true;
||||    fi
||||}
||||
||||
|||back to shell level: 7
|||foo has returned to: 
|||foo () 
|||{ 
|||    if (( " " " "$#" " " " )); then
|||        echo true;
|||    fi
|||}
|||exiting
||back to shell level: 6
||foo has returned to: 
||foo () 
||{ 
||    if (( " " "$#" " " )); then
||        echo true;
||    fi
||}
||exiting
|back to shell level: 5
|foo has returned to: 
|foo () 
|{ 
|    if (( " "$#" " )); then
|        echo true;
|    fi
|}
|exiting
back to shell level: 4
foo has returned to: 
foo () 
{ 
    if (( "$#" )); then
        echo true;
    fi
}
exiting
-- cut here --


Fix:
        I would say that there are several possible fixes for the problem.

        One would be to apply the logic from arith_for_loops, as described
        in this comment from parse.y, to (( )) statements in general

    /* parse_arith_cmd adds quotes at the beginning and end
       of the string it returns; we need to take those out. */

        Note that this is insufficient for arith_for_loops, which is the 
section of
        code that it comments, since although it removes the quotes, arithmetic 
for
        loops still gain a space on either side for each export/import cycle,
        looking rather absurd in deeply nested shells.

        Another would be to change the logic in parse_arith_cmd, so that rather 
than
        adding the quotes and spaces at that level, the quotes and spaces are 
added
        at a higher level in those cases that require them.  It would seem that 
the
        cases that benefit from them are fewer from those that are harmed.

        Yet another would be to change the stringifying logic so that what the 
parser
        giveth, the stringifier taketh away.

        Since I know little about the internals of bash, it is hard for me to 
comment
        as to the best solution.  If someone could describe for me what cases 
require
        the extra quotes and spaces, and provide a couple of examples, I'd be 
happy to
        try my hand at finding a fix for this.  But I'm loath to attempt this 
without
        knowing why that code is there in the first place.  I do know that the 
patch
        I have tried I have had to remove because it broke other constructs.

        Is there a definitive reference to parsing the bashese language, from 
which a
        poor c++ guy out of his element might benifit?




reply via email to

[Prev in Thread] Current Thread [Next in Thread]