improve of cmpl.
[bush.git] / builtins / break.def
blobc234170e9025b9e94297a8a6bbb8dff264bd2c79
1 This file is break.def, from which is created break.c.
2 It implements the builtins "break" and "continue" in Bush.
4 Copyright (C) 1987-2020 Free Software Foundation, Inc.
6 This file is part of GNU Bush, the Bourne Again SHell.
8 Bush 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.
13 Bush 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.
18 You should have received a copy of the GNU General Public License
19 along with Bush. If not, see <http://www.gnu.org/licenses/>.
21 $PRODUCES break.c
23 $BUILTIN break
24 $FUNCTION break_builtin
25 $SHORT_DOC break [n]
26 Exit for, while, or until loops.
28 Exit a FOR, WHILE or UNTIL loop. If N is specified, break N enclosing
29 loops.
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>
36 #if defined (HAVE_UNISTD_H)
37 # ifdef _MINIX
38 # include <sys/types.h>
39 # endif
40 # include <unistd.h>
41 #endif
43 #include "../src/bushintl.h"
45 #include "../src/shell.h"
46 #include "../src/runner/execute_cmd.h"
47 #include "common.h"
49 static int check_loop_level PARAMS((void));
51 /* The depth of while's and until's. */
52 int loop_level = 0;
54 /* Non-zero when a "break" instruction is encountered. */
55 int breaking = 0;
57 /* Non-zero when we have encountered a continue instruction. */
58 int continuing = 0;
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;
66 intmax_t newbreak;
68 CHECK_HELPOPT (list);
70 if (check_loop_level () == 0)
71 return (EXECUTION_SUCCESS);
73 (void)get_numeric_arg (list, 1, &newbreak);
75 if (newbreak <= 0)
77 sh_erange (list->word->word, _("loop count"));
78 breaking = loop_level;
79 return (EXECUTION_FAILURE);
82 if (newbreak > loop_level)
83 newbreak = loop_level;
85 breaking = newbreak;
87 return (EXECUTION_SUCCESS);
90 $BUILTIN continue
91 $FUNCTION continue_builtin
92 $SHORT_DOC continue [n]
93 Resume for, while, or until loops.
95 Resumes the next iteration of the enclosing FOR, WHILE or UNTIL loop.
96 If N is specified, resumes the Nth enclosing loop.
98 Exit Status:
99 The exit status is 0 unless N is not greater than or equal to 1.
100 $END
102 /* Set up to continue x levels, where x defaults to 1, but can be specified
103 as the first argument. */
105 continue_builtin (list)
106 WORD_LIST *list;
108 intmax_t newcont;
110 CHECK_HELPOPT (list);
112 if (check_loop_level () == 0)
113 return (EXECUTION_SUCCESS);
115 (void)get_numeric_arg (list, 1, &newcont);
117 if (newcont <= 0)
119 sh_erange (list->word->word, _("loop count"));
120 breaking = loop_level;
121 return (EXECUTION_FAILURE);
124 if (newcont > loop_level)
125 newcont = loop_level;
127 continuing = newcont;
129 return (EXECUTION_SUCCESS);
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 ()
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 */
142 return (loop_level);