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