brian@radio.astro.utoronto.ca (Brian Glendenning) (06/27/89)
The following may not be a bug, it may be due to my not understanding shell functions properly. It does, however, seem to be at least an incompatibility with sh (the one on SunOS 4.0.1 anyway), and I would also appreciate knowing the correct way to do this type of thing if I'm mishandling the syntax. 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' So, I'd like to report this incompatibility, and ask for the correct syntax for getting "for" "while" "if" and friends into bash shell functions. Thanks. -- Brian Glendenning - Radio astronomy, University of Toronto brian@radio.astro.utoronto.ca uunet!utai!radio!brian glendenn@utorphys.bitnet -- Brian Glendenning - Radio astronomy, University of Toronto brian@radio.astro.utoronto.ca uunet!utai!radio!brian glendenn@utorphys.bitnet
bfox@AUREL.CALTECH.EDU (Brian Fox) (06/27/89)
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, '.')) ----------------------------------------