- Don't define llabs(). This breaks if llabs() is already a macro, which
is allowed by the C standard/POSIX. llabs() was introduced in C99, so
I think we can safely assume it is present on all interesting systems.
- Cast the parameters to fabs() to the floating point type. Clang has
introduced some interesting warnings that trigger if the arguments to
fabs*() are not the right type.
I often build the code with -Wmissing-prototypes to ensure that we don't
accidentically pollute the symbol namespace. If we want to provide a
symbol such as isopenlibm(), make sure we also declare it in
<openlibm_math.h>.
This is a bit more consistent with the naming of the other header files
(openlibm_complex.h and openlibm_fenv.h). Re-add an openlibm.h header
that includes all of the public headers as a shorthand.
Fix up all of the source files to include <openlibm_math.h> instead of
<openlibm.h>. While there, fix ordering of the includes.
While there, also modify the install target. We should make sure to
install all openlibm*.h headers. There is still some work to be done:
openlibm_fenv_*.h still depends on some additional bits. I'd propose
that we eventually create an include/openlibm_cdefs.h that contains all
of the macros we need.
Unlike the __weak_reference() macro, __strong_reference() does type
checking. It can only create the reference if the type of the source and
the destination function match exactly.
Even if double == long double in practice, they remain unequal at the
language level.
I guess the idea would be to eventually also install all of the
openlibm*.h headers, instead of just openlibm.h. Make openlibm_fenv.h
suitable for this purpose by moving all of the $ARCH/fenv.h headers next
to it.
We actually need this change to make OPENLIBM_USE_HOST_FENV_H work.
Right now it's still broken, because the "#include <fenv.h>" performed
by openlibm_fenv.h still pulls in $ARCH/fenv.h as $ARCH/ is added to the
compiler include path.
OpenLibm uses the __weak_reference() macro for platforms where double
and long double use the same layout. That way functions only need to be
provided by the library once. The point is, in this specific case we
want to use strong references; not weak references.
Strong references can be used to give a symbol a second name. If you
look at the resulting object file, you will have two symbols with the
same offset and size. Weak references are different, in the sense that
they are marked in such a way that they act as fallbacks. They are only
used if an explicitly matching symbol is missing.
The global signgam variable is only part of the X/Open System
Interfaces. It is not part of the POSIX base definitions nor the C
standard.
I'd rather have it disabled for my specific use-case, so introduce a new
compilation flag that we can use to disable it.
I grepped through the FreeBSD source tree and for me, it seems to be
totally unclear why these two specific functions are weak references.
Such a construct is commonly used by FreeBSD's threading library
(libthr) to override certain functions, but I can't find any traces of
that.
Just use the function name directly. This fixes a compiler warning as
well (-Wmissing-prototypes).
Put external headers before internal ones. While there, replace a lot of
occurences of "openlibm.h" with <openlibm.h>. It should be thought of as
an external header, as it is installed along with the library.
While there, make CMPLX() work with Clang by using compound literals.
Now that cimag*() uses __imag__, we can also just inline the unions.
There is no need for the separate types anymore.
Also just define CMPLX() unconditionally now, as we no longer pull in
the host's <complex.h>.
OpenLibm has an implementation of fenv.h internally. This may be
problematic in case you want it to build against the host system's
implementation, as it would require you to somehow take the fenv.h file
out of the compiler search path.
Simply use a different naming scheme, similar to openlibm.h and
openlibm_complex.h. If we want to build against the host's fenv.h, we
can simply add an '#include <fenv.h>' from within this header.
I am currently working on building openlibm against stock copies of
<math.h>, instead of the openlibm.h header. It seems that a C compliant
<math.h> header can be used as a drop-in replacement for openlibm.h,
with the exception that it lacks cpack*().
In FreeBSD SVN r275819 I patched up the math library by replacing
cpack*() by CMPLX*(). That way many functions become less tied to the
intrinsics of the math library. Make the same change to openlibm.
We already provide lgammaf_r() and lgamma_r(). It's not hard to also add
lgammal_r(), for consistency.
I am currently working on porting openlibm to an environment where
global state, and thus signgam, is not available. By adding lgammal_r(),
I can trivially disable support for signgam by just patching up
src/e_lgamma{f,,l}.c. That way there is no need to patch up the actual
algorithms.
When building openlibm with Clang, I seem to get a lot of warnings in
ld80/ related to some prototypes for long double functions that are
missing. This seems to be because we don't define _DECLARE_C99_LDBL_MATH
anywhere.
It seems that this definition only existed on FreeBSD, as certain C99
math functions were not present yet. The prototypes were simply there as
placeholders. This flag has been removed upstream (FreeBSD SVN r236148).
Letting tgammal() modify signgam has two disadvantages:
- It breaks valid code that assumes that the value of signgam is not
clobbered by calls to tgammal().
- It makes this function depend on the presence of signgam. signgam is
an X/Open System Interface. It is not part of the C standard.