From f10ee434a3986ade1d579f5e5b92bc5a27cdefce Mon Sep 17 00:00:00 2001 From: Tim Jenness Date: Thu, 21 Jun 2012 16:20:05 -0700 Subject: [PATCH] pal: Handle a missing copysign() function Some older compilers are missing copysign() and we can't simply replace it with the dsign() macro from SOFA. The main issue is that strtod() can return -0.0 and copysign can correctly note that. When copysign() is missing we have to go back to scanning the string for minus signs. --- component.xml | 2 +- configure.ac | 4 +++- palDfltin.c | 43 +++++++++++++++++++++++++++++++++++++++++++ palPertue.c | 15 ++++++++++++++- palmac.h | 4 ++++ 5 files changed, 65 insertions(+), 3 deletions(-) diff --git a/component.xml b/component.xml index f90c7cf..4997e0e 100644 --- a/component.xml +++ b/component.xml @@ -3,7 +3,7 @@ - 0.1.1 + 0.1.2 libraries/pal Position Astronomy Library

diff --git a/configure.ac b/configure.ac index 49aa128..b70f85f 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script AC_REVISION($Revision: 27534 $) dnl Initialisation: package name and version number -AC_INIT(pal, 0.1.1, stardev@jiscmail.ac.uk) +AC_INIT(pal, 0.1.2, stardev@jiscmail.ac.uk) dnl Require autoconf-2.50 at least AC_PREREQ(2.50) @@ -23,6 +23,8 @@ AC_PROG_LIBTOOL # If --with-pic=no is set we should honour that. AM_CONDITIONAL(NOPIC, test x$pic_mode = xno) +dnl copysign is a c99 feature +AC_CHECK_FUNCS(copysign) dnl Declare the build and use dependencies for this package STAR_DECLARE_DEPENDENCIES(build, [sofa starutil]) diff --git a/palDfltin.c b/palDfltin.c index c33736d..a232f11 100644 --- a/palDfltin.c +++ b/palDfltin.c @@ -52,9 +52,16 @@ * - Unlike slaDfltin a standalone "E" will return status 1 (could not find * a number) rather than 2 (bad number). +* Implementation Status: +* - The code is more robust if the C99 copysign() function is available. +* This can recognize the -0.0 values returned by strtod. If copysign() is +* missing we try to scan the string looking for minus signs. + * History: * 2012-03-08 (TIMJ): * Initial version based on strtod +* 2012-06-21 (TIMJ): +* Provide a backup for missing copysign. * {enter_further_changes_here} * Copyright: @@ -82,6 +89,10 @@ *- */ +#if HAVE_CONFIG_H +#include +#endif + /* Shenanigans for isblank() which is C99 only */ #define _POSIX_C_SOURCE 200112L #define _ISOC99_SOURCE @@ -93,6 +104,12 @@ #include "pal.h" +#if HAVE_COPYSIGN +# define SCAN_FOR_MINUS 0 +#else +# define SCAN_FOR_MINUS 1 +#endif + /* We prefer to use the starutil package */ #if NOSTARUTIL #else @@ -112,6 +129,28 @@ void palDfltin( const char * string, int *nstrt, D or d in the string. */ char tempbuf[256]; +#if SCAN_FOR_MINUS + int dreslt_sign = 1; + int ipos = *nstrt; + const char * cctemp = NULL; + + /* Scan the string looking for a minus sign. Then update the + start position for the subsequent copy iff we find a '-'. + Note that commas are a special delimiter so we stop looking for a + minus if we find one or if we find a digit. */ + cctemp = &(string[ipos-1]); + while (!isdigit(*cctemp) && (*cctemp != ',') && (*cctemp != '\0')) { + printf("Looking at char %d '%c'\n",ipos-1, *cctemp); + if (*cctemp == '-') { + *nstrt = ipos; + dreslt_sign = -1; + break; + } + ipos++; + cctemp++; + } +#endif + /* Correct for SLA use of fortran convention */ #if NOSTARUTIL /* Use standard C interface */ @@ -149,6 +188,9 @@ void palDfltin( const char * string, int *nstrt, } else if ( errno == ERANGE ) { *jflag = 2; } else { +#if SCAN_FOR_MINUS + *jflag = (dreslt_sign < 0 ? -1 : 0); +#else if ( retval < 0.0 ) { *jflag = -1; } else if ( retval == 0.0 ) { @@ -162,6 +204,7 @@ void palDfltin( const char * string, int *nstrt, } else { *jflag = 0; } +#endif } /* Sort out the position for the next index */ diff --git a/palPertue.c b/palPertue.c index bc3272a..730e9fd 100644 --- a/palPertue.c +++ b/palPertue.c @@ -151,6 +151,8 @@ * History: * 2012-03-12 (TIMJ): * Initial version direct conversion of SLA/F. +* 2012-06-21 (TIMJ): +* Support a lack of copysign() function. * {enter_further_changes_here} * Copyright: @@ -178,6 +180,10 @@ *- */ +#if HAVE_CONFIG_H +#include +#endif + #include #include "pal.h" @@ -188,6 +194,13 @@ #define MAX(x, y) (((x) > (y)) ? (x) : (y)) #define MIN(x, y) (((x) < (y)) ? (x) : (y)) +/* copysign is C99 */ +#if HAVE_COPYSIGN +# define COPYSIGN copysign +#else +# define COPYSIGN(a,b) DSIGN(a,b) +#endif + void palPertue( double date, double u[13], int *jstat ) { /* Distance from EMB at which Earth and Moon are treated separately */ @@ -344,7 +357,7 @@ void palPertue( double date, double u[13], int *jstat ) { if (fabs(TSPAN) > 36525.0) *jstat=101; /* Time direction: +1 for forwards, -1 for backwards. */ - FB = copysign(1.0,TSPAN); + FB = COPYSIGN(1.0,TSPAN); /* Initialize relative epoch for start of current timestep. */ RTN = 0.0; diff --git a/palmac.h b/palmac.h index 2603b85..be2f317 100644 --- a/palmac.h +++ b/palmac.h @@ -109,5 +109,9 @@ static const double PAL__GCON = 0.01720209895; /* DMAX(A,B) - return maximum value - evaluates arguments multiple times */ #define DMAX(A,B) (A > B ? A : B ) +/* We actually prefer to use C99 copysign() but we define this here as a backup + but it will not detect -0.0 so is not useful for palDfltin. */ +/* DSIGN(A,B) - magnitude of A with sign of B (double) */ +#define DSIGN(A,B) ((B)<0.0?-fabs(A):fabs(A)) #endif