Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/make Add :On for numeric sort



details:   https://anonhg.NetBSD.org/src/rev/3b44c67d3d88
branches:  trunk
changeset: 984904:3b44c67d3d88
user:      sjg <sjg%NetBSD.org@localhost>
date:      Fri Jul 30 19:55:22 2021 +0000

description:
Add :On for numeric sort

Reviewed by: christos rillig

diffstat:

 usr.bin/make/make.1                              |  14 +++-
 usr.bin/make/unit-tests/Makefile                 |   3 +-
 usr.bin/make/unit-tests/varmod-order-numeric.exp |   1 +
 usr.bin/make/unit-tests/varmod-order-numeric.mk  |  18 +++++
 usr.bin/make/var.c                               |  74 ++++++++++++++++++++++-
 5 files changed, 103 insertions(+), 7 deletions(-)

diffs (204 lines):

diff -r 701bbc7c79ca -r 3b44c67d3d88 usr.bin/make/make.1
--- a/usr.bin/make/make.1       Fri Jul 30 13:44:09 2021 +0000
+++ b/usr.bin/make/make.1       Fri Jul 30 19:55:22 2021 +0000
@@ -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 @@
 .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
diff -r 701bbc7c79ca -r 3b44c67d3d88 usr.bin/make/unit-tests/Makefile
--- a/usr.bin/make/unit-tests/Makefile  Fri Jul 30 13:44:09 2021 +0000
+++ b/usr.bin/make/unit-tests/Makefile  Fri Jul 30 19:55:22 2021 +0000
@@ -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-escape
 TESTS+=                varmod-no-match
 TESTS+=                varmod-order
+TESTS+=                varmod-order-numeric
 TESTS+=                varmod-order-reverse
 TESTS+=                varmod-order-shuffle
 TESTS+=                varmod-path
diff -r 701bbc7c79ca -r 3b44c67d3d88 usr.bin/make/unit-tests/varmod-order-numeric.exp
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/make/unit-tests/varmod-order-numeric.exp  Fri Jul 30 19:55:22 2021 +0000
@@ -0,0 +1,1 @@
+exit status 0
diff -r 701bbc7c79ca -r 3b44c67d3d88 usr.bin/make/unit-tests/varmod-order-numeric.mk
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/make/unit-tests/varmod-order-numeric.mk   Fri Jul 30 19:55:22 2021 +0000
@@ -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:
+       @:;
diff -r 701bbc7c79ca -r 3b44c67d3d88 usr.bin/make/var.c
--- a/usr.bin/make/var.c        Fri Jul 30 13:44:09 2021 +0000
+++ b/usr.bin/make/var.c        Fri Jul 30 19:55:22 2021 +0000
@@ -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 @@
        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 @@
        }
 }
 
-/* :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 @@
        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);



Home | Main Index | Thread Index | Old Index