]> git.ipfire.org Git - thirdparty/bash.git/blob - builtins/break.def
bash-5.0 distribution sources and documentation
[thirdparty/bash.git] / builtins / break.def
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 "../execute_cmd.h"
47 #include "common.h"
48
49 static int check_loop_level __P((void));
50
51 /* The depth of while's and until's. */
52 int loop_level = 0;
53
54 /* Non-zero when a "break" instruction is encountered. */
55 int breaking = 0;
56
57 /* Non-zero when we have encountered a continue instruction. */
58 int continuing = 0;
59
60 /* Set up to break x levels, where x defaults to 1, but can be specified
61 as the first argument. */
62 int
63 break_builtin (list)
64 WORD_LIST *list;
65 {
66 intmax_t newbreak;
67
68 CHECK_HELPOPT (list);
69
70 if (check_loop_level () == 0)
71 return (EXECUTION_SUCCESS);
72
73 (void)get_numeric_arg (list, 1, &newbreak);
74
75 if (newbreak <= 0)
76 {
77 sh_erange (list->word->word, _("loop count"));
78 breaking = loop_level;
79 return (EXECUTION_FAILURE);
80 }
81
82 if (newbreak > loop_level)
83 newbreak = loop_level;
84
85 breaking = newbreak;
86
87 return (EXECUTION_SUCCESS);
88 }
89
90 $BUILTIN continue
91 $FUNCTION continue_builtin
92 $SHORT_DOC continue [n]
93 Resume for, while, or until loops.
94
95 Resumes the next iteration of the enclosing FOR, WHILE or UNTIL loop.
96 If N is specified, resumes the Nth enclosing loop.
97
98 Exit Status:
99 The exit status is 0 unless N is not greater than or equal to 1.
100 $END
101
102 /* Set up to continue x levels, where x defaults to 1, but can be specified
103 as the first argument. */
104 int
105 continue_builtin (list)
106 WORD_LIST *list;
107 {
108 intmax_t newcont;
109
110 CHECK_HELPOPT (list);
111
112 if (check_loop_level () == 0)
113 return (EXECUTION_SUCCESS);
114
115 (void)get_numeric_arg (list, 1, &newcont);
116
117 if (newcont <= 0)
118 {
119 sh_erange (list->word->word, _("loop count"));
120 breaking = loop_level;
121 return (EXECUTION_FAILURE);
122 }
123
124 if (newcont > loop_level)
125 newcont = loop_level;
126
127 continuing = newcont;
128
129 return (EXECUTION_SUCCESS);
130 }
131
132 /* Return non-zero if a break or continue command would be okay.
133 Print an error message if break or continue is meaningless here. */
134 static int
135 check_loop_level ()
136 {
137 #if defined (BREAK_COMPLAINS)
138 if (loop_level == 0 && posixly_correct == 0)
139 builtin_error (_("only meaningful in a `for', `while', or `until' loop"));
140 #endif /* BREAK_COMPLAINS */
141
142 return (loop_level);
143 }