Discussion:
error message for missing fi is not helpful
Manuel Reiter
2018-09-12 09:17:39 UTC
Permalink
++ Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64'
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-pc-linux-gnu'
-DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash'
-DSHELL -DHAVE_CONFIG_H -I. -I../. -I.././include -I.././lib
-Wdate-time -D_FORTIFY_SOURCE=2 -g -O2
-fdebug-prefix-map=/build/bash-7fckc0/bash-4.4=.
-fstack-protector-strong -Wformat -Werror=format-security -Wall -no-pie
-Wno-parentheses -Wno-format-security
uname output: Linux eeyore 4.9.0-4-amd64 #1 SMP Debian 4.9.65-3
(2017-12-03) x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu

Bash Version: 4.4
Patch Level: 12
Release Status: release

++ Description:

When an if statement is not terminated by a fi, bash's error message is
not helpful in locating the problem.

This was mentioned in
http://lists.gnu.org/archive/html/bug-bash/2008-06/msg00105.html but
never replied to.

I don't know whether bash allows an if statement to be terminated by EOF
(as it does for a here document which was the original subject of the
cited post) but even if it does, a warning message might be helpful.

This applies to case not being terminated by esac (and possibly other
commands) as well.

++ Repeat-By:

+ run the following script in bash:
--snip
#!/bin/bash
if true
then
exit 0
# fi missing

exit 1
-- snip

+ expected output:

./test.bash: line 2: syntax error: if without corresponding fi

or at least

./test.bash: line 2: warning: if without corresponding fi

+ actual output:

./test.bash: line 8: syntax error: unexpected end of file
Chet Ramey
2018-09-12 13:35:41 UTC
Permalink
Post by Manuel Reiter
Bash Version: 4.4
Patch Level: 12
Release Status: release
When an if statement is not terminated by a fi, bash's error message is
not helpful in locating the problem.
This is tough to do in a bison-generated parser. If someone would like to
build the structures required to keep track of which conditional command
the shell is currently parsing, and incorporate that into an error
message, I'd be happy to look at it.

Chet
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU ***@case.edu http://tiswww.cwru.edu/~chet/
L A Walsh
2018-09-13 02:29:01 UTC
Permalink
Post by Chet Ramey
Post by Manuel Reiter
Bash Version: 4.4
Patch Level: 12
Release Status: release
When an if statement is not terminated by a fi, bash's error message is
not helpful in locating the problem.
This is tough to do in a bison-generated parser. If someone would like to
build the structures required to keep track of which conditional command
the shell is currently parsing, and incorporate that into an error
message, I'd be happy to look at it.
Chet
This isn't *exactly* what you wanted, but this gives the line number
of the last unmatched statement (but doesn't tell you what the statement
was). The diff was against bash-4.4.23 (4.4 base w/23 patches)

I can't speak for formatting or base-specific function usage, but I don't
think there was any of those.

Anyway, if you store the word in a separate array where the line #
is stored, you _could_ list the matching word, but I suspect just the
line it started on would be enough for most users.

--- (eoftest.sh)
#!/bin/bash

if ((1)); then
for i in 1 2 3; do



echo wow

---
Post by Chet Ramey
./bash eoftest.sh
eoftest.sh: line 10: syntax error: unexpected end of file from line 4.

The wording was just what I threw in. I don't _need_ attribution for
this if that makes it easier.
Chet Ramey
2018-09-13 20:21:21 UTC
Permalink
Post by L A Walsh
I can't speak for formatting or base-specific function usage, but I don't
think there was any of those.
Anyway, if you store the word in a separate array where the line #
is stored, you _could_ list the matching word, but I suspect just the
line it started on would be enough for most users.
--- (eoftest.sh)
#!/bin/bash
if ((1)); then
   for i in 1 2 3; do
       echo wow
---
 ./bash eoftest.sh                         
eoftest.sh: line 10: syntax error: unexpected end of file from line 4.
The wording was just what I threw in.  I don't _need_ attribution for
this if that makes it easier.
I'm sure you noticed that word_lineno isn't set for every compound command
and that it's limited.
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU ***@case.edu http://tiswww.cwru.edu/~chet/
L A Walsh
2018-09-14 20:30:18 UTC
Permalink
Post by Chet Ramey
I'm sure you noticed that word_lineno isn't set for every compound command
and that it's limited.
----
Actually I didn't notice. Under what circumstances is it not set?
What is it's purpose if it's not to keep track of a stack of nested
conditionals?

Could it store the line number of each or would that cause other
problems?

Manuel Reiter
2018-09-14 14:26:14 UTC
Permalink
Post by L A Walsh
This isn't *exactly* what you wanted, but this gives the line number
of the last unmatched statement (but doesn't tell you what the statement
was).  The diff was against bash-4.4.23 (4.4 base w/23 patches)
Thank you for taking the time to look into this! There seems to be a
problem with your code though: if word_top is zero and EOF_Reached is
true, you set msg to msg0 without initializing msg0 first.

Reviving the code you commented out (your first attempt?) I came to the
attached result. I also added if/fi to the compound commands tracked by
word_top. There are probably others that I have missed missed.
Post by L A Walsh
Anyway, if you store the word in a separate array where the line #
is stored, you _could_ list the matching word, but I suspect just the
line it started on would be enough for most users.
I totally agree with that.

Thanks and best regards,

Manuel
Loading...