Re: Minix

2020-07-23 Thread Bruno Haible
Paul Eggert wrote:
> Minix is moribund (its last release was 2014) and is no longer a significant 
> porting target.

Indeed. There was a conference around Minix in 2016 [1], but development
apparently stopped more than 1½ years ago. [2][3]

Bruno

[1] http://www.minix3.org/conference/2016/program.html
[2] https://git.minix3.org/index.cgi?p=minix.git
[3] https://github.com/Stichting-MINIX-Research-Foundation/minix/




Re: Module with preprocessor utilities

2020-07-23 Thread Bruno Haible
[Adding back bug-gnulib in CC]

Marc Nieper-Wißkirchen wrote:
> > Marc Nieper-Wißkirchen wrote:
> > > For example, do we want to encourage the writing of
> > > sophisticated macros like the TRACE macros in chapter 16 of (the IMHO
> > > opinionated) book Modern C ([1]).
> >
> > This TRACE macro is an interesting academic example. I say "academic",
> > because who wants a trace statement that outputs only numbers, no string
> > arguments? And once you allow string arguments, you notice that you need
> > a varargs function, not a macro.
> 
> Unless you want to use _Generic of C11, you probably need a varargs function.

Do you have an idea which compilers support _Generic and which don't?

> > > [1] https://gforge.inria.fr/frs/download.php/latestfile/5298/ModernC.pdf
> >
> > Will I learn something by reading this book, or will it spoil me? :-)
> 
> There's possibly something to learn but I don't think that one will be
> spoiled. :) A number of things look interesting but also quite
> Idiosyncratic to me. Due to these things, I wouldn't suggest the book
> to a beginner who wants to learn C, though.
> 
> For example, the author suggests to use a prototype like
> 
> void foo (X x [static 1]);
> 
> to denote that the argument "x" is a non-null pointer to a value of
> type "X". While this seems to be the intent of "[static 1]" in the C
> standard, it doesn't generalize well when "X" does not denote a
> complete type. In that case, one has to resort to
> 
> void foo (X *x);
> 
> as pointers to incomplete types are fine.

Also, if that's the intent of the syntax, it has been overlooked by the
GCC developers. See:

 decl.c 
#include 

extern void foo1 (double x [static 1]);
extern void foo2 (double x []) __attribute__ ((__nonnull__(1)));

int bar ()
{
  foo1 (NULL);
  foo2 (NULL);
  return 1;
}
=
$ gcc -Wall -S decl.c
decl.c: In function 'bar':
decl.c:9:3: warning: null argument where non-null required (argument 1) 
[-Wnonnull]
9 |   foo2 (NULL);
  |   ^~~~

(This is with gcc 10.1.0.)

clang, OTOH, produces warnings for both foo1 and foo2.

But I won't spend time to report a GCC bug on this, because - as you said -
without the ability to declare a pointer to an incomplete type or a 'void *'
as non-null, this language feature is worthless.

Bruno




Re: [PATCH] fchmodat: Use /proc on Cygwin

2020-07-23 Thread Ken Brown

Hi Bruno,

On 7/23/2020 6:36 PM, Bruno Haible wrote:

I tested it by running
   rm -rf ../testdir
   ./gnulib-tool --create-testdir --dir=../testdir --single-configure lchmod 
fchmodat
then transporting that testdir to my Cygwin machine, and building there
(./configure && make && make check).


Thanks!

Ken



Re: libgmp: link to the correct shared library

2020-07-23 Thread Bruno Haible
Hi Paul,

> > Also, adding -Wl,-rpath=/PREFIX64/lib to LDFLAGS will have ill consequences
> > when the package contains shared libraries and uses libtool to create them. 
> > See
> > .
> 
> That's OK too, since Emacs and coreutils don't use libtool to create packages.

GNU poke is likely to use GMP soon. When it does that, it will of course use
the module 'libgmp'. And this package happens to use libtool.

> Coreutils 'expr' already  links to GMP anyway. :-)

:-)

> > Do you think there is something to add to the documentation
> > https://www.gnu.org/software/gnulib/manual/html_node/Searching-for-Libraries.html
> >  ?
> 
> I am hoping that I do not have to read that documentation; I just want to 
> keep 
> building Coreutils the way it's been built for quite some time. ... I merely 
> want to be able to use GMP without worrying about libtool.

You can. For uses of system-wide installed GMP, nothing changes. For users who
built GMP on their own, there is the configure option --with-libgmp-prefix. If
there is a problem with it, you can redirect the reports to bug-gnulib or me.

You probably don't want to deal with libtool because of its deep platform
dependencies? 'havelib' also has some platform dependencies, but
  - much less of them,
  - they are contained in a single file, 'build-aux/config.rpath',
  - this file does not need updates more frequently than once in 5 years.

Bruno




Re: libgmp: link to the correct shared library

2020-07-23 Thread Paul Eggert

On 7/23/20 3:30 PM, Bruno Haible wrote:


If, say, we change the 'factor' program in GNU coreutils
to use GMP, so that it can factor integers with more than 20 digits, anyone who
wants to use their own installed GMP would get programs (from 'expr' to 'mkdir')
that all spend time, during program startup, to look up their libraries in
/PREFIX64/lib.
This may not be perfect, but it's good enough for many applications. Coreutils 
has been doing it this way since Coreutils 7.0 (2008) and it doesn't appear to 
have been a significant problem in practice. (Plus, Coreutils 'expr' already 
links to GMP anyway. :-)



Also, adding -Wl,-rpath=/PREFIX64/lib to LDFLAGS will have ill consequences
when the package contains shared libraries and uses libtool to create them. See
.


That's OK too, since Emacs and coreutils don't use libtool to create packages.


Do you think there is something to add to the documentation
https://www.gnu.org/software/gnulib/manual/html_node/Searching-for-Libraries.html
 ?


I am hoping that I do not have to read that documentation; I just want to keep 
building Coreutils the way it's been built for quite some time. I introduced 
libgmp in order make it easier to use GMP in other apps like Emacs; I didn't 
want the module to complicate configuration in coreutils or in other packages 
that don't need the complication. Emacs in particular prefers to use pkg-config 
and PKG_CHECK_MODULES to configure libraries, and I don't want to have to worry 
about how that interacts with libtool.


I'm not saying I'm against having a libtool-aware GMP module in Gnulib; I merely 
want to be able to use GMP without worrying about libtool.




Re: [PATCH] fchmodat: Use /proc on Cygwin

2020-07-23 Thread Bruno Haible
Hi Ken,

> > 2020-07-23  Bruno Haible  
> > 
> > lchmod: Use /proc on Cygwin.
> > * lib/lchmod.c (lchmod): Use /proc on Cygwin.
> > 
> > diff --git a/lib/lchmod.c b/lib/lchmod.c
> > index e113211..77a0060 100644
> > --- a/lib/lchmod.c
> > +++ b/lib/lchmod.c
> > @@ -76,7 +76,7 @@ lchmod (char const *file, mode_t mode)
> > return -1;
> >   }
> >   
> > -# if defined __linux__ || defined __ANDROID__
> > +# if defined __linux__ || defined __ANDROID__ || defined __CYGWIN__
> > static char const fmt[] = "/proc/self/fd/%d";
> > char buf[sizeof fmt - sizeof "%d" + INT_BUFSIZE_BOUND (int)];
> > sprintf (buf, fmt, fd);
> 
> Yes, that should work.  Can you tell me how to test it?  I've never had 
> occasion 
> to use Gnulib except indirectly

I tested it by running
  rm -rf ../testdir
  ./gnulib-tool --create-testdir --dir=../testdir --single-configure lchmod 
fchmodat
then transporting that testdir to my Cygwin machine, and building there
(./configure && make && make check).

There is a unit test (test-lchmod.c); I assume that it exercises the main case.

Of course I did so before pushing my change.

Bruno




Re: libgmp: link to the correct shared library

2020-07-23 Thread Bruno Haible
Hi Paul,

> > This test fails when I build this gnulib module in my usual way:
> >./configure --prefix=/PREFIX64 \
> >CPPFLAGS="-I/PREFIX64/include -Wall" \
> >LDFLAGS="-L/PREFIX64/lib"
> 
> I don't see why this should be expected to work. Instead, you can tell 
> 'configure' to pass -rpath to the linker, so that the executable it produces 
> runs with the correct libraries. Something like this, say:
> 
>  ./configure --prefix=/PREFIX64 \
> CPPFLAGS="-I/PREFIX64/include -Wall" \
> LDFLAGS="-L/PREFIX64/lib -Wl,-rpath=/PREFIX64/lib"
> 
> This is a common issue when using dynamically-linked libraries in nonstandard 
> locations, and the longstanding way to address the issue is to use -rpath.

Yes, using rpath in the particular link command is the solution, and this is
what the 'havelib' module does.

But adding -Wl,-rpath=/PREFIX64/lib to LDFLAGS is not the solution, because it
affects all programs. If, say, we change the 'factor' program in GNU coreutils
to use GMP, so that it can factor integers with more than 20 digits, anyone who
wants to use their own installed GMP would get programs (from 'expr' to 'mkdir')
that all spend time, during program startup, to look up their libraries in
/PREFIX64/lib. This is not welcome.

Also, adding -Wl,-rpath=/PREFIX64/lib to LDFLAGS will have ill consequences
when the package contains shared libraries and uses libtool to create them. See
.

> > * modules/libgmp (Depends-on): Add havelib.
> 
> This approach requires all libgmp-using packages to also use havelib and do 
> all 
> the libtool stuff. Emacs, coreutils etc. build without libtool and I would 
> rather not introduce a dependency on libtool to them.

This is a misunderstanding. 'havelib' does not depend on libtool. *Creating*
a library is what requires libtool. *Linking* with a library does not require
libtool.

Do you think there is something to add to the documentation
https://www.gnu.org/software/gnulib/manual/html_node/Searching-for-Libraries.html
 ?

Bruno




Re: [PATCH] fchmodat: Use /proc on Cygwin

2020-07-23 Thread Ken Brown

On 7/23/2020 5:16 PM, Bruno Haible wrote:

Ken Brown wrote:

diff --git a/lib/fchmodat.c b/lib/fchmodat.c
index 895016860..eee0a1c56 100644
--- a/lib/fchmodat.c
+++ b/lib/fchmodat.c
@@ -98,7 +98,7 @@ fchmodat (int dir, char const *file, mode_t mode, int flags)
return -1;
  }
  
-#   if defined __linux__ || defined __ANDROID__

+#   if defined __linux__ || defined __ANDROID__ || defined __CYGWIN__
static char const fmt[] = "/proc/self/fd/%d";
char buf[sizeof fmt - sizeof "%d" + INT_BUFSIZE_BOUND (int)];
sprintf (buf, fmt, fd);



So, chmod ("/proc/self/fd/n") works on Cygwin like on Linux. Then, we can make
the same change also in lchmod.c.


2020-07-23  Bruno Haible  

lchmod: Use /proc on Cygwin.
* lib/lchmod.c (lchmod): Use /proc on Cygwin.

diff --git a/lib/lchmod.c b/lib/lchmod.c
index e113211..77a0060 100644
--- a/lib/lchmod.c
+++ b/lib/lchmod.c
@@ -76,7 +76,7 @@ lchmod (char const *file, mode_t mode)
return -1;
  }
  
-# if defined __linux__ || defined __ANDROID__

+# if defined __linux__ || defined __ANDROID__ || defined __CYGWIN__
static char const fmt[] = "/proc/self/fd/%d";
char buf[sizeof fmt - sizeof "%d" + INT_BUFSIZE_BOUND (int)];
sprintf (buf, fmt, fd);


Yes, that should work.  Can you tell me how to test it?  I've never had occasion 
to use Gnulib except indirectly, when building a project like Emacs that uses 
it.  But the Cygwin build of Emacs doesn't seem to use lchmod.


Thanks.



Optimize three-valued comparison between integers

2020-07-23 Thread Bruno Haible
A comment in Luca Saiu 'jitter' project [1] brought my attention to 3-valued
comparison and the book "Hacker's Delight".

===
int sign1 (long n1, long n2)
{
  return (n1 > n2 ? 1 : n1 < n2 ? -1 : 0);
}

int sign2 (long n1, long n2)
{
  return (n1 < n2 ? -1 : n1 > n2);
}

int sign3 (long n1, long n2)
{
  return (n1 > n2) - (n1 < n2);
}
===

Which of these, do you think, generates better code? The important fact,
nowadays, is that conditional jumps cause the CPU to stall when it has
mispredicted the jump. So, 1 or 2 more or less ALU instructions are
irrelevant, but conditional jumps are not.

You find conditional jumps in code (x86) produced by GCC versions

sign1: 4.1.2 4.2.4 4.3.6 4.4.7 4.5.4 4.6.4 4.7.3 4.8.5 4.9.4 5.5.0 7.5.0 8.4.0 
9.3.0 10.1.0
sign2: 4.1.2 4.2.4 4.3.6 4.4.7 7.5.0 8.4.0 9.3.0
sign3: 

So, the third variant comes out best.

Maybe in 10 years, GCC and clang will recognize the patterns from sign1 and
sign2, but we are not there yet.

[1] http://ageinghacker.net/projects/jitter/
[2] 
https://books.google.de/books?id=VicPJYM0I5QC=frontcover=%22hacker%27s+delight%22=en=X=2ahUKEwjN7_LSouHqAhVJKewKHREQBZ8Q6AEwAXoECAMQAg#v=onepage=false


2020-07-23  Bruno Haible  

Optimize three-valued comparison between integers.
(a > b ? 1 : a < b ? -1 : 0) is the same as (a > b) - (a < b).
* m4/gnulib-common.m4 (gl_COMMON): Define _GL_CMP.
* lib/c-strcasecmp.c (c_strcasecmp): Use _GL_CMP.
* lib/c-strncasecmp.c (c_strncasecmp): Likewise.
* lib/dfa.c (compare): Likewise.
* lib/fts.c (fts_compare_ino): Likewise.
* lib/mbmemcasecmp.c (mbmemcasecmp): Likewise.
* lib/mbscasecmp.c (mbscasecmp): Likewise.
* lib/mbsncasecmp.c (mbsncasecmp): Likewise.
* lib/memcasecmp.c (memcasecmp): Likewise.
* lib/memcmp2.c (memcmp2): Likewise.
* lib/savedir.c (direntry_cmp_inode): Likewise.
* lib/strcasecmp.c (strcasecmp): Likewise.
* lib/strncasecmp.c (strncasecmp): Likewise.
* lib/unistr/u-cmp2.h (FUNC): Likewise.

diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4
index f4ba5e3..ba42391 100644
--- a/m4/gnulib-common.m4
+++ b/m4/gnulib-common.m4
@@ -1,4 +1,4 @@
-# gnulib-common.m4 serial 50
+# gnulib-common.m4 serial 51
 dnl Copyright (C) 2007-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -293,6 +293,20 @@ AC_DEFUN([gl_COMMON_BODY], [
errno.  */
 #define _GL_ASYNC_SAFE
 ])
+  AH_VERBATIM([micro_optimizations],
+[/* _GL_CMP (n1, n2) performs a three-valued comparison on n1 vs. n2.
+   It returns
+ 1  if n1 > n2
+ 0  if n1 == n2
+ -1 if n1 < n2
+   The naïve code   (n1 > n2 ? 1 : n1 < n2 ? -1 : 0)  produces a conditional
+   jump with nearly all GCC versions up to GCC 10.
+   This variant (n1 < n2 ? -1 : n1 > n2)  produces a conditional with many
+   GCC versions up to GCC 9.
+   The better code  (n1 > n2) - (n1 < n2)  from Hacker's Delight § 2-9
+   avoids conditional jumps in all GCC versions >= 3.4.  */
+#define _GL_CMP(n1, n2) ((n1) > (n2)) - ((n1) < (n2))
+])
   dnl Hint which direction to take regarding cross-compilation guesses:
   dnl When a user installs a program on a platform they are not intimately
   dnl familiar with, --enable-cross-guesses=conservative is the appropriate

diff --git a/lib/c-strcasecmp.c b/lib/c-strcasecmp.c
index 3ac650f..1de04b7 100644
--- a/lib/c-strcasecmp.c
+++ b/lib/c-strcasecmp.c
@@ -52,5 +52,5 @@ c_strcasecmp (const char *s1, const char *s2)
 /* On machines where 'char' and 'int' are types of the same size, the
difference of two 'unsigned char' values - including the sign bit -
doesn't fit in an 'int'.  */
-return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0);
+return _GL_CMP (c1, c2);
 }
diff --git a/lib/c-strncasecmp.c b/lib/c-strncasecmp.c
index a4e67d1..1782e54 100644
--- a/lib/c-strncasecmp.c
+++ b/lib/c-strncasecmp.c
@@ -52,5 +52,5 @@ c_strncasecmp (const char *s1, const char *s2, size_t n)
 /* On machines where 'char' and 'int' are types of the same size, the
difference of two 'unsigned char' values - including the sign bit -
doesn't fit in an 'int'.  */
-return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0);
+return _GL_CMP (c1, c2);
 }
diff --git a/lib/dfa.c b/lib/dfa.c
index dee7be8..1d2d404 100644
--- a/lib/dfa.c
+++ b/lib/dfa.c
@@ -2466,7 +2466,7 @@ static int
 compare (const void *a, const void *b)
 {
   position const *p = a, *q = b;
-  return p->index < q->index ? -1 : p->index > q->index;
+  return _GL_CMP (p->index, q->index);
 }
 
 static void
diff --git a/lib/fts.c b/lib/fts.c
index 5e357be..a34092c 100644
--- a/lib/fts.c
+++ b/lib/fts.c
@@ -1190,8 +1190,7 @@ fts_children (register FTS *sp, int instr)
 static int
 fts_compare_ino (struct _ftsent const **a, struct _ftsent const **b)
 {
-  

Re: libgmp: link to the correct shared library

2020-07-23 Thread Paul Eggert

On 7/12/20 2:48 PM, Bruno Haible wrote:


This test fails when I build this gnulib module in my usual way:
   ./configure --prefix=/PREFIX64 \
   CPPFLAGS="-I/PREFIX64/include -Wall" \
   LDFLAGS="-L/PREFIX64/lib"


I don't see why this should be expected to work. Instead, you can tell 
'configure' to pass -rpath to the linker, so that the executable it produces 
runs with the correct libraries. Something like this, say:


./configure --prefix=/PREFIX64 \
   CPPFLAGS="-I/PREFIX64/include -Wall" \
   LDFLAGS="-L/PREFIX64/lib -Wl,-rpath=/PREFIX64/lib"

This is a common issue when using dynamically-linked libraries in nonstandard 
locations, and the longstanding way to address the issue is to use -rpath.



* modules/libgmp (Depends-on): Add havelib.


This approach requires all libgmp-using packages to also use havelib and do all 
the libtool stuff. Emacs, coreutils etc. build without libtool and I would 
rather not introduce a dependency on libtool to them.




Re: [PATCH] fchmodat: Use /proc on Cygwin

2020-07-23 Thread Bruno Haible
Ken Brown wrote:
> diff --git a/lib/fchmodat.c b/lib/fchmodat.c
> index 895016860..eee0a1c56 100644
> --- a/lib/fchmodat.c
> +++ b/lib/fchmodat.c
> @@ -98,7 +98,7 @@ fchmodat (int dir, char const *file, mode_t mode, int flags)
>return -1;
>  }
>  
> -#   if defined __linux__ || defined __ANDROID__
> +#   if defined __linux__ || defined __ANDROID__ || defined __CYGWIN__
>static char const fmt[] = "/proc/self/fd/%d";
>char buf[sizeof fmt - sizeof "%d" + INT_BUFSIZE_BOUND (int)];
>sprintf (buf, fmt, fd);
> 

So, chmod ("/proc/self/fd/n") works on Cygwin like on Linux. Then, we can make
the same change also in lchmod.c.


2020-07-23  Bruno Haible  

lchmod: Use /proc on Cygwin.
* lib/lchmod.c (lchmod): Use /proc on Cygwin.

diff --git a/lib/lchmod.c b/lib/lchmod.c
index e113211..77a0060 100644
--- a/lib/lchmod.c
+++ b/lib/lchmod.c
@@ -76,7 +76,7 @@ lchmod (char const *file, mode_t mode)
   return -1;
 }
 
-# if defined __linux__ || defined __ANDROID__
+# if defined __linux__ || defined __ANDROID__ || defined __CYGWIN__
   static char const fmt[] = "/proc/self/fd/%d";
   char buf[sizeof fmt - sizeof "%d" + INT_BUFSIZE_BOUND (int)];
   sprintf (buf, fmt, fd);




Re: new module 'aligned-malloc'

2020-07-23 Thread Florian Weimer
* Paul Eggert:

> On 7/23/20 5:24 AM, Florian Weimer wrote:
>> Ah, 4096 is too small.
>>
>> For large allocations (above the mmap threshold), what happens in the
>> example is that the process VMA limit is eventually exhausted, at which
>> malloc falls back to sbrk, and then the algorithm succeeds.  I don't
>> think it's a good idea to trigger ENOMEM, it's certainly not
>> thread-safe.
>
> I'm not sure I see what ENOMEM has to do with it if the algorithm is
> succeeding.

During the mmap phase, the algorithm never achieves alignment.  Once
mmap fails with ENOMEM (likely because the number of VMAs would exceed
the per-process limit), malloc switch to the brk heap, where the
algorithm eventually produces an aligned allocation.  Only then the loop
terminates.

Thanks,
Florian




Re: [PATCH] fchmodat: Use /proc on Cygwin

2020-07-23 Thread Paul Eggert

Thanks, I installed that.



Re: new module 'aligned-malloc'

2020-07-23 Thread Paul Eggert

On 7/23/20 5:24 AM, Florian Weimer wrote:

Ah, 4096 is too small.

For large allocations (above the mmap threshold), what happens in the
example is that the process VMA limit is eventually exhausted, at which
malloc falls back to sbrk, and then the algorithm succeeds.  I don't
think it's a good idea to trigger ENOMEM, it's certainly not
thread-safe.


I'm not sure I see what ENOMEM has to do with it if the algorithm is succeeding.

Anyway, none of this matters since glibc has aligned_alloc already. All that 
matters is how well native MS-Windows performs since it's the only significant 
platform that lacks native support for aligned allocation. I don't use 
MS-Windows so I'm not the best person to comment on it; still, I'd be surprised 
if there's no way to support common uses of aligned_alloc on MS-Windows, such as 
the use that prompted this thread.




[PATCH] fchmodat: Use /proc on Cygwin

2020-07-23 Thread Ken Brown
* lib/fchmodat.c (fchmodat): Use /proc on Cygwin.
---
 ChangeLog  | 4 
 lib/fchmodat.c | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 8cac948ad..9d6051f76 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2020-07-23  Ken Brown  
+
+   * lib/fchmodat.c (fchmodat): Use /proc on Cygwin.
+
 2020-07-21  Bruno Haible  
 
aligned-malloc: Optionally use aligned_alloc.
diff --git a/lib/fchmodat.c b/lib/fchmodat.c
index 895016860..eee0a1c56 100644
--- a/lib/fchmodat.c
+++ b/lib/fchmodat.c
@@ -98,7 +98,7 @@ fchmodat (int dir, char const *file, mode_t mode, int flags)
   return -1;
 }
 
-#   if defined __linux__ || defined __ANDROID__
+#   if defined __linux__ || defined __ANDROID__ || defined __CYGWIN__
   static char const fmt[] = "/proc/self/fd/%d";
   char buf[sizeof fmt - sizeof "%d" + INT_BUFSIZE_BOUND (int)];
   sprintf (buf, fmt, fd);
-- 
2.27.0




Re: new module 'aligned-malloc'

2020-07-23 Thread Florian Weimer
* Paul Eggert:

> On 7/22/20 12:13 AM, Florian Weimer wrote:
>> I don't think it will work.  Try to get an allocation of 4096 bytes with
>> 4096 bytes alignment using glibc malloc this way.
>
> That's just a mental exercise since glibc malloc already has
> aligned_alloc, but I took the challenge anyway and found that it's
> eminently doable with glibc malloc alone. Run the attached program,
> and it should exit with status 0. At least, it works for me.

Ah, 4096 is too small.

For large allocations (above the mmap threshold), what happens in the
example is that the process VMA limit is eventually exhausted, at which
malloc falls back to sbrk, and then the algorithm succeeds.  I don't
think it's a good idea to trigger ENOMEM, it's certainly not
thread-safe.

Thanks,
Florian




Re: stack module

2020-07-23 Thread Marc Nieper-Wißkirchen
Hi Bruno,

> This is perfectly acceptable for Gnulib. It has debuggability and type safety.

Perfect. Then I will come up with a module in this form.

> You have precedent e.g. in lib/diffseq.h and lib/aligned-malloc.h.

Good to know; I hadn't taken a look at these sources yet.

> You can even omit the 'GL_' prefix from the macro names. The user can #undef
> the macros after including the file; therefore there is nearly no risk of
> collision with macros defined by other code.

Or the included file #undefs the macros as in lib/diffseq.h.

Speaking of prefixes: As macro names (and other names) starting with
"_GL_" are not officially allowed by ISO C, I think it makes sense to
think of a new convention for new sources (while old sources could
later be updated incrementally).

For example, one could use the prefix "GL__" (double underscore) for
(future) private identifiers.

Marc



Re: stack module

2020-07-23 Thread Bruno Haible
Hi Marc,

> The alternative with the same type safety would be a source file with
> stack code procedures meant for inclusion (without include guards).
> The source file would expect a preprocessor defines GL_STACK_NAME,
> GL_STACK_TYPE, and GL_STACK_EXTERN.
> 
> The file itself would contain code like the following:
> 
> #define _GL_STACK_PREFIX(name) _GL_CONCAT(GL_STACK_NAME, _GL_CONCAT(_, name))
> 
> typedef struct
> {
>   GL_STACK_TYPE *base;
>   size_t size;
>   size_t allocated;
> }
> GL_STACK_PREFIX(type);
> 
> GL_STACK_EXTERN GL_STACK_PREFIX(init) (GL_STACK_PREFIX(type) *stack)
> {
>   stack->base = NULL;
>   stack->size = 0;
>   stack->allocated = 0;
> }
> 
> ...
> 
> The advantage of this model is that it generalizes to other data
> structures, for which a sole (or at least simple) macro implementation
> is not possible.

This is perfectly acceptable for Gnulib. It has debuggability and type safety.

You have precedent e.g. in lib/diffseq.h and lib/aligned-malloc.h.

You can even omit the 'GL_' prefix from the macro names. The user can #undef
the macros after including the file; therefore there is nearly no risk of
collision with macros defined by other code.

Bruno