Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/make make: add .break to terminate .for loop early
details: https://anonhg.NetBSD.org/src/rev/ef7b849365c2
branches: trunk
changeset: 369825:ef7b849365c2
user: sjg <sjg%NetBSD.org@localhost>
date: Fri Sep 02 16:24:31 2022 +0000
description:
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
diffstat:
usr.bin/make/cond.c | 15 +++++++++++++--
usr.bin/make/for.c | 12 ++++++++++--
usr.bin/make/make.1 | 12 ++++++++++--
usr.bin/make/make.h | 4 +++-
usr.bin/make/parse.c | 16 +++++++++++++---
usr.bin/make/unit-tests/Makefile | 3 ++-
usr.bin/make/unit-tests/directive-for-break.exp | 5 +++++
usr.bin/make/unit-tests/directive-for-break.mk | 25 +++++++++++++++++++++++++
8 files changed, 81 insertions(+), 11 deletions(-)
diffs (213 lines):
diff -r 9e9980d3fbfc -r ef7b849365c2 usr.bin/make/cond.c
--- a/usr.bin/make/cond.c Fri Sep 02 12:48:04 2022 +0000
+++ b/usr.bin/make/cond.c Fri Sep 02 16:24:31 2022 +0000
@@ -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_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;
+}
diff -r 9e9980d3fbfc -r ef7b849365c2 usr.bin/make/for.c
--- a/usr.bin/make/for.c Fri Sep 02 12:48:04 2022 +0000
+++ b/usr.bin/make/for.c Fri Sep 02 16:24:31 2022 +0000
@@ -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 @@
} else
ForLoop_Free(f);
}
+
+/* Breaking out of a .for loop */
+void
+For_Break(ForLoop *f)
+{
+ f->nextItem = f->items.len;
+}
+
diff -r 9e9980d3fbfc -r ef7b849365c2 usr.bin/make/make.1
--- a/usr.bin/make/make.1 Fri Sep 02 12:48:04 2022 +0000
+++ b/usr.bin/make/make.1 Fri Sep 02 16:24:31 2022 +0000
@@ -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 @@
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 \&#
diff -r 9e9980d3fbfc -r ef7b849365c2 usr.bin/make/make.h
--- a/usr.bin/make/make.h Fri Sep 02 12:48:04 2022 +0000
+++ b/usr.bin/make/make.h Fri Sep 02 16:24:31 2022 +0000
@@ -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 @@
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 @@
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);
diff -r 9e9980d3fbfc -r ef7b849365c2 usr.bin/make/parse.c
--- a/usr.bin/make/parse.c Fri Sep 02 12:48:04 2022 +0000
+++ b/usr.bin/make/parse.c Fri Sep 02 16:24:31 2022 +0000
@@ -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 @@
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);
diff -r 9e9980d3fbfc -r ef7b849365c2 usr.bin/make/unit-tests/Makefile
--- a/usr.bin/make/unit-tests/Makefile Fri Sep 02 12:48:04 2022 +0000
+++ b/usr.bin/make/unit-tests/Makefile Fri Sep 02 16:24:31 2022 +0000
@@ -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-gmake
TESTS+= directive-export-literal
TESTS+= directive-for
+#TESTS+= directive-for-break
TESTS+= directive-for-empty
TESTS+= directive-for-errors
TESTS+= directive-for-escape
diff -r 9e9980d3fbfc -r ef7b849365c2 usr.bin/make/unit-tests/directive-for-break.exp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/make/unit-tests/directive-for-break.exp Fri Sep 02 16:24:31 2022 +0000
@@ -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
diff -r 9e9980d3fbfc -r ef7b849365c2 usr.bin/make/unit-tests/directive-for-break.mk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/make/unit-tests/directive-for-break.mk Fri Sep 02 16:24:31 2022 +0000
@@ -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
Home |
Main Index |
Thread Index |
Old Index