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:
+ @:;