Line data Source code
1 : This file is break.def, from which is created break.c. 2 : It implements the builtins "break" and "continue" in Bash. 3 : 4 : Copyright (C) 1987-2009 Free Software Foundation, Inc. 5 : 6 : This file is part of GNU Bash, the Bourne Again SHell. 7 : 8 : Bash is free software: you can redistribute it and/or modify 9 : it under the terms of the GNU General Public License as published by 10 : the Free Software Foundation, either version 3 of the License, or 11 : (at your option) any later version. 12 : 13 : Bash is distributed in the hope that it will be useful, 14 : but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : GNU General Public License for more details. 17 : 18 : You should have received a copy of the GNU General Public License 19 : along with Bash. If not, see <http://www.gnu.org/licenses/>. 20 : 21 : $PRODUCES break.c 22 : 23 : $BUILTIN break 24 : $FUNCTION break_builtin 25 : $SHORT_DOC break [n] 26 : Exit for, while, or until loops. 27 : 28 : Exit a FOR, WHILE or UNTIL loop. If N is specified, break N enclosing 29 : loops. 30 : 31 : Exit Status: 32 : The exit status is 0 unless N is not greater than or equal to 1. 33 : $END 34 : #include <config.h> 35 : 36 : #if defined (HAVE_UNISTD_H) 37 : # ifdef _MINIX 38 : # include <sys/types.h> 39 : # endif 40 : # include <unistd.h> 41 : #endif 42 : 43 : #include "../bashintl.h" 44 : 45 : #include "../shell.h" 46 : #include "common.h" 47 : 48 : extern char *this_command_name; 49 : extern int posixly_correct; 50 : 51 : static int check_loop_level __P((void)); 52 : 53 : /* The depth of while's and until's. */ 54 : int loop_level = 0; 55 : 56 : /* Non-zero when a "break" instruction is encountered. */ 57 : int breaking = 0; 58 : 59 : /* Non-zero when we have encountered a continue instruction. */ 60 : int continuing = 0; 61 : 62 : /* Set up to break x levels, where x defaults to 1, but can be specified 63 : as the first argument. */ 64 : int 65 66 : break_builtin (list) 66 : WORD_LIST *list; 67 : { 68 66 : intmax_t newbreak; 69 : 70 66 : CHECK_HELPOPT (list); 71 : 72 66 : if (check_loop_level () == 0) 73 : return (EXECUTION_SUCCESS); 74 : 75 0 : (void)get_numeric_arg (list, 1, &newbreak); 76 : 77 0 : if (newbreak <= 0) 78 : { 79 0 : sh_erange (list->word->word, _("loop count")); 80 0 : breaking = loop_level; 81 0 : return (EXECUTION_FAILURE); 82 : } 83 : 84 0 : if (newbreak > loop_level) 85 0 : newbreak = loop_level; 86 : 87 0 : breaking = newbreak; 88 : 89 0 : return (EXECUTION_SUCCESS); 90 : } 91 : 92 : $BUILTIN continue 93 : $FUNCTION continue_builtin 94 : $SHORT_DOC continue [n] 95 : Resume for, while, or until loops. 96 : 97 : Resumes the next iteration of the enclosing FOR, WHILE or UNTIL loop. 98 : If N is specified, resumes the Nth enclosing loop. 99 : 100 : Exit Status: 101 : The exit status is 0 unless N is not greater than or equal to 1. 102 : $END 103 : 104 : /* Set up to continue x levels, where x defaults to 1, but can be specified 105 : as the first argument. */ 106 : int 107 75 : continue_builtin (list) 108 : WORD_LIST *list; 109 : { 110 75 : intmax_t newcont; 111 : 112 75 : CHECK_HELPOPT (list); 113 : 114 75 : if (check_loop_level () == 0) 115 : return (EXECUTION_SUCCESS); 116 : 117 0 : (void)get_numeric_arg (list, 1, &newcont); 118 : 119 0 : if (newcont <= 0) 120 : { 121 0 : sh_erange (list->word->word, _("loop count")); 122 0 : breaking = loop_level; 123 0 : return (EXECUTION_FAILURE); 124 : } 125 : 126 0 : if (newcont > loop_level) 127 0 : newcont = loop_level; 128 : 129 0 : continuing = newcont; 130 : 131 0 : return (EXECUTION_SUCCESS); 132 : } 133 : 134 : /* Return non-zero if a break or continue command would be okay. 135 : Print an error message if break or continue is meaningless here. */ 136 : static int 137 141 : check_loop_level () 138 : { 139 : #if defined (BREAK_COMPLAINS) 140 141 : if (loop_level == 0 && posixly_correct == 0) 141 141 : builtin_error (_("only meaningful in a `for', `while', or `until' loop")); 142 : #endif /* BREAK_COMPLAINS */ 143 : 144 141 : return (loop_level); 145 : }