Re: [PATCH 3/3] Introduce $(compare ...) for numerical comparison

2021-12-06 Thread Edward Welbourne
On Nov 28 2021, Paul Smith wrote:
>> The C standard defines the largest unsigned long long value
>> as 18446744073709551615, the largest signed long long value
>> as 9223372036854775807, and the smallest signed long long value as -
>> 9223372036854775808.  So, the definition cannot be wrong in any
>> standards-conforming implementation of C.

Andreas Schwab (6 December 2021 12:30) replied:
> This is wrong.  These are *minimum* limits.

For reference: the number of bytes needed for the ASCII decimal
representation (including terminating '\0') of an integral type is
bounded (fairly tightly) above by

  53 * sizeof(type) / 22 + (3 if type is signed else 2)

When I need a compile-time constant for an array buffer size, this is
what I use.  Fuller explanation here:
https://github.com/ediosyncratic/study.py/blob/master/maths/buffersize.py

Eddy.



Re: [PATCH 3/3] Introduce $(compare ...) for numerical comparison

2021-12-06 Thread Andreas Schwab
On Nov 28 2021, Paul Smith wrote:

> The C standard defines the largest unsigned long long value
> as 18446744073709551615, the largest signed long long value
> as 9223372036854775807, and the smallest signed long long value as -
> 9223372036854775808.  So, the definition cannot be wrong in any
> standards-conforming implementation of C.

This is wrong.  These are *minimum* limits.

Andreas.

-- 
Andreas Schwab, SUSE Labs, sch...@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."



Re: [PATCH 3/3] Introduce $(compare ...) for numerical comparison

2021-11-28 Thread Paul Smith
On Sun, 2021-11-28 at 15:49 +0100, Jouke Witteveen wrote:
> I fully agree, but was not aware of the robustness of INTSTR_LENGTH.
> It felt a bit fragile when I spotted its definition in makeint.h.

The C standard defines the largest unsigned long long value
as 18446744073709551615, the largest signed long long value
as 9223372036854775807, and the smallest signed long long value as -
9223372036854775808.  So, the definition cannot be wrong in any
standards-conforming implementation of C.

> File sizes are an interesting application indeed. If you want me to
> change the patches to use strtoll, I would need some help since I am
> not sure how to set things up so that we get a fallback
> implementation on platforms where it is missing.

I already did it locally, thanks for the offer.  I enhanced the tests
to check that the above (signed) values are parsed correctly.

I just changed the gnulib import of "strtol" to "strtoll".  strtoll()
is required by the C99 standard (which we were forced to require in GNU
make as well, since gnulib requires it) so it's pretty much everywhere
these days.  There are a few older platforms where it has incorrect
implementations that gnulib will take care of for us.

Cheers!




Re: [PATCH 3/3] Introduce $(compare ...) for numerical comparison

2021-11-28 Thread Jouke Witteveen
On Sun, Nov 28, 2021 at 3:20 PM Paul Smith  wrote:
>
> On Sun, 2021-11-28 at 14:57 +0100, Jouke Witteveen wrote:
> > > Since the two arguments are equal, it doesn't matter which of LHS
> > > or RHS we return.
> >
> > They could differ for instance when one of them contains a '+'-sign.
> > My reason for using LHS is that we already have a string for it.
>
> I don't think that it's necessary return the exact string.  If the user
> wanted a string match they can do that other ways.  Returning the
> "absolute value" (stripping leading +/-, leading 0's, etc.) seems more
> useful to me.

I fully agree, but was not aware of the robustness of INTSTR_LENGTH.
It felt a bit fragile when I spotted its definition in makeint.h.

> > > However, now that I think about it I need to change the code more: we
> > > need to be using "long long" here not just "long".  While on Linux etc.
> > > a "long" is 8 bytes, on Windows "long" is only 4 bytes.
> >
> > I was hoping this would not be necessary, and I cannot think of a
> > typical use case where make is a good fit for dealing with large
> > integers. The benefit of "long" is that strtol is more widely
> > available than strtoll.
>
> I see what you mean, but I _really_ don't like the idea of GNU make
> working differently on different platforms, even if such use cases are
> rare.  I can imagine a situation where, for example, someone wants to
> compare the sizes of files and if one of the files is >4G then it will
> work on Linux and fail on Windows.

File sizes are an interesting application indeed. If you want me to
change the patches to use strtoll, I would need some help since I am
not sure how to set things up so that we get a fallback implementation
on platforms where it is missing.



Re: [PATCH 3/3] Introduce $(compare ...) for numerical comparison

2021-11-28 Thread Jouke Witteveen
On Sun, Nov 28, 2021 at 3:33 PM Paul Smith  wrote:
>
> On Sun, 2021-11-28 at 08:24 +0100, Jouke Witteveen wrote:
> > On the user side, strcmp could now probably be defined something like
> > $(and $(intcmp $(words $1),$(words $2)),$(findstring x $1 x,x $2 x))
>
> I don't think this is equivalent since a putative strcmp would also do
> greater / less than comparison (like intcmp does).  Of course that
> leads into all sorts of i18n / locale issues, but likely we'd just punt
> (like C's strcmp does) and use ASCII ordering; we've already taken that
> route elsewhere.

This was only intended as a demonstration of how the two-argument
strcmp function could be implemented already (I initially forgot the
spaces around the 'x's). This would serve as a test for exact
string-wise equality.

If anything, this could mean that there is no reason to spend time on
adding strcmp now. It's all a digression and I agree with everything
you said about it.



Re: [PATCH 3/3] Introduce $(compare ...) for numerical comparison

2021-11-28 Thread Paul Smith
On Sun, 2021-11-28 at 08:24 +0100, Jouke Witteveen wrote:
> On the user side, strcmp could now probably be defined something like
> $(and $(intcmp $(words $1),$(words $2)),$(findstring x$1x,x$2x))

I don't think this is equivalent since a putative strcmp would also do
greater / less than comparison (like intcmp does).  Of course that
leads into all sorts of i18n / locale issues, but likely we'd just punt
(like C's strcmp does) and use ASCII ordering; we've already taken that
route elsewhere.

You can probably gin up something that works using $(sort ...) but it
seems tricky.  Anyway I'm not suggesting this be added right now but
just keeping options open for the future.




Re: [PATCH 3/3] Introduce $(compare ...) for numerical comparison

2021-11-28 Thread Paul Smith
On Sun, 2021-11-28 at 14:57 +0100, Jouke Witteveen wrote:
> > Since the two arguments are equal, it doesn't matter which of LHS
> > or RHS we return.
> 
> They could differ for instance when one of them contains a '+'-sign.
> My reason for using LHS is that we already have a string for it.

I don't think that it's necessary return the exact string.  If the user
wanted a string match they can do that other ways.  Returning the
"absolute value" (stripping leading +/-, leading 0's, etc.) seems more
useful to me.

>  By using sprintf, we need to make the buffer big enough, which in
> turn requires INTSTR_LENGTH to be fitting for whatever width a long
> has on the current platform.

That's already the case; GNU make defines this constant to be large
enough to hold the largest possible (8-byte) integer value, regardless
of platform.  This is used in various places when showing output etc.

> > However, now that I think about it I need to change the code more: we
> > need to be using "long long" here not just "long".  While on Linux etc.
> > a "long" is 8 bytes, on Windows "long" is only 4 bytes.
> 
> I was hoping this would not be necessary, and I cannot think of a
> typical use case where make is a good fit for dealing with large
> integers. The benefit of "long" is that strtol is more widely
> available than strtoll.

I see what you mean, but I _really_ don't like the idea of GNU make
working differently on different platforms, even if such use cases are
rare.  I can imagine a situation where, for example, someone wants to
compare the sizes of files and if one of the files is >4G then it will
work on Linux and fail on Windows.




Re: [PATCH 3/3] Introduce $(compare ...) for numerical comparison

2021-11-28 Thread Jouke Witteveen
On Sun, Nov 28, 2021 at 2:45 PM Paul Smith  wrote:
>
> On Sun, 2021-11-28 at 08:24 +0100, Jouke Witteveen wrote:
> > Thanks for sending this message, I would have otherwise prepared and
> > sent an updated patch series today. My plan was to expand to RHS in
> > the two-argument case if both values are equal. I assume you also
> > updated the documentation where needed? If so, there's nothing I have
> > to add and I'm looking forward to the new functionality.
>
> Yes, I updated the docs.
>
> Since the two arguments are equal, it doesn't matter which of LHS or
> RHS we return.

They could differ for instance when one of them contains a '+'-sign.
My reason for using LHS is that we already have a string for it. By
using sprintf, we need to make the buffer big enough, which in turn
requires INTSTR_LENGTH to be fitting for whatever width a long has on
the current platform.

> The change I made was:
>
>   argv += 2;
>
>   if (*argv == NULL)
> {
>   if (lhs == rhs)
> {
>   char buf[INTSTR_LENGTH+1];
>   sprintf (buf, "%ld", lhs);
>   o = variable_buffer_output(o, buf, strlen (buf));
> }
>   return o;
> }
>
> However, now that I think about it I need to change the code more: we
> need to be using "long long" here not just "long".  While on Linux etc.
> a "long" is 8 bytes, on Windows "long" is only 4 bytes.

I was hoping this would not be necessary, and I cannot think of a
typical use case where make is a good fit for dealing with large
integers. The benefit of "long" is that strtol is more widely
available than strtoll.

Regards,
- Jouke



Re: [PATCH 3/3] Introduce $(compare ...) for numerical comparison

2021-11-28 Thread Paul Smith
On Sun, 2021-11-28 at 08:24 +0100, Jouke Witteveen wrote:
> Thanks for sending this message, I would have otherwise prepared and
> sent an updated patch series today. My plan was to expand to RHS in
> the two-argument case if both values are equal. I assume you also
> updated the documentation where needed? If so, there's nothing I have
> to add and I'm looking forward to the new functionality.

Yes, I updated the docs.

Since the two arguments are equal, it doesn't matter which of LHS or
RHS we return.

The change I made was:

  argv += 2;

  if (*argv == NULL)
{
  if (lhs == rhs)
{
  char buf[INTSTR_LENGTH+1];
  sprintf (buf, "%ld", lhs);
  o = variable_buffer_output(o, buf, strlen (buf));
}
  return o;
}

However, now that I think about it I need to change the code more: we
need to be using "long long" here not just "long".  While on Linux etc.
a "long" is 8 bytes, on Windows "long" is only 4 bytes.




Re: [PATCH 3/3] Introduce $(compare ...) for numerical comparison

2021-11-27 Thread Jouke Witteveen
On Sun, Nov 28, 2021 at 5:02 AM Paul Smith  wrote:
>
> On Mon, 2021-11-15 at 20:49 +0100, Jouke Witteveen wrote:
> > It may be obscure, but how about we implement this as well? Sure, the
> > two-argument form of $(compare) will be a little inconsistent, but it
> > may be useful.
>
> I applied this three-patch set.
>
> I left the argument order as you originally specified it, and I added
> support for a 2-argument form that provides a trivial equality as
> above.  Maybe it's weird but I think it might be useful.
>
> The one change I made is changing the name of the function from
> "compare" to "intcmp": I felt "compare" was too generic.  Sometime we
> may want to introduce other types of comparison such as "strcmp" etc.
>
> Let me know what you think about this: I've only applied it to my local
> Git repository but not pushed it yet.
>

Hi Paul,

Thanks for sending this message, I would have otherwise prepared and
sent an updated patch series today. My plan was to expand to RHS in
the two-argument case if both values are equal. I assume you also
updated the documentation where needed? If so, there's nothing I have
to add and I'm looking forward to the new functionality.

On the user side, strcmp could now probably be defined something like
$(and $(intcmp $(words $1),$(words $2)),$(findstring x$1x,x$2x))

Thanks,
- Jouke



Re: [PATCH 3/3] Introduce $(compare ...) for numerical comparison

2021-11-27 Thread Paul Smith
On Mon, 2021-11-15 at 20:49 +0100, Jouke Witteveen wrote:
> It may be obscure, but how about we implement this as well? Sure, the
> two-argument form of $(compare) will be a little inconsistent, but it
> may be useful.

I applied this three-patch set.

I left the argument order as you originally specified it, and I added
support for a 2-argument form that provides a trivial equality as
above.  Maybe it's weird but I think it might be useful.

The one change I made is changing the name of the function from
"compare" to "intcmp": I felt "compare" was too generic.  Sometime we
may want to introduce other types of comparison such as "strcmp" etc.

Let me know what you think about this: I've only applied it to my local
Git repository but not pushed it yet.




Re: [PATCH 3/3] Introduce $(compare ...) for numerical comparison

2021-11-16 Thread Jouke Witteveen
On Tue, Nov 16, 2021 at 10:28 AM Edward Welbourne
 wrote:
>
> On Sun, Nov 14, 2021 at 8:42 PM Paul Smith  wrote:
> > It's even possible to allow $(compare ,) with no other
> > arguments and say that if they are equal then it expands to the value,
> > else it expands to the empty string, to give a very short-circuited
> > equality statement.
>
> I should point out one bug in that: if the two parameters are equal
> *but empty* you're going to mistake that for them being different.

Empty strings will not be accepted as  or , since those
arguments are parsed as numbers. A case like
  $(compare +0,-0)
would expand to "0" (without quotes), which is how the value would be
formatted by the standard C routines.
I don't think there is a bug here.

Regards,
- Jouke



Re: [PATCH 3/3] Introduce $(compare ...) for numerical comparison

2021-11-16 Thread Edward Welbourne
On Sun, Nov 14, 2021 at 8:42 PM Paul Smith  wrote:
> It's even possible to allow $(compare ,) with no other
> arguments and say that if they are equal then it expands to the value,
> else it expands to the empty string, to give a very short-circuited
> equality statement.

I should point out one bug in that: if the two parameters are equal
*but empty* you're going to mistake that for them being different.

Eddy.



Re: [PATCH 3/3] Introduce $(compare ...) for numerical comparison

2021-11-15 Thread Jouke Witteveen
On Sun, Nov 14, 2021 at 8:42 PM Paul Smith  wrote:
>
> On Wed, 2021-11-10 at 18:19 +0100, Jouke Witteveen wrote:
> > On Mon, Nov 8, 2021 at 4:08 PM Paul Smith  wrote:
> >
> > > On Fri, 2021-07-16 at 14:04 +0200, Jouke Witteveen wrote:
> > > > $(compare 
> > > > @var{lhs},@var{rhs},@var{lt-part}[,@var{eq-part}[,@var{gt-part}]])
> > > Let me ask this: would it be better to use a format of:
> > >$(compare , , [, [, ]])
> >
> >   $(if $(compare ,,,they_are_equal,),,)
> >
> > In fact, in the original design you could get away with just the
> > three-argument version of $(compare) in combination with $(if),
> > $(and) and $(or). This is not the case for the alternative design.
>
> Can you explain this, perhaps with an example or two?  I don't quite
> follow.  It seems that:
>
>   $(if $(compare ,,equal),,)
>
> works fine with the alternative syntax.

What I was trying to say is that the two versions differ only in the
abilities provided by their thee-argument forms. It's not much of a
reason to favor one over the other, but the three-argument form of the
original proposal (less-than) is 'complete' in the sense that all of
<, >, =, and their negations can be expressed as boolean combinations
of it. The same is not true of the three-argument form of the
alternative design (e.g. less-than cannot be expressed using the
three-argument version of that design alone).

> It's even possible to allow $(compare ,) with no other
> arguments and say that if they are equal then it expands to the value,
> else it expands to the empty string, to give a very short-circuited
> equality statement.

It may be obscure, but how about we implement this as well? Sure, the
two-argument form of $(compare) will be a little inconsistent, but it
may be useful.

> > I also took a look at other languages. Nearly everywhere I could find
> > three-way comparisons, the possible outcomes are listed as LT, EQ,
> > GT, in that order.
>
> I'm certainly willing to be convinced that the original idea is better,
> but this argument doesn't hold much water for me.  I don't think that
> changing the order of the extra arguments will cause much cognitive
> dissonance for people.

Interesting. The fact that I saw the mental model of the LT, EQ, GT
ordering of outcomes reflected so often was convincing for me that
this would be the more unsurprising design. I'm not saying the
alternative will cause cognitive dissonance, just that the occasional
user of make might not need to consult the reference documentation as
much trying to recall how the compare function works. Admittedly, the
difference, if any, will likely be negligible.

Regards,
- Jouke

P.S.
I started this series saying that I see no merit in discussing
possible extensions and alternatives. Regarding version comparison (a
minefield if you ask me), I'd just like to point out that you can do
basic parsing of a version with
  $(let major minor patch, $(subst ., ,$(version)),)



Re: [PATCH 3/3] Introduce $(compare ...) for numerical comparison

2021-11-14 Thread Paul Smith
On Wed, 2021-11-10 at 18:19 +0100, Jouke Witteveen wrote:
> On Mon, Nov 8, 2021 at 4:08 PM Paul Smith  wrote:
> 
> > On Fri, 2021-07-16 at 14:04 +0200, Jouke Witteveen wrote:
> > > $(compare 
> > > @var{lhs},@var{rhs},@var{lt-part}[,@var{eq-part}[,@var{gt-part}]])
> > Let me ask this: would it be better to use a format of:
> >$(compare , , [, [, ]])
> 
>   $(if $(compare ,,,they_are_equal,),,)
> 
> In fact, in the original design you could get away with just the
> three-argument version of $(compare) in combination with $(if),
> $(and) and $(or). This is not the case for the alternative design.

Can you explain this, perhaps with an example or two?  I don't quite
follow.  It seems that:

  $(if $(compare ,,equal),,)

works fine with the alternative syntax.

It's even possible to allow $(compare ,) with no other
arguments and say that if they are equal then it expands to the value,
else it expands to the empty string, to give a very short-circuited
equality statement.

I do agree, though, that we already have a way to test equality (via
filter-out) and although it will treat "1" and "01" as different this
is probably a rare problem.

> I also took a look at other languages. Nearly everywhere I could find
> three-way comparisons, the possible outcomes are listed as LT, EQ,
> GT, in that order.

I'm certainly willing to be convinced that the original idea is better,
but this argument doesn't hold much water for me.  I don't think that
changing the order of the extra arguments will cause much cognitive
dissonance for people.




RE: [PATCH 3/3] Introduce $(compare ...) for numerical comparison

2021-11-10 Thread rsbecker
On November 10, 2021 12:19 PM, Jouke Witteveen wrote:
> To: psm...@gnu.org
> Cc: bug-make 
> Subject: Re: [PATCH 3/3] Introduce $(compare ...) for numerical comparison
> 
> On Mon, Nov 8, 2021 at 4:08 PM Paul Smith  wrote:
> >
> > On Fri, 2021-07-16 at 14:04 +0200, Jouke Witteveen wrote:
> > > +@item $(compare
> > > +@var{lhs},@var{rhs},@var{lt-part}[,@var{eq-part}[,@var{gt-part}]])
> >
> > Let me ask this: would it be better to use a format of:
> >
> >   $(compare , , [, [, ]])
> >
> > Then the rule is, if the values are equal we get the  part, if lhs
> > is less than rhs we get , and if lhs is greater than rhs we get
> > .
> >
> > If  is not present then the invocation devolves to:
> >
> >   $(compare , , , )
> >
> > that is, the fourth arg is used for not equal.
> >
> > If  is also not present then  is used if the value is equal
> > else it expands to the empty string.
> >
> 
> Cool, an alternative design that has something to go for it! Here is why I 
> like
> the original design better.
> 
> The only real difference is in four-argument usage. This alternative trades 
> the
> 'ordered' nature of the arguments for favoring equality testing. To some
> degree, equality testing is already possible through string-based equality
> testing, and even if you really want to do a numerical equality check, the
> original design allows you to do
> 
>   $(if $(compare ,,,they_are_equal,),,)
> 
> In fact, in the original design you could get away with just the three-
> argument version of $(compare) in combination with $(if), $(and) and $(or).
> This is not the case for the alternative design.
> 
> I also took a look at other languages. Nearly everywhere I could find three-
> way comparisons, the possible outcomes are listed as LT, EQ, GT, in that
> order. Fortran apparently had an "Arithmetic IF", that was also ordered as in
> the original design of $(compare).

I have a similar function in my own fork called $(vcompare), which is similar, 
but does comparison of version-like strings. It does not have the additional 
arguments, which I would think are better separated off into a control function 
like $(if) instead of having then and else built into the $(compare).

Randall




Re: [PATCH 3/3] Introduce $(compare ...) for numerical comparison

2021-11-08 Thread Paul Smith
On Fri, 2021-07-16 at 14:04 +0200, Jouke Witteveen wrote:
> +@item $(compare 
> @var{lhs},@var{rhs},@var{lt-part}[,@var{eq-part}[,@var{gt-part}]])

Let me ask this: would it be better to use a format of:

  $(compare , , [, [, ]])

Then the rule is, if the values are equal we get the  part, if lhs
is less than rhs we get , and if lhs is greater than rhs we get
.

If  is not present then the invocation devolves to:

  $(compare , , , )

that is, the fourth arg is used for not equal.

If  is also not present then  is used if the value is equal
else it expands to the empty string.




Re: [PATCH 3/3] Introduce $(compare ...) for numerical comparison

2021-09-13 Thread Pete Dietl
Also perhaps the more general mathematical function

On Mon, Sep 13, 2021 at 10:04 PM Randall S. Becker 
wrote:

> On September 13, 2021 2:40 PM, Jouke Witteveen wrote:
> >On Fri, Jul 16, 2021 at 2:04 PM Jouke Witteveen 
> wrote:
> >>
> >> Numbers can come from $(words ...), automatic variables such as
> >> $(MAKELEVEL), from environment variables, or from shell output such as
> >> through $(shell expr ...).  The $(compare ...) function allows
> >> conditional evaluation controlled by numerical variables.
> >>
> >> * NEWS: Announce this feature.
> >> * doc/make.texi (Functions for Conditionals): Document 'compare'.
> >> * src/function.c (func_compare): Create the 'compare' built-in function.
> >> * tests/scripts/functions/compare: Test the 'compare' built-in function.
> >> ---
> >>
> >> This is a cleaned-up and documented version of a proposal submitted a
> >> year ago. The interface was conceived by Edward Welbourne and myself.
> >> Personally, I would not introduce mathematical operators to make, but
> >> given that numbers are a thing and they do pop up in variables, a
> >> comparison function makes sense to me.
> >>
> >> Thanks for considering!
> >> - Jouke
> >
> >I would still be interested in seeing this patch series I sent two months
> ago considered. I am not in a rush: this is just a friendly reminder.
>
> I am interested in this series as well, although something more general
> might also be interesting, like a general version compare function like
> $(compare 1.6.1 1.6.100), and that also take into account character-based
> versioning, like $(compare A10.88 B20.94).
>
> -Randall
>
>
>


RE: [PATCH 3/3] Introduce $(compare ...) for numerical comparison

2021-09-13 Thread Randall S. Becker
On September 13, 2021 2:40 PM, Jouke Witteveen wrote:
>On Fri, Jul 16, 2021 at 2:04 PM Jouke Witteveen  wrote:
>>
>> Numbers can come from $(words ...), automatic variables such as
>> $(MAKELEVEL), from environment variables, or from shell output such as
>> through $(shell expr ...).  The $(compare ...) function allows
>> conditional evaluation controlled by numerical variables.
>>
>> * NEWS: Announce this feature.
>> * doc/make.texi (Functions for Conditionals): Document 'compare'.
>> * src/function.c (func_compare): Create the 'compare' built-in function.
>> * tests/scripts/functions/compare: Test the 'compare' built-in function.
>> ---
>>
>> This is a cleaned-up and documented version of a proposal submitted a
>> year ago. The interface was conceived by Edward Welbourne and myself.
>> Personally, I would not introduce mathematical operators to make, but
>> given that numbers are a thing and they do pop up in variables, a
>> comparison function makes sense to me.
>>
>> Thanks for considering!
>> - Jouke
>
>I would still be interested in seeing this patch series I sent two months ago 
>considered. I am not in a rush: this is just a friendly reminder.

I am interested in this series as well, although something more general might 
also be interesting, like a general version compare function like $(compare 
1.6.1 1.6.100), and that also take into account character-based versioning, 
like $(compare A10.88 B20.94).

-Randall




Re: [PATCH 3/3] Introduce $(compare ...) for numerical comparison

2021-09-13 Thread Jouke Witteveen
On Fri, Jul 16, 2021 at 2:04 PM Jouke Witteveen  wrote:
>
> Numbers can come from $(words ...), automatic variables such as
> $(MAKELEVEL), from environment variables, or from shell output such as
> through $(shell expr ...).  The $(compare ...) function allows
> conditional evaluation controlled by numerical variables.
>
> * NEWS: Announce this feature.
> * doc/make.texi (Functions for Conditionals): Document 'compare'.
> * src/function.c (func_compare): Create the 'compare' built-in function.
> * tests/scripts/functions/compare: Test the 'compare' built-in function.
> ---
>
> This is a cleaned-up and documented version of a proposal submitted a
> year ago. The interface was conceived by Edward Welbourne and myself.
> Personally, I would not introduce mathematical operators to make, but
> given that numbers are a thing and they do pop up in variables, a
> comparison function makes sense to me.
>
> Thanks for considering!
> - Jouke

I would still be interested in seeing this patch series I sent two
months ago considered. I am not in a rush: this is just a friendly
reminder.

Regards,
- Jouke



[PATCH 3/3] Introduce $(compare ...) for numerical comparison

2021-07-16 Thread Jouke Witteveen
Numbers can come from $(words ...), automatic variables such as
$(MAKELEVEL), from environment variables, or from shell output such as
through $(shell expr ...).  The $(compare ...) function allows
conditional evaluation controlled by numerical variables.

* NEWS: Announce this feature.
* doc/make.texi (Functions for Conditionals): Document 'compare'.
* src/function.c (func_compare): Create the 'compare' built-in function.
* tests/scripts/functions/compare: Test the 'compare' built-in function.
---

This is a cleaned-up and documented version of a proposal submitted a
year ago. The interface was conceived by Edward Welbourne and myself.
Personally, I would not introduce mathematical operators to make, but
given that numbers are a thing and they do pop up in variables, a
comparison function makes sense to me.

Thanks for considering!
- Jouke

 NEWS|  4 +++
 doc/make.texi   | 36 -
 src/function.c  | 46 ++
 tests/scripts/functions/compare | 57 +
 4 files changed, 142 insertions(+), 1 deletion(-)
 create mode 100644 tests/scripts/functions/compare

diff --git a/NEWS b/NEWS
index 5356260..6a3a744 100644
--- a/NEWS
+++ b/NEWS
@@ -40,6 +40,10 @@ 
https://sv.gnu.org/bugs/index.php?group=make_id=111_release_id=109
   user-defined function and they will not impact global variable assignments.
   Implementation provided by Jouke Witteveen 
 
+* New feature: The $(compare ...) function
+  This function allows conditional evaluation controlled by a numerical
+  comparison.
+
 * New debug option "print" will show the recipe to be run, even when silent
   mode is set.
 
diff --git a/doc/make.texi b/doc/make.texi
index 1ebf6ae..14a59f6 100644
--- a/doc/make.texi
+++ b/doc/make.texi
@@ -7654,7 +7654,7 @@ the file names to refer to an existing file or directory. 
 Use the
 @section Functions for Conditionals
 @findex if
 @cindex conditional expansion
-There are three functions that provide conditional expansion.  A key
+There are four functions that provide conditional expansion.  A key
 aspect of these functions is that not all of the arguments are
 expanded initially.  Only those arguments which need to be expanded,
 will be expanded.
@@ -7701,6 +7701,32 @@ empty string the processing stops and the result of the 
expansion is
 the empty string.  If all arguments expand to a non-empty string then
 the result of the expansion is the expansion of the last argument.
 
+@item $(compare 
@var{lhs},@var{rhs},@var{lt-part}[,@var{eq-part}[,@var{gt-part}]])
+@findex compare
+The @code{compare} function provides support for numerical comparison of
+integers.  This function has no counterpart among the GNU @code{make}
+makefile conditionals.
+
+The left-hand side, @var{lhs}, and right-hand side, @var{rhs}, are
+expanded and parsed as integral numbers in base 10.  Expansion of the
+remaining arguments is controlled by how the numerical left-hand side
+compares to the numerical right-hand side.
+
+If the left-hand side is strictly less than the right-hand side, the
+entire @code{compare} function evaluates to the expansion of the third
+argument, @var{lt-part}.  If both sides compare equal, then the fourth
+argument, @var{eq-part}, is expanded and becomes the result of the
+@code{compare} function.  If the left-hand side is strictly greater than
+the right-hand side, then the @code{compare} function evaluates to the
+expansion of the fifth argument, @var{gt-part}.
+
+In case of missing arguments, @var{gt-part} defaults to @var{eq-part},
+and @var{eq-part} defaults to the empty string.  Thus both
+@samp{$(compare 9,7,hello)} and @samp{$(compare 9,7,hello,world,)}
+evaluate to the empty string, while @samp{$(compare 9,7,hello,world)}
+(notice the absence of a comma after @code{world}) evaluates to
+@samp{world}.
+
 @end table
 
 @node Let Function, Foreach Function, Conditional Functions, Functions
@@ -12523,6 +12549,14 @@ all expansions result in a non-empty string, 
substitute the expansion
 of the last @var{condition}.@*
 @xref{Conditional Functions, ,Functions for Conditionals}.
 
+@item $(compare 
@var{lhs},@var{rhs},@var{lt-part}[,@var{eq-part}[,@var{gt-part}]])
+Compare @var{lhs} and @var{rhs} numerically; substitute the expansion of
+@var{lt-part}, @var{eq-part}, or @var{gt-part} depending on whether the
+left-hand side is less-than, equal-to, or greater-than the right-hand
+side, respectively.  If @var{gt-part} is left out, it defaults to
+@var{eq-part}.@*
+@xref{Conditional Functions, ,Functions for Conditionals}.
+
 @item $(call @var{var},@var{param},@dots{})
 Evaluate the variable @var{var} replacing any references to @code{$(1)},
 @code{$(2)} with the first, second, etc.@: @var{param} values.@*
diff --git a/src/function.c b/src/function.c
index 964169a..587786a 100644
--- a/src/function.c
+++ b/src/function.c
@@ -1272,6 +1272,51 @@ func_sort (char *o, char **argv, const char *funcname