[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?
- Clearer: monatonicly increasing whitespace in fn,
linguist <=