Module Name:    src
Committed By:   sjg
Date:           Fri Jul 30 19:55:22 UTC 2021

Modified Files:
        src/usr.bin/make: make.1 var.c
        src/usr.bin/make/unit-tests: Makefile
Added Files:
        src/usr.bin/make/unit-tests: varmod-order-numeric.exp
            varmod-order-numeric.mk

Log Message:
Add :On for numeric sort

Reviewed by: christos rillig


To generate a diff of this commit:
cvs rdiff -u -r1.296 -r1.297 src/usr.bin/make/make.1
cvs rdiff -u -r1.938 -r1.939 src/usr.bin/make/var.c
cvs rdiff -u -r1.280 -r1.281 src/usr.bin/make/unit-tests/Makefile
cvs rdiff -u -r0 -r1.1 src/usr.bin/make/unit-tests/varmod-order-numeric.exp \
    src/usr.bin/make/unit-tests/varmod-order-numeric.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/make.1
diff -u src/usr.bin/make/make.1:1.296 src/usr.bin/make/make.1:1.297
--- src/usr.bin/make/make.1:1.296	Thu Feb  4 21:42:46 2021
+++ src/usr.bin/make/make.1	Fri Jul 30 19:55:22 2021
@@ -1,4 +1,4 @@
-.\"	$NetBSD: make.1,v 1.296 2021/02/04 21:42:46 rillig Exp $
+.\"	$NetBSD: make.1,v 1.297 2021/07/30 19:55:22 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 December 22, 2020
+.Dd July 30, 2020
 .Dt MAKE 1
 .Os
 .Sh NAME
@@ -1232,8 +1232,18 @@ but selects all words which do not match
 .Ar pattern .
 .It Cm \&:O
 Orders every word in variable alphabetically.
+.It Cm \&:On
+Orders every word in variable numerically.
+A number followed by one of
+.Ql K ,
+.Ql M
+or
+.Ql G
+is multiplied by the appropriate factor.
 .It Cm \&:Or
 Orders every word in variable in reverse alphabetical order.
+.It Cm \&:Orn
+Orders every word in variable in reverse numerical order.
 .It Cm \&:Ox
 Shuffles the words in variable.
 The results will be different each time you are referring to the

Index: src/usr.bin/make/var.c
diff -u src/usr.bin/make/var.c:1.938 src/usr.bin/make/var.c:1.939
--- src/usr.bin/make/var.c:1.938	Mon Jun 21 18:25:20 2021
+++ src/usr.bin/make/var.c	Fri Jul 30 19:55:22 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: var.c,v 1.938 2021/06/21 18:25:20 rillig Exp $	*/
+/*	$NetBSD: var.c,v 1.939 2021/07/30 19:55:22 sjg Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -140,7 +140,7 @@
 #include "metachar.h"
 
 /*	"@(#)var.c	8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: var.c,v 1.938 2021/06/21 18:25:20 rillig Exp $");
+MAKE_RCSID("$NetBSD: var.c,v 1.939 2021/07/30 19:55:22 sjg Exp $");
 
 /*
  * Variables are defined using one of the VAR=value assignments.  Their
@@ -3272,6 +3272,56 @@ bad_modifier:
 	return AMR_BAD;
 }
 
+#ifndef NUM_TYPE
+# define NUM_TYPE long long
+#endif
+
+static NUM_TYPE
+num_val(const char *s)
+{
+	NUM_TYPE val;
+	char *ep;
+
+	val = strtoll(s, &ep, 0);
+	if (ep != s) {
+		switch (*ep) {
+		case 'K':
+		case 'k':
+			val <<= 10;
+			break;
+		case 'M':
+		case 'm':
+			val <<= 20;
+			break;
+		case 'G':
+		case 'g':
+			val <<= 30;
+			break;
+		}
+	}
+	return val;
+}
+
+static int
+num_cmp_asc(const void *sa, const void *sb)
+{
+	NUM_TYPE a, b;
+
+	a = num_val(*(const char *const *)sa);
+	b = num_val(*(const char *const *)sb);
+	return (a > b) ? 1 : (b > a) ? -1 : 0;
+}
+    
+static int
+num_cmp_desc(const void *sa, const void *sb)
+{
+	NUM_TYPE a, b;
+
+	a = num_val(*(const char *const *)sa);
+	b = num_val(*(const char *const *)sb);
+	return (a > b) ? -1 : (b > a) ? 1 : 0;
+}
+    
 static int
 str_cmp_asc(const void *a, const void *b)
 {
@@ -3297,22 +3347,35 @@ ShuffleStrings(char **strs, size_t n)
 	}
 }
 
-/* :O (order ascending) or :Or (order descending) or :Ox (shuffle) */
+/* :O (order ascending) or :Or (order descending) or :Ox (shuffle) or
+ * :On (numeric ascending) or :Onr or :Orn (numeric descending)
+ */
 static ApplyModifierResult
 ApplyModifier_Order(const char **pp, ModChain *ch)
 {
 	const char *mod = (*pp)++;	/* skip past the 'O' in any case */
 	Words words;
 	enum SortMode {
-		ASC, DESC, SHUFFLE
+		ASC, DESC, NUM_ASC, NUM_DESC, SHUFFLE
 	} mode;
 
 	if (IsDelimiter(mod[1], ch)) {
 		mode = ASC;
+	} else if (mod[1] == 'n') {
+		mode = NUM_ASC;
+		(*pp)++;
+		if (!IsDelimiter(mod[2], ch)) {
+			(*pp)++;
+			if (mod[2] == 'r')
+				mode = NUM_DESC;
+		}
 	} else if ((mod[1] == 'r' || mod[1] == 'x') &&
 	    IsDelimiter(mod[2], ch)) {
 		(*pp)++;
 		mode = mod[1] == 'r' ? DESC : SHUFFLE;
+	} else if (mod[1] == 'r' && mod[2] == 'n') {
+		(*pp) += 2;
+		mode = NUM_DESC;
 	} else
 		return AMR_BAD;
 
@@ -3322,6 +3385,9 @@ ApplyModifier_Order(const char **pp, Mod
 	words = Str_Words(ch->expr->value.str, false);
 	if (mode == SHUFFLE)
 		ShuffleStrings(words.words, words.len);
+	else if (mode == NUM_ASC || mode == NUM_DESC)
+		qsort(words.words, words.len, sizeof words.words[0],
+		    mode == NUM_ASC ? num_cmp_asc : num_cmp_desc);
 	else
 		qsort(words.words, words.len, sizeof words.words[0],
 		    mode == ASC ? str_cmp_asc : str_cmp_desc);

Index: src/usr.bin/make/unit-tests/Makefile
diff -u src/usr.bin/make/unit-tests/Makefile:1.280 src/usr.bin/make/unit-tests/Makefile:1.281
--- src/usr.bin/make/unit-tests/Makefile:1.280	Tue Jun 29 00:35:23 2021
+++ src/usr.bin/make/unit-tests/Makefile	Fri Jul 30 19:55:22 2021
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.280 2021/06/29 00:35:23 sjg Exp $
+# $NetBSD: Makefile,v 1.281 2021/07/30 19:55:22 sjg Exp $
 #
 # Unit tests for make(1)
 #
@@ -355,6 +355,7 @@ TESTS+=		varmod-match
 TESTS+=		varmod-match-escape
 TESTS+=		varmod-no-match
 TESTS+=		varmod-order
+TESTS+=		varmod-order-numeric
 TESTS+=		varmod-order-reverse
 TESTS+=		varmod-order-shuffle
 TESTS+=		varmod-path

Added files:

Index: src/usr.bin/make/unit-tests/varmod-order-numeric.exp
diff -u /dev/null src/usr.bin/make/unit-tests/varmod-order-numeric.exp:1.1
--- /dev/null	Fri Jul 30 19:55:22 2021
+++ src/usr.bin/make/unit-tests/varmod-order-numeric.exp	Fri Jul 30 19:55:22 2021
@@ -0,0 +1 @@
+exit status 0
Index: src/usr.bin/make/unit-tests/varmod-order-numeric.mk
diff -u /dev/null src/usr.bin/make/unit-tests/varmod-order-numeric.mk:1.1
--- /dev/null	Fri Jul 30 19:55:22 2021
+++ src/usr.bin/make/unit-tests/varmod-order-numeric.mk	Fri Jul 30 19:55:22 2021
@@ -0,0 +1,18 @@
+# $NetBSD: varmod-order-numeric.mk,v 1.1 2021/07/30 19:55:22 sjg Exp $
+#
+# Tests for the :On variable modifier, which returns the words, sorted in
+# ascending numeric order.
+
+NUMBERS=	3 5 7 1 42 -42 1M 1k
+
+.if ${NUMBERS:On} != "-42 1 3 5 7 42 1k 1M"
+.  error ${NUMBERS:On}
+.endif
+
+.if ${NUMBERS:Orn} != "1M 1k 42 7 5 3 1 -42"
+.  error ${NUMBERS:Orn}
+.endif
+
+
+all:
+	@:;

Reply via email to