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