git: 25a8168f86a1 - main - m4: Change defn processing order

From: Dag-Erling Smørgrav <des_at_FreeBSD.org>
Date: Sat, 07 Feb 2026 18:17:05 UTC
The branch main has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=25a8168f86a1222388475ce858da405e4d06c1c3

commit 25a8168f86a1222388475ce858da405e4d06c1c3
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2026-02-07 18:16:21 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2026-02-07 18:16:21 +0000

    m4: Change defn processing order
    
    Currently, defn pushes its arguments on the stack in order, which means
    they are then processed in reverse order.  POSIX does not specify what
    order they are processed in, which arguably suggests that they should be
    processed in the order they are listed.  Push them in reverse order so
    they will be processed in their original order.  This matches GNU m4.
    
    PR:             292937
    MFC after:      1 week
    Sponsored by:   Klara, Inc.
    Reviewed by:    obiwac, imp
    Differential Revision:  https://reviews.freebsd.org/D55116
---
 usr.bin/m4/eval.c                 | 2 +-
 usr.bin/m4/tests/Makefile         | 2 ++
 usr.bin/m4/tests/defn.m4          | 5 +++++
 usr.bin/m4/tests/m4_test.sh       | 9 +++++++++
 usr.bin/m4/tests/regress.defn.out | 1 +
 5 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/usr.bin/m4/eval.c b/usr.bin/m4/eval.c
index 3170d52bfe2a..4e45a71874e1 100644
--- a/usr.bin/m4/eval.c
+++ b/usr.bin/m4/eval.c
@@ -490,7 +490,7 @@ expand_builtin(const char *argv[], int argc, int td)
 
 	case DEFNTYPE:
 		if (argc > 2)
-			for (n = 2; n < argc; n++)
+			for (n = argc - 1; n >= 2; n--)
 				dodefn(argv[n]);
 		break;
 
diff --git a/usr.bin/m4/tests/Makefile b/usr.bin/m4/tests/Makefile
index bbf26d4e42d9..fd7a44cea14c 100644
--- a/usr.bin/m4/tests/Makefile
+++ b/usr.bin/m4/tests/Makefile
@@ -5,6 +5,7 @@ ATF_TESTS_SH=	m4_test
 ${PACKAGE}FILES+=		args.m4
 ${PACKAGE}FILES+=		args2.m4
 ${PACKAGE}FILES+=		comments.m4
+${PACKAGE}FILES+=		defn.m4
 ${PACKAGE}FILES+=		esyscmd.m4
 ${PACKAGE}FILES+=		eval.m4
 ${PACKAGE}FILES+=		ff_after_dnl.m4.uu
@@ -27,6 +28,7 @@ ${PACKAGE}FILES+=		translit2.m4
 ${PACKAGE}FILES+=		regress.args.out
 ${PACKAGE}FILES+=		regress.args2.out
 ${PACKAGE}FILES+=		regress.comments.out
+${PACKAGE}FILES+=		regress.defn.out
 ${PACKAGE}FILES+=		regress.esyscmd.out
 ${PACKAGE}FILES+=		regress.eval.out
 ${PACKAGE}FILES+=		regress.ff_after_dnl.out
diff --git a/usr.bin/m4/tests/defn.m4 b/usr.bin/m4/tests/defn.m4
new file mode 100644
index 000000000000..6599f95a5f20
--- /dev/null
+++ b/usr.bin/m4/tests/defn.m4
@@ -0,0 +1,5 @@
+dnl Check that our defn processes its arguments in order.
+define(a,1)dnl
+define(b,2)dnl
+define(c,3)dnl
+defn(`a',`b',`c')
diff --git a/usr.bin/m4/tests/m4_test.sh b/usr.bin/m4/tests/m4_test.sh
index 671f25ff4673..aa9be767d1c9 100644
--- a/usr.bin/m4/tests/m4_test.sh
+++ b/usr.bin/m4/tests/m4_test.sh
@@ -70,6 +70,14 @@ comments_body()
 	m4_test comments
 }
 
+defn_head()
+{
+}
+defn_body()
+{
+	m4_test defn
+}
+
 esyscmd_head()
 {
 }
@@ -219,6 +227,7 @@ atf_init_test_cases()
 	atf_add_test_case args
 	atf_add_test_case args2
 	atf_add_test_case comments
+	atf_add_test_case defn
 	atf_add_test_case esyscmd
 	atf_add_test_case eval
 	atf_add_test_case ff_after_dnl
diff --git a/usr.bin/m4/tests/regress.defn.out b/usr.bin/m4/tests/regress.defn.out
new file mode 100644
index 000000000000..190a18037c64
--- /dev/null
+++ b/usr.bin/m4/tests/regress.defn.out
@@ -0,0 +1 @@
+123