Skip to content

Commit

Permalink
pal: Handle a missing copysign() function
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
timj committed Jun 21, 2012
1 parent 83382f1 commit f10ee43
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 3 deletions.
2 changes: 1 addition & 1 deletion component.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<!-- component.xml. Generated from component.xml.in by configure. -->

<component id="pal" support="S">
<version>0.1.1</version>
<version>0.1.2</version>
<path>libraries/pal</path>
<description>Position Astronomy Library</description>
<abstract><p>
Expand Down
4 changes: 3 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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, [email protected])
AC_INIT(pal, 0.1.2, [email protected])

dnl Require autoconf-2.50 at least
AC_PREREQ(2.50)
Expand All @@ -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])
Expand Down
43 changes: 43 additions & 0 deletions palDfltin.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -82,6 +89,10 @@
*-
*/

#if HAVE_CONFIG_H
#include <config.h>
#endif

/* Shenanigans for isblank() which is C99 only */
#define _POSIX_C_SOURCE 200112L
#define _ISOC99_SOURCE
Expand All @@ -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
Expand All @@ -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 */
Expand Down Expand Up @@ -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 ) {
Expand All @@ -162,6 +204,7 @@ void palDfltin( const char * string, int *nstrt,
} else {
*jflag = 0;
}
#endif
}

/* Sort out the position for the next index */
Expand Down
15 changes: 14 additions & 1 deletion palPertue.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -178,6 +180,10 @@
*-
*/

#if HAVE_CONFIG_H
#include <config.h>
#endif

#include <math.h>

#include "pal.h"
Expand All @@ -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 */
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions palmac.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit f10ee43

Please sign in to comment.