Module Name: src Committed By: sjg Date: Fri Sep 2 16:24:31 UTC 2022
Modified Files: src/usr.bin/make: cond.c for.c make.1 make.h parse.c src/usr.bin/make/unit-tests: Makefile Added Files: src/usr.bin/make/unit-tests: directive-for-break.exp directive-for-break.mk Log Message: make: add .break to terminate .for loop early When .break is encountered within a .for loop it causes immediate termination. Outside of a .for loop .break causes a parse error. Reviewed by: christos To generate a diff of this commit: cvs rdiff -u -r1.334 -r1.335 src/usr.bin/make/cond.c cvs rdiff -u -r1.168 -r1.169 src/usr.bin/make/for.c cvs rdiff -u -r1.330 -r1.331 src/usr.bin/make/make.1 cvs rdiff -u -r1.303 -r1.304 src/usr.bin/make/make.h cvs rdiff -u -r1.681 -r1.682 src/usr.bin/make/parse.c cvs rdiff -u -r1.321 -r1.322 src/usr.bin/make/unit-tests/Makefile cvs rdiff -u -r0 -r1.1 src/usr.bin/make/unit-tests/directive-for-break.exp \ src/usr.bin/make/unit-tests/directive-for-break.mk Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/make/cond.c diff -u src/usr.bin/make/cond.c:1.334 src/usr.bin/make/cond.c:1.335 --- src/usr.bin/make/cond.c:1.334 Fri Apr 15 09:33:20 2022 +++ src/usr.bin/make/cond.c Fri Sep 2 16:24:31 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: cond.c,v 1.334 2022/04/15 09:33:20 rillig Exp $ */ +/* $NetBSD: cond.c,v 1.335 2022/09/02 16:24:31 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -95,7 +95,7 @@ #include "dir.h" /* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */ -MAKE_RCSID("$NetBSD: cond.c,v 1.334 2022/04/15 09:33:20 rillig Exp $"); +MAKE_RCSID("$NetBSD: cond.c,v 1.335 2022/09/02 16:24:31 sjg Exp $"); /* * Conditional expressions conform to this grammar: @@ -1275,3 +1275,14 @@ Cond_save_depth(void) cond_min_depth = cond_depth; return depth; } + +/* + * When we break out of a .for loop + * we want to restore cond_depth to where it was + * when the loop started. + */ +void +Cond_reset_depth(unsigned int depth) +{ + cond_depth = depth; +} Index: src/usr.bin/make/for.c diff -u src/usr.bin/make/for.c:1.168 src/usr.bin/make/for.c:1.169 --- src/usr.bin/make/for.c:1.168 Sun Jun 12 16:09:21 2022 +++ src/usr.bin/make/for.c Fri Sep 2 16:24:31 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: for.c,v 1.168 2022/06/12 16:09:21 rillig Exp $ */ +/* $NetBSD: for.c,v 1.169 2022/09/02 16:24:31 sjg Exp $ */ /* * Copyright (c) 1992, The Regents of the University of California. @@ -58,7 +58,7 @@ #include "make.h" /* "@(#)for.c 8.1 (Berkeley) 6/6/93" */ -MAKE_RCSID("$NetBSD: for.c,v 1.168 2022/06/12 16:09:21 rillig Exp $"); +MAKE_RCSID("$NetBSD: for.c,v 1.169 2022/09/02 16:24:31 sjg Exp $"); typedef struct ForLoop { @@ -504,3 +504,11 @@ For_Run(unsigned headLineno, unsigned bo } else ForLoop_Free(f); } + +/* Breaking out of a .for loop */ +void +For_Break(ForLoop *f) +{ + f->nextItem = f->items.len; +} + Index: src/usr.bin/make/make.1 diff -u src/usr.bin/make/make.1:1.330 src/usr.bin/make/make.1:1.331 --- src/usr.bin/make/make.1:1.330 Sun Aug 14 22:11:20 2022 +++ src/usr.bin/make/make.1 Fri Sep 2 16:24:31 2022 @@ -1,4 +1,4 @@ -.\" $NetBSD: make.1,v 1.330 2022/08/14 22:11:20 uwe Exp $ +.\" $NetBSD: make.1,v 1.331 2022/09/02 16:24:31 sjg Exp $ .\" .\" Copyright (c) 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -29,7 +29,7 @@ .\" .\" from: @(#)make.1 8.4 (Berkeley) 3/19/94 .\" -.Dd August 14, 2022 +.Dd September 2, 2022 .Dt MAKE 1 .Os .Sh NAME @@ -2084,6 +2084,14 @@ inside the body of the for loop. The number of words must come out even; that is, if there are three iteration variables, the number of words provided must be a multiple of three. + +If +.Sq Ic .break +is encountered within a +.Cm \&.for +loop, it causes early termination of the loop, +otherwise a parse error. + .Sh COMMENTS Comments begin with a hash .Pq Ql \&# Index: src/usr.bin/make/make.h diff -u src/usr.bin/make/make.h:1.303 src/usr.bin/make/make.h:1.304 --- src/usr.bin/make/make.h:1.303 Sun Jun 12 13:37:32 2022 +++ src/usr.bin/make/make.h Fri Sep 2 16:24:31 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: make.h,v 1.303 2022/06/12 13:37:32 rillig Exp $ */ +/* $NetBSD: make.h,v 1.304 2022/09/02 16:24:31 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -800,6 +800,7 @@ void Compat_Make(GNode *, GNode *); CondResult Cond_EvalCondition(const char *) MAKE_ATTR_USE; CondResult Cond_EvalLine(const char *) MAKE_ATTR_USE; void Cond_restore_depth(unsigned int); +void Cond_reset_depth(unsigned int); unsigned int Cond_save_depth(void) MAKE_ATTR_USE; /* dir.c; see also dir.h */ @@ -829,6 +830,7 @@ void For_Run(unsigned, unsigned); bool For_NextIteration(struct ForLoop *, Buffer *); char *ForLoop_Details(struct ForLoop *); void ForLoop_Free(struct ForLoop *); +void For_Break(struct ForLoop *); /* job.c */ void JobReapChild(pid_t, int, bool); Index: src/usr.bin/make/parse.c diff -u src/usr.bin/make/parse.c:1.681 src/usr.bin/make/parse.c:1.682 --- src/usr.bin/make/parse.c:1.681 Sun Jul 24 20:25:23 2022 +++ src/usr.bin/make/parse.c Fri Sep 2 16:24:31 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: parse.c,v 1.681 2022/07/24 20:25:23 rillig Exp $ */ +/* $NetBSD: parse.c,v 1.682 2022/09/02 16:24:31 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -105,7 +105,7 @@ #include "pathnames.h" /* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: parse.c,v 1.681 2022/07/24 20:25:23 rillig Exp $"); +MAKE_RCSID("$NetBSD: parse.c,v 1.682 2022/09/02 16:24:31 sjg Exp $"); /* * A file being read. @@ -2689,7 +2689,17 @@ ParseDirective(char *line) pp_skip_whitespace(&cp); arg = cp; - if (Substring_Equals(dir, "undef")) + if (Substring_Equals(dir, "break")) { + IncludedFile *curFile = CurFile(); + + if (curFile->forLoop != NULL) { + /* pretend we reached EOF */ + For_Break(curFile->forLoop); + Cond_reset_depth(curFile->cond_depth); + ParseEOF(); + } else + Parse_Error(PARSE_FATAL, "break outside of for loop"); + } else if (Substring_Equals(dir, "undef")) Var_Undef(arg); else if (Substring_Equals(dir, "export")) Var_Export(VEM_PLAIN, arg); Index: src/usr.bin/make/unit-tests/Makefile diff -u src/usr.bin/make/unit-tests/Makefile:1.321 src/usr.bin/make/unit-tests/Makefile:1.322 --- src/usr.bin/make/unit-tests/Makefile:1.321 Thu Aug 25 06:23:38 2022 +++ src/usr.bin/make/unit-tests/Makefile Fri Sep 2 16:24:31 2022 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.321 2022/08/25 06:23:38 rillig Exp $ +# $NetBSD: Makefile,v 1.322 2022/09/02 16:24:31 sjg Exp $ # # Unit tests for make(1) # @@ -168,6 +168,7 @@ TESTS+= directive-export-impl TESTS+= directive-export-gmake TESTS+= directive-export-literal TESTS+= directive-for +#TESTS+= directive-for-break TESTS+= directive-for-empty TESTS+= directive-for-errors TESTS+= directive-for-escape Added files: Index: src/usr.bin/make/unit-tests/directive-for-break.exp diff -u /dev/null src/usr.bin/make/unit-tests/directive-for-break.exp:1.1 --- /dev/null Fri Sep 2 16:24:31 2022 +++ src/usr.bin/make/unit-tests/directive-for-break.exp Fri Sep 2 16:24:31 2022 @@ -0,0 +1,5 @@ +make: "directive-for-break.mk" line 16: I=3 +make: "directive-for-break.mk" line 24: break outside of for loop +make: Fatal errors encountered -- cannot continue +make: stopped in unit-tests +exit status 1 Index: src/usr.bin/make/unit-tests/directive-for-break.mk diff -u /dev/null src/usr.bin/make/unit-tests/directive-for-break.mk:1.1 --- /dev/null Fri Sep 2 16:24:31 2022 +++ src/usr.bin/make/unit-tests/directive-for-break.mk Fri Sep 2 16:24:31 2022 @@ -0,0 +1,25 @@ +# $NetBSD: directive-for-break.mk,v 1.1 2022/09/02 16:24:31 sjg Exp $ +# +# Tests for .break in .for loops + +I= 0 +LIST= 1 2 3 4 5 6 7 8 + +# .break terminates the loop early +# this is usually done within a conditional +.for i in ${LIST} +.if $i == 3 +I:= $i +.break +.endif +.endfor +.info I=$I + +# .break outside the context of a .for loop is an error +.if $I == 0 +# harmless +.break +.else +# error +.break +.endif