Article View: gnu.bash.bug
Article #148Bash functions incompatibility with sh?
From: Brian Fox
Date: Mon, 26 Jun 1989 23:56
Date: Mon, 26 Jun 1989 23:56
166 lines
5298 bytes
5298 bytes
Date: 26 Jun 89 20:10:03 GMT
From: brian@radio.astro (Brian Glendenning)
Organization: Radio Astronomy, Univeristy of Toronto
Sender: bug-bash-request@prep.ai.mit.edu
The following may not be a bug...
It was a bug. I've enclosed the fix.
Under sh if I type:
c() { for i in a b c d; do echo $i; done ; }
then "c" does what I expect (i.e. echoes a b c d each on a new line).
However under bash exactly the same line gives me:
syntax error near `do'
Two problems:
1) Because Bash does curly brace expansion, the curly brace
character cannot be a reserved word, and has to be found
specially. I fixed that.
2) After fixing that, I noticed that FOR wasn't being
recognized, since it wasn't (according to the buggy code)
in a place where reserved words can appear. So I fixed
that.
----------------------------------------
File: /usr/gnu/src/bash/parse.y-diffs
----------------------------------------
*** bash-1.01/parse.y Fri Jun 23 00:10:32 1989
--- parse.y Mon Jun 26 16:42:24 1989
***************
*** 970,977 ****
/* When non-zero, we have read the required tokens
which allow ESAC to be the next one read. */
! int allow_esac_as_next = 0;
/* If non-zero, it is the token that we want read_token to return regardless
of what text is (or isn't) present to be read. read_token resets this. */
int token_to_read = 0;
--- 970,980 ----
/* When non-zero, we have read the required tokens
which allow ESAC to be the next one read. */
! static int allow_esac_as_next = 0;
+ /* When non-zero, accept single '{' as a token itself. */
+ static int allow_open_brace = 0;
+
/* If non-zero, it is the token that we want read_token to return regardless
of what text is (or isn't) present to be read. read_token resets this. */
int token_to_read = 0;
***************
*** 1076,1081 ****
--- 1079,1092 ----
return (AND_GREATER);
}
shell_ungetc (peek_char);
+
+ /* If we look like we are reading the start of a function
+ definition, then let the reader know about it so that
+ we will do the right thing with `{'. */
+ if (character == ')' && last_read_token == '(' &&
+ token_before_that == WORD)
+ allow_open_brace = 1;
+
return (character);
}
***************
*** 1268,1274 ****
got_token:
token[token_index] = '\0';
!
if ((delimiter || dollar_paren_level) && character == EOF)
{
if (dollar_paren_level && !delimiter)
--- 1279,1285 ----
got_token:
token[token_index] = '\0';
!
if ((delimiter || dollar_paren_level) && character == EOF)
{
if (dollar_paren_level && !delimiter)
***************
*** 1293,1298 ****
--- 1304,1310 ----
return (NUMBER);
}
}
+
/* Handle special case. IN is recognized if the last token
was WORD and the token before that was FOR or CASE. */
if ((strcmp (token, "in") == 0) &&
***************
*** 1324,1335 ****
}
/* Ditto for `{' in the FUNCTION case. */
! if ((strcmp (token, "{") == 0) &&
! (last_read_token == WORD) &&
! (token_before_that == FUNCTION))
! return ('{');
! if (!dollar_present && !quoted && reserved_word_acceptable (last_read_token))
{
/* Check to see if it is a reserved word. */
int i;
--- 1336,1350 ----
}
/* Ditto for `{' in the FUNCTION case. */
! if (allow_open_brace)
! {
! allow_open_brace = 0;
! if (strcmp (token, "{") == 0)
! return ('{');
! }
! if (!dollar_present && !quoted &&
! reserved_word_acceptable (last_read_token))
{
/* Check to see if it is a reserved word. */
int i;
***************
*** 1356,1362 ****
reserved_word_acceptable (token)
int token;
{
! if (member (last_read_token, "\n;()|&") ||
last_read_token == AND_AND ||
last_read_token == OR_OR ||
last_read_token == SEMI_SEMI ||
--- 1371,1377 ----
reserved_word_acceptable (token)
int token;
{
! if (member (last_read_token, "\n;()|&{") ||
last_read_token == AND_AND ||
last_read_token == OR_OR ||
last_read_token == SEMI_SEMI ||
***************
*** 1510,1516 ****
case 'h':
{
extern char *current_host_name;
! char *t_string;
temp = savestring (current_host_name);
if (t_string = index (temp, '.'))
--- 1525,1531 ----
case 'h':
{
extern char *current_host_name;
! char *t_string, *index ();
temp = savestring (current_host_name);
if (t_string = index (temp, '.'))
----------------------------------------
Technical Details
Message-ID:
<8906262356.AA18490@aurel.caltech.edu>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!tut.cis.ohio-state.edu!AUREL.CALTECH.EDU!bfoxReferences:
<BRIAN.89Jun26160957@radio.astro.utoronto.ca>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!tut.cis.ohio-state.edu!AUREL.CALTECH.EDU!bfox From: bfox@AUREL.CALTECH.EDU (Brian Fox) Newsgroups: gnu.bash.bug Subject: Bash functions incompatibility with sh? Message-ID: <8906262356.AA18490@aurel.caltech.edu> Date: 26 Jun 89 23:56:56 GMT References: <BRIAN.89Jun26160957@radio.astro.utoronto.ca> Sender: daemon@tut.cis.ohio-state.edu Reply-To: bfox@aurel.caltech.edu Distribution: gnu Organization: GNUs Not Usenet Lines: 166