summaryrefslogtreecommitdiffstats
path: root/ast/skyaxis.c
diff options
context:
space:
mode:
authorWilliam Joye <wjoye@cfa.harvard.edu>2019-05-10 19:01:49 (GMT)
committerWilliam Joye <wjoye@cfa.harvard.edu>2019-05-10 19:01:49 (GMT)
commitbeb90b7d3f526440250bba67e5ab07bb7eb7bbc3 (patch)
tree8d0d428ac62291f834ea8927bfa82c115ff1689d /ast/skyaxis.c
parenta213dadabce2b2e02eca8376765fa425f01792f5 (diff)
downloadblt-beb90b7d3f526440250bba67e5ab07bb7eb7bbc3.zip
blt-beb90b7d3f526440250bba67e5ab07bb7eb7bbc3.tar.gz
blt-beb90b7d3f526440250bba67e5ab07bb7eb7bbc3.tar.bz2
upgrade ast 8.7.1
Diffstat (limited to 'ast/skyaxis.c')
-rw-r--r--ast/skyaxis.c5150
1 files changed, 0 insertions, 5150 deletions
diff --git a/ast/skyaxis.c b/ast/skyaxis.c
deleted file mode 100644
index fd6d6f6..0000000
--- a/ast/skyaxis.c
+++ /dev/null
@@ -1,5150 +0,0 @@
-/*
-*class++
-* Name:
-* SkyAxis
-
-* Purpose:
-* Store celestial axis information.
-
-* Constructor Function:
-* None.
-
-* Description:
-* The SkyAxis class is used to store information associated with a
-* particular axis of a SkyFrame. It is used internally by the AST
-* library and has no constructor function. You should encounter it
-c only within textual output (e.g. from astWrite).
-f only within textual output (e.g. from AST_WRITE).
-
-* Inheritance:
-* The SkyAxis class inherits from the Axis class.
-
-* Copyright:
-* Copyright (C) 1997-2006 Council for the Central Laboratory of the
-* Research Councils
-* Copyright (C) 2008 Science & Technology Facilities Council.
-* All Rights Reserved.
-
-* Licence:
-* This program is free software: you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation, either
-* version 3 of the License, or (at your option) any later
-* version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General
-* License along with this program. If not, see
-* <http://www.gnu.org/licenses/>.
-
-* Authors:
-* RFWS: R.F. Warren-Smith (Starlink)
-* DSB: B.S. Berry (Starlink)
-
-* History:
-* 1-MAR-1996 (RFWS):
-* Original version.
-* 19-APR-1996 (RFWS):
-* Tidied up, etc.
-* 8-MAY-1996 (RFWS):
-* Remove leading minus sign from formatted HMS string if all
-* fields are zero.
-* 9-MAY-1996 (RFWS):
-* Fixed bug in rounding of fractional parts of HMS strings and
-* improved algorithm to cope gracefully with requests for
-* excessive numbers of decimal places.
-* 13-MAY-1996 (RFWS):
-* Over-ride the astGetAxisDirection method so that a SkyAxis
-* with the AsTime attribute set is displayed in reverse by
-* default.
-* 17-MAY-1996 (RFWS):
-* Change AxisNorm to return a bad coordinate value if a bad
-* value is given.
-* 11-SEP-1996 (RFWS):
-* Added AxisGap and DHmsGap (written by DSB).
-* 26-FEB-1998 (RFWS):
-* Over-ride the astAxisUnformat method.
-* 6-MAR-1998 (RFWS):
-* Add formatting options to omit degrees/hours field and change
-* all affected functions.
-* 10-AUG-2000 (DSB):
-* Fixed bug in DHmsFormat which could cause (for instance) a formatted
-* galactic longitude value of zero to be formated as "-0.-0".
-* 29-AUG-2001 (DSB):
-* Added AxisDistance and AxisOffset.
-* 10-OCT-2002 (DSB):
-* Over-ride the astGetAxisTop and astGetAxisBottom methods so that a
-* SkyAxis with the IsLatitude attribute set is legal between plus
-* and minus 90 degrees.
-* 8-JAN-2003 (DSB):
-* - Changed private InitVtab method to protected astInitSkyAxisVtab
-* method.
-* - Modify DHmsGap to avoid decimal gap "4" which produces things
-* like "0.0 0.4 0.8 1.2 1.6 2.0" ("4" replaced by "5").
-* 24-JAN-2004 (DSB):
-* o Added AxisFields.
-* o Added 'g' format character which produces graphical separators.
-* o Modified AxisAbbrev to use AxisFields so that delimiters which
-* include digits can be recognised.
-* 13-SEP-20904 (DSB):
-* Modify AxisFields to correct usage of the "p" pointer in the
-* case that the first and only field begins with a minus sign.
-* 15-SEP-2004 (DSB):
-* Modified ParseDHmsFormat so that the number of decimal places
-* is specified by Digits if the given format string include a ".*"
-* precision (e.g. "dms.*").
-* 18-MAR-2005 (DSB):
-* Invoke methods inherited from parent Axis class if the format
-* string starts with a '%' character.
-* 14-FEB-2006 (DSB):
-* Override astGetObjSize.
-* 30-JUN-2006 (DSB):
-* Guard against a null "str1" value in AxisAbbrev.
-* 7-AUG-2007 (DSB):
-* Added CentreZero attribute.
-* 1-FEB-2008 (DSB):
-* Modified AxisUnformat to allow the final numerical field to include
-* an exponent.
-* 13-OCT-2011 (DSB):
-* Use tuning parameters to store graphical delimiters.
-* 27-APR-2015 (DSB):
-* Added InternalUNit attribute..
-* 26-OCT-2016 (DSB):
-* Override astAxisNormValues.
-* 7-NOV-2016 (DSB):
-* Ensure astAxisNormValues ignores bad axis values.
-*class--
-*/
-
-/* Module Macros. */
-/* ============== */
-/* Set the name of the class we are implementing. This indicates to the header
- files that define class interfaces that they should make "protected"
- symbols available. */
-#define astCLASS SkyAxis
-
-/* Header files. */
-/* ============= */
-#include "ast_err.h" /* Error code definitions */
-
-/* Interface definitions. */
-/* ---------------------- */
-#include "pal.h" /* SLALIB interface */
-
-#include "globals.h" /* Thread-safe global data access */
-#include "error.h" /* Error reporting facilities */
-#include "memory.h" /* Memory allocation facilities */
-#include "pointset.h" /* Sets of points (for AST__BAD) */
-#include "axis.h" /* Axis (parent) class interface */
-#include "skyaxis.h" /* Interface definition for this class */
-#include "globals.h" /* Thread-safe global data access */
-#include "wcsmap.h" /* For constants */
-
-/* C header files. */
-/* --------------- */
-#include <ctype.h>
-#include <limits.h>
-#include <math.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* Module Variables. */
-/* ================= */
-
-/* Address of this static variable is used as a unique identifier for
- member of this class. */
-static int class_check;
-
-/* Pointers to parent class methods which are extended by this class. */
-static int (* parent_getobjsize)( AstObject *, int * );
-static const char *(* parent_getattrib)( AstObject *, const char *, int * );
-static const char *(* parent_getaxislabel)( AstAxis *, int * );
-static const char *(* parent_getaxissymbol)( AstAxis *, int * );
-static const char *(* parent_getaxisunit)( AstAxis *, int * );
-static int (* parent_testattrib)( AstObject *, const char *, int * );
-static int (*parent_getaxisdirection)( AstAxis *this, int * );
-static void (* parent_axisoverlay)( AstAxis *, AstAxis *, int * );
-static void (* parent_clearattrib)( AstObject *, const char *, int * );
-static void (* parent_setattrib)( AstObject *, const char *, int * );
-static double (*parent_getaxisbottom)( AstAxis *this, int * );
-static double (*parent_getaxistop)( AstAxis *this, int * );
-static const char *(* parent_axisformat)( AstAxis *, double, int * );
-static double (*parent_axisgap)( AstAxis *, double, int *, int * );
-static int (*parent_axisunformat)( AstAxis *, const char *, double *, int * );
-static int (*parent_axisfields)( AstAxis *, const char *, const char *, int, char **, int *, double *, int * );
-
-/* Factors for converting between hours, degrees and radians. */
-static double hr2rad;
-static double deg2rad;
-static double pi;
-static double piby2;
-
-/* Define macros for accessing each item of thread specific global data. */
-#ifdef THREAD_SAFE
-
-/* Define how to initialise thread-specific globals. */
-#define GLOBAL_inits \
- globals->Class_Init = 0; \
- globals->DHmsFormat_Buff[ 0 ] = 0; \
- globals->DHmsUnit_Buff[ 0 ] = 0; \
- globals->GetAttrib_Buff[ 0 ] = 0; \
- globals->GetAxisFormat_Buff[ 0 ] = 0;
-
-/* Create the function that initialises global data for this module. */
-astMAKE_INITGLOBALS(SkyAxis)
-
-/* Define macros for accessing each item of thread specific global data. */
-#define class_init astGLOBAL(SkyAxis,Class_Init)
-#define class_vtab astGLOBAL(SkyAxis,Class_Vtab)
-#define dhmsformat_buff astGLOBAL(SkyAxis,DHmsFormat_Buff)
-#define dhmsunit_buff astGLOBAL(SkyAxis,DHmsUnit_Buff)
-#define getattrib_buff astGLOBAL(SkyAxis,GetAttrib_Buff)
-#define getaxisformat_buff astGLOBAL(SkyAxis,GetAxisFormat_Buff)
-
-static pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
-#define LOCK_MUTEX2 pthread_mutex_lock( &mutex2 );
-#define UNLOCK_MUTEX2 pthread_mutex_unlock( &mutex2 );
-
-/* If thread safety is not needed, declare and initialise globals at static
- variables. */
-#else
-
-static char dhmsformat_buff[ AST__SKYAXIS_DHMSFORMAT_BUFF_LEN + 1 ];
-static char dhmsunit_buff[ AST__SKYAXIS_DHMSUNIT_BUFF_LEN + 1 ];
-static char getattrib_buff[ AST__SKYAXIS_GETATTRIB_BUFF_LEN + 1 ];
-static char getaxisformat_buff[ AST__SKYAXIS_GETAXISFORMAT_BUFF_LEN + 1 ];
-
-/* Define the class virtual function table and its initialisation flag
- as static variables. */
-static AstSkyAxisVtab class_vtab; /* Virtual function table */
-static int class_init = 0; /* Virtual function table initialised? */
-
-#define LOCK_MUTEX2
-#define UNLOCK_MUTEX2
-
-#endif
-
-
-/* External Interface Function Prototypes. */
-/* ======================================= */
-/* The following functions have public prototypes only (i.e. no
- protected prototypes), so we must provide local prototypes for use
- within this module. */
-AstSkyAxis *astSkyAxisId_( const char *, ... );
-
-/* Prototypes for Private Member Functions. */
-/* ======================================== */
-static const char *AxisAbbrev( AstAxis *, const char *, const char *, const char *, int * );
-static const char *AxisFormat( AstAxis *, double, int * );
-static int GetObjSize( AstObject *, int * );
-static const char *GetAttrib( AstObject *, const char *, int * );
-static const char *GetAxisFormat( AstAxis *, int * );
-static const char *GetAxisInternalUnit( AstAxis *, int * );
-static const char *GetAxisLabel( AstAxis *, int * );
-static const char *GetAxisSymbol( AstAxis *, int * );
-static const char *GetAxisUnit( AstAxis *, int * );
-static const char *DHmsFormat( const char *, int, double, int * );
-static const char *DHmsUnit( const char *, int, int, int * );
-static double AxisGap( AstAxis *, double, int *, int * );
-static double AxisDistance( AstAxis *, double, double, int * );
-static double AxisOffset( AstAxis *, double, double, int * );
-static double DHmsGap( const char *, int, double, int *, int * );
-static double GetAxisTop( AstAxis *, int * );
-static double GetAxisBottom( AstAxis *, int * );
-static int AxisIn( AstAxis *, double, double, double, int, int * );
-static int AxisFields( AstAxis *, const char *, const char *, int, char **, int *, double *, int * );
-static int AxisUnformat( AstAxis *, const char *, double *, int * );
-static int GetAxisAsTime( AstSkyAxis *, int * );
-static int GetAxisDirection( AstAxis *, int * );
-static int GetAxisIsLatitude( AstSkyAxis *, int * );
-static int GetAxisCentreZero( AstSkyAxis *, int * );
-static int TestAttrib( AstObject *, const char *, int * );
-static int TestAxisAsTime( AstSkyAxis *, int * );
-static int TestAxisFormat( AstAxis *, int * );
-static int TestAxisInternalUnit( AstAxis *, int * );
-static int TestAxisIsLatitude( AstSkyAxis *, int * );
-static int TestAxisCentreZero( AstSkyAxis *, int * );
-static void AxisNorm( AstAxis *, double *, int * );
-static void AxisNormValues( AstAxis *, int, int, double *, int * );
-static void AxisOverlay( AstAxis *, AstAxis *, int * );
-static void ClearAttrib( AstObject *, const char *, int * );
-static void ClearAxisAsTime( AstSkyAxis *, int * );
-static void ClearAxisFormat( AstAxis *, int * );
-static void ClearAxisIsLatitude( AstSkyAxis *, int * );
-static void ClearAxisCentreZero( AstSkyAxis *, int * );
-static void Copy( const AstObject *, AstObject *, int * );
-static void Delete( AstObject *, int * );
-static void Dump( AstObject *, AstChannel *, int * );
-static void ParseDHmsFormat( const char *, int, char *, int *, int *, int *, int *, int *, int *, int *, int * );
-static void SetAttrib( AstObject *, const char *, int * );
-static void SetAxisAsTime( AstSkyAxis *, int, int * );
-static void SetAxisFormat( AstAxis *, const char *, int * );
-static void SetAxisIsLatitude( AstSkyAxis *, int, int * );
-static void SetAxisCentreZero( AstSkyAxis *, int, int * );
-
-/* Member functions. */
-/* ================= */
-static const char *AxisAbbrev( AstAxis *this_axis, const char *fmt,
- const char *str1, const char *str2, int *status ) {
-/*
-* Name:
-* AxisAbbrev
-
-* Purpose:
-* Abbreviate a formatted SkyAxis value by skipping leading fields.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* const char *AxisAbbrev( AstAxis *this, const char *fmt,
-* const char *str1, const char *str2 )
-
-* Class Membership:
-* SkyAxis member function (over-rides the protected astAxisAbbrev
-* method inherited from the Axis class).
-
-* Description:
-* This function compares two SkyAxis values that have been
-* formatted with the supplied format specifier (using astAxisFormat)
-* and determines if they have any redundant leading fields (i.e.
-* leading fields in common which can be suppressed when tabulating
-* the values or plotting them on the axis of a graph).
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* fmt
-* Pointer to a constant null-terminated string containing the
-* format specifier used to format the two values.
-* str1
-* Pointer to a constant null-terminated string containing the
-* first formatted value. If this is null, the returned pointer
-* points to the start of the final field in str2.
-* str2
-* Pointer to a constant null-terminated string containing the
-* second formatted value.
-
-* Returned Value:
-* A pointer into the "str2" string which locates the first
-* character in the first field that differs between the two
-* formatted values.
-*
-* If the two values have no leading fields in common, the returned
-* value will point at the start of string "str2". If the two
-* values are equal, it will point at the terminating null at the
-* end of this string.
-
-* Notes:
-* - A pointer to the start of "str2" will be returned if this
-* function is invoked with the global error status set, or if it
-* should fail for any reason.
-*/
-
-/* Local Variables: */
- char *fld1[ 3 ]; /* Pointers to start of each field in str1 */
- char *fld2[ 3 ]; /* Pointers to start of each field in str2 */
- const char *result; /* Result pointer to return */
- int i; /* Loop counter for string fields */
- int nf1; /* Number of fields found in str1 */
- int nf2; /* Number of fields found in str2 */
- int nc1[ 3 ]; /* Length of each field in str1 */
- int nc2[ 3 ]; /* Length of each field in str2 */
-
-/* Initialise. */
- result = str2;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Find the fields within the "str2" string. */
- nf2 = astAxisFields( this_axis, fmt, str2, 3, fld2, nc2, NULL );
-
-/* If "str1" was not supplied, return a pointer to the final field in
- "str2". */
- if( !str1 ) {
- result = fld2[ nf2 - 1 ];
-
-/* Otherwise, find the fields within the "str1" string. */
- } else {
- nf1 = astAxisFields( this_axis, fmt, str1, 3, fld1, nc1, NULL );
-
-/* Loop to inspect corresponding fields from each string. */
- for ( i = 0; i < nf1 && i < nf2; i++ ) {
-
-/* If the fields are different, break out of the loop. */
- if ( nc1[ i ] != nc2[ i ] ||
- strncmp( fld1[ i ], fld2[ i ], nc1[ i ] ) ) {
- break;
-
-/* Otherwise, move the returned poitner on to point to the start of the
- next field in str2. If we are already at the last field in str2,
- return a pointer to the terminating null. */
- } else {
- if ( i + 1 < nf2 ) {
- result = fld2[ i + 1 ];
- } else {
- result = strchr( str2, '\0' );
- }
- }
- }
- }
-
-/* Return the result. */
- return result;
-}
-
-static double AxisDistance( AstAxis *this_axis, double v1, double v2, int *status ) {
-/*
-* Name:
-* AxisDistance
-
-* Purpose:
-* Find the distance between two axis values.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* AxisDistance( AstAxis *this, double v1, double v2 )
-
-* Class Membership:
-* SkyAxis member function (over-rides the protected astAxisDistance
-* method inherited from the Axis class).
-
-* Description:
-* This function returns a signed value representing the axis increment
-* from axis value v1 to axis value v2.
-*
-* For a SkyAxis, the angular difference between the two supplied axis
-* values is normalized into the range +PI to -PI.
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* v1
-* The first axis value
-* v2
-* The second axis value
-
-* Returned Value:
-* The axis increment from v1 to v2.
-
-* Notes:
-* - A value of AST__BAD is returned if either axis value is AST__BAD.
-* - A value of AST__BAD will be returned if this function is invoked
-* with the global error status set, or if it should fail for any
-* reason.
-*/
-
-/* Local Variables: */
- double result; /* Returned gap size */
-
-/* Initialise. */
- result = AST__BAD;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Check both axis values are OK, and form the returned increment,
- normalizing it into the range +PI to -PI. */
- if( v1 != AST__BAD && v2 != AST__BAD ) result = palDrange( v2 - v1 );
-
-/* Return the result. */
- return result;
-}
-
-static int AxisFields( AstAxis *this_axis, const char *fmt, const char *str,
- int maxfld, char **fields, int *nc, double *val, int *status ) {
-/*
-* Name:
-* AxisFields
-
-* Purpose:
-* Identify numerical fields within a formatted SkyAxis value.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* int AxisFields( AstAxis *this_axis, const char *fmt, const char *str,
-* int maxfld, char **fields, int *nc, double *val )
-
-* Class Membership:
-* SkyAxis member function (over-rides the protected astAxisFields
-* method inherited from the Axis class).
-
-* Description:
-* This function identifies the numerical fields within a SkyAxis value
-* that have been formatted using astAxisFormat. It assumes that the
-* value was formatted using the supplied format string. It also
-* returns the equivalent floating point value in radians.
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* fmt
-* Pointer to a constant null-terminated string containing the
-* format used when creating "str".
-* str
-* Pointer to a constant null-terminated string containing the
-* formatted value.
-* maxfld
-* The maximum number of fields to identify within "str".
-* fields
-* A pointer to an array of at least "maxfld" character pointers.
-* Each element is returned holding a pointer to the start of the
-* corresponding field in "str" (in the order in which they occur
-* within "str"), or NULL if no corresponding field can be found.
-* nc
-* A pointer to an array of at least "maxfld" integers. Each
-* element is returned holding the number of characters in the
-* corresponding field, or zero if no corresponding field can be
-* found.
-* val
-* Pointer to a location at which to store the radians value
-* equivalent to the returned field values. If this is NULL,
-* it is ignored.
-
-* Returned Value:
-* The number of fields succesfully identified and returned.
-
-* Notes:
-* - Leading and trailing spaces are ignored.
-* - If the formatted value is not consistent with the supplied format
-* string, then a value of zero will be returned, "fields" will be
-* returned holding NULLs, "nc" will be returned holding zeros, and
-* "val" is returned holding VAL__BAD.
-* - Fields are counted from the start of the formatted string. If the
-* string contains more than "maxfld" fields, then trailing fields are
-* ignored.
-* - If this function is invoked with the global error status set, or
-* if it should fail for any reason, then a value of zero will be returned
-* as the function value, and "fields", "nc" and "val" will be returned
-* holding their supplied values
-
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Pointer to thread-specific global data */
- char sep; /* Field separator character */
- char tbuf[50]; /* Buffer for terminator string */
- char *p; /* Pointer to next character */
- char *t; /* Pointer to start of terminator string */
- char *term; /* Pointer to terminator string */
- double dval; /* Value read from string */
- double value; /* Equivalent radians value */
- int as_time; /* Format the value as a time? */
- int dh; /* Hours field required? */
- int ifld; /* Field index */
- int lead_zero; /* Add leading zeros? */
- int min; /* Minutes field required? */
- int ndp; /* Number of decimal places */
- int ok; /* Value and format consistent? */
- int plus; /* Add leading plus sign? */
- int result; /* Result fields count to return */
- int sec; /* Seconds field required? */
- int sign; /* The sign of the radians value */
-
-/* Check the global error status. */
- if ( !astOK ) return 0;
-
-/* Get a pointer to the thread specific global data structure. */
- astGET_GLOBALS(this_axis);
-
-/* If the format string starts with a "%" call the method inherited from
- the parent Axis class. */
- if( fmt[ 0 ] == '%' ) {
- return (*parent_axisfields)( this_axis, fmt, str, maxfld, fields, nc,
- val, status );
- }
-
-/* Initialise. */
- result = 0;
- for( ifld = 0; ifld < maxfld; ifld++ ) {
- fields[ ifld ] = NULL;
- nc[ ifld ] = 0;
- }
- if( val ) *val = AST__BAD;
-
-/* Parse the format specifier. */
- ParseDHmsFormat( fmt, astGetAxisDigits( this_axis ), &sep, &plus, &lead_zero,
- &as_time, &dh, &min, &sec, &ndp, status );
-
-/* Only proceed if the format was parsed succesfully, and the supplied arrays
- are not of zero size. */
- if( astOK && maxfld > 0 ) {
-
-/* Indicate that we have not yet found any inconsistency between the
- formatted value and the forat string. */
- ok = 1;
-
-/* Variable "p" points to the next character to be read from the
- formatted string. Initialise it to point to the first non-space
- character. */
- p = (char *) str;
- while( *p == ' ' ) p++;
-
-/* Note the start of the first field. */
- fields[ 0 ] = p;
-
-/* If the first non-blank character is a + or - sign, skip it and note
- the sign of the final value. */
- sign = 1;
- if( *p == '-' ) {
- sign = -1;
- p++;
- } else if( *p == '+' ) {
- p++;
- }
-
-/* Initialise the equivalent radian value. */
- value = 0.0;
-
-/* If the format string specifies a degrees or hours field, it should be
- the first field. */
- if( dh ) {
-
-/* If the format indicates that fields are separated by characters, or if
- there is a minutes or seconds field, then the first field should end with
- the appropriate separator. In these cases locate the terminator,and
- store the length of the first field. */
- if( sep == 'l' || sep == 'g' || min || sec ) {
-
- if( sep == 'l' ) {
- term = as_time ? "h" : "d";
-
- } else if( sep == 'g' ) {
- astTuneC( as_time ? "hrdel":"dgdel", NULL, tbuf,
- sizeof( tbuf ) );
- term = tbuf;
-
- } else {
- tbuf[ 0 ] = sep;
- tbuf[ 1 ] = '\0';
- term = tbuf;
- }
-
- t = strstr( p, term );
- if( t ) {
- nc[ 0 ] = t - fields[ 0 ];
- } else {
- ok = 0;
- }
-
-/* Move on to the first character following the terminator. */
- p = t + strlen( term );
-
-/* In all other cases, the first field is the only field and is not
- terminated. Note its length (ignoring trailing spaces). Move the
- pointer on by the length of the field, remembering that any leading
- minus sign has already been skipped. */
- } else {
- nc[ 0 ] = astChrLen( fields[ 0 ] );
- p += nc[ result ];
- if( sign == -1 ) p--;
- }
-
-/* Read a numerical value from the first field. */
- if( astSscanf( fields[ 0 ], "%lg", &dval ) ) {
- value = fabs( dval );
- } else {
- ok = 0;
- }
-
-/* Increment then number of returned fields if OK */
- if( ok ) result++;
-
- }
-
-/* If the format string specifies a minutes field, it should be the next
- field. */
- if( min && ok ) {
-
-/* Note the start of the next field. */
- fields[ result ] = p;
-
-/* If the format indicates that fields are separated by characters, or if
- there is a seconds field, then this field should end with the appropriate
- separator. In these cases locate the terminator,and store the length of
- this field. */
- if( sep == 'l' || sep == 'g' || sec ) {
- if( sep == 'l' ) {
- term = "m";
-
- } else if( sep == 'g' ) {
- astTuneC( as_time ? "mndel":"amdel", NULL, tbuf,
- sizeof( tbuf ) );
- term = tbuf;
-
- } else {
- tbuf[ 0 ] = sep;
- tbuf[ 1 ] = '\0';
- term = tbuf;
- }
-
- t = strstr( p, term );
- if( t ) {
- nc[ result ] = t - fields[ result ];
- } else {
- ok = 0;
- }
-
-/* Move on to the first character following the terminator. */
- p = t + strlen( term );
-
-/* In all other cases, this field is not terminated. Note its length
- (ignoring trailing spaces). */
- } else {
- nc[ result ] = astChrLen( fields[ result ] );
- p += nc[ result ];
- }
-
-/* Read a numerical value from this field. */
- if( astSscanf( fields[ result ], "%lg", &dval ) ) {
- value += dval/60.0;
- } else {
- ok = 0;
- }
-
-/* Increment then number of returned fields if OK */
- if( ok ) result++;
-
- }
-
-/* If the format string specifies a seconds field, it should be the next
- field. */
- if( sec && ok ) {
-
-/* Note the start of the next field. */
- fields[ result ] = p;
-
-/* If the format indicates that fields are separated by characters, then this
- field should end with the appropriate separator. In this case locate the
- terminator,and store the length of this field. */
- if( sep == 'l' || sep == 'g' ) {
- if( sep == 'l' ) {
- term = "s";
- } else {
- astTuneC( as_time ? "scdel":"asdel", NULL, tbuf,
- sizeof( tbuf ) );
- term = tbuf;
- }
-
- t = strstr( p, term );
- if( t ) {
- nc[ result ] = t - fields[ result ];
- } else {
- ok = 0;
- }
-
-/* Move on to the first character following the terminator. */
- p = t + strlen( term );
-
-/* In all other cases, this field is not terminated. Note its length
- (ignoring trailing spaces). */
- } else {
- nc[ result ] = astChrLen( fields[ result ] );
- p += nc[ result ];
- }
-
-/* Read a numerical value from this field. */
- if( astSscanf( fields[ result ], "%lg", &dval ) ) {
- value += dval/3600.0;
- } else {
- ok = 0;
- }
-
-/* Increment then number of returned fields if OK */
- if( ok ) result++;
-
- }
-
-/* Check that nothing is left.*/
- if( astChrLen( p ) > 0 ) ok = 0;
-
-/* If OK, convert the axis value to radians. */
- if( ok ) {
- if( val ) {
- *val = sign*value*( as_time ? hr2rad : deg2rad );
- }
-
-/* Otherwise, return zero. */
- } else {
- result = 0;
- for( ifld = 0; ifld < maxfld; ifld++ ) {
- fields[ ifld ] = NULL;
- nc[ ifld ] = 0;
- }
- }
- }
-
-/* Return the result. */
- return result;
-}
-
-static const char *AxisFormat( AstAxis *this_axis, double value, int *status ) {
-/*
-* Name:
-* AxisFormat
-
-* Purpose:
-* Format a coordinate value for a SkyAxis.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* const char *AxisFormat( AstAxis *this, double value, int *status )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astAxisFormat method inherited
-* from the Axis class).
-
-* Description:
-* This function returns a pointer to a string containing the formatted
-* (character) version of a coordinate value for a SkyAxis. The formatting
-* applied is that specified by a previous invocation of the
-* astSetAxisFormat method. A suitable default format is applied if
-* necessary.
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* value
-* The coordinate value to be formatted (in radians).
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A pointer to a null-terminated string containing the formatted value.
-
-* Notes:
-* - The returned string pointer may point at memory allocated within
-* the SkyAxis object, or at static memory. The contents of the string may
-* be over-written or the pointer may become invalid following a further
-* invocation of the same function or deletion of the SkyAxis. A copy of the
-* string should therefore be made if necessary.
-* - A NULL pointer will be returned if this function is invoked with the
-* global error status set, or if it should fail for any reason.
-*/
-
-/* Local Variables: */
- AstSkyAxis *this; /* Pointer to the SkyAxis structure */
- const char *fmt; /* Pointer to format specifier */
- const char *result; /* Pointer to result string */
-
-/* Check the global error status. */
- if ( !astOK ) return NULL;
-
-/* Initialise. */
- result = NULL;
-
-/* Obtain a pointer to the SkyAxis structure. */
- this = (AstSkyAxis *) this_axis;
-
-/* Obtain a pointer to the format specifier to be used. Note we use a private
- member function to obtain this (not a method) in case derived classes have
- extended the syntax of this string. */
- fmt = GetAxisFormat( this_axis, status );
-
-/* If the format string starts with a percent, use the AxisFormat method
- inherited from the parent Axis class. Otherwise, format using the
- syntax of this class. */
- if ( astOK ) {
- if( fmt[ 0 ] == '%' ) {
- result = (*parent_axisformat)( this_axis, value, status );
- } else {
- result = DHmsFormat( fmt, astGetAxisDigits( this ), value, status );
- }
- }
-
-/* Return the result. */
- return result;
-}
-
-static double AxisGap( AstAxis *this_axis, double gap, int *ntick, int *status ) {
-/*
-* Name:
-* AxisGap
-
-* Purpose:
-* Find a "nice" gap for tabulating SkyAxis values.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* double AxisGap( AstAxis *this, double gap, int *ntick, int *status )
-
-* Class Membership:
-* SkyAxis member function (over-rides the protected astAxisGap
-* method inherited from the Axis class).
-
-* Description:
-* This function returns a gap size in radians which produces a
-* nicely spaced series of formatted SkyAxis values, the returned
-* gap size being as close as possible to the supplied target gap
-* size. It also returns a convenient number of divisions into
-* which the gap can be divided.
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* gap
-* The target gap size.
-* ntick
-* Address of an int in which to return a convenient number of
-* divisions into which the gap can be divided.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The nice gap size.
-
-* Notes:
-* - The returned gap size is influenced by the format string
-* specified for the SkyAxis by a previous invocation of the
-* astSetAxisFormat method. A suitable default format is used if
-* necessary.
-* - A value of zero is returned if the supplied gap size is zero.
-* - A negative gap size is returned if the supplied gap size is negative.
-* - A value of zero will be returned if this function is invoked
-* with the global error status set, or if it should fail for any
-* reason.
-*/
-
-/* Local Variables: */
- AstSkyAxis *this; /* Pointer to the SkyAxis structure */
- const char *fmt; /* Pointer to Format string */
- double result; /* Returned gap size */
-
-/* Initialise. */
- result = 0.0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the SkyAxis structure. */
- this = (AstSkyAxis *) this_axis;
-
-/* Obtain a pointer to the format string to be used. Note we use a
- private member function to obtain this (not a method) in case
- derived classes have extended the syntax of this string. */
- fmt = GetAxisFormat( this_axis, status );
-
-/* Obtain the closest "nice" gap size. */
- if ( astOK ) result = DHmsGap( fmt, astGetAxisDigits( this ), gap, ntick, status );
-
-/* If the format string starts with a percent, use the AxisGap method
- inherited from the parent Axis class. Otherwise, use the method
- provided by this class. */
- if ( astOK ) {
- if( fmt[ 0 ] == '%' ) {
- result = (*parent_axisgap)( this_axis, gap, ntick, status );
- } else {
- result = DHmsGap( fmt, astGetAxisDigits( this ), gap, ntick, status );
- }
- }
-
-/* Return the result. */
- return result;
-}
-
-static int AxisIn( AstAxis *this, double lo, double hi, double val, int closed, int *status ){
-/*
-* Name:
-* AxisIn
-
-* Purpose:
-* Test if an axis value lies within a given interval.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* int AxisIn( AstAxis *this, double lo, double hi, double val, int closed, int *status )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astAxisIn method inherited
-* from the Axis class).
-
-* Description:
-* This function returns non-zero if a given axis values lies within a
-* given axis interval.
-*
-* The SkyAxis implementation of this method treats the supplied
-* numerical values as non-cyclic (e.g. lo=10, hi = 350 implies that
-* val = 180 is inside and zero is outside: lo = 10, hi = 400 would imply
-* that all angles are inside: lo = -10, hi = 10 would imply that 180 is
-* outside and zero is inside). But when testing a supplied value, adding
-* or subtracting multiples of 2.PI from the supplied value will make no
-* difference to whether the point is inside or outside).
-
-* Parameters:
-* this
-* Pointer to the Axis.
-* lo
-* The lower axis limit of the interval.
-* hi
-* The upper axis limit of the interval.
-* val
-* The axis value to be tested.
-* closed
-* If non-zero, then the lo and hi axis values are themselves
-* considered to be within the interval. Otherwise they are outside.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Non-zero if the test value is inside the interval.
-
-*/
-
-/* For speed, omit the astOK check since no pointers are being used. */
-
-/* Deal with closed intervals. */
- if( closed ) {
-
-/* If the supplied value is greater than the upper limit, subtract 2.PI until
- it is not. */
- while( val > hi ) val -= 2*pi;
-
-/* If the value is now less than the lower limit, add 2.PI until it is not. */
- while( val < lo ) val += 2*pi;
-
-/* The axis value is in the range if its numerical value is less than or
- equal to the end value. */
- return ( val <= hi );
-
-/* Now deal with open intervals. */
- } else {
-
-/* If the supplied value is greater than or equal to the upper limit, subtract
- 2.PI until it is not. */
- while( val >= hi ) val -= 2*pi;
-
-/* If the value is now less than or equal to the lower limit, add 2.PI until
- it is not. */
- while( val <= lo ) val += 2*pi;
-
-/* The axis value is in the range if its numerical value is less than the
- end value. */
- return ( val < hi );
- }
-}
-
-static void AxisNorm( AstAxis *this_axis, double *value, int *status ) {
-/*
-* Name:
-* AxisNorm
-
-* Purpose:
-* Normalise a SkyAxis coordinate value.
-
-* Type:
-* Public virtual function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* void AxisNorm( AstAxis *this, double *value, int *status )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astAxisNorm method inherited
-* from the Axis class).
-
-* Description:
-* This function converts a SkyAxis coordinate value which might
-* potentially be unsuitable for display to a user (for instance,
-* may lie outside the expected range of values) into an acceptable
-* alternative value suitable for display.
-*
-* For a SkyAxis that is a longitude axis, values are wrapped into
-* the range zero to 2*pi, while for a latitude axis, they are
-* wrapped into the range -pi to +pi. The astAxisCentreZero method
-* is used to determine which algorithm to apply.
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* value
-* Pointer to the coordinate value to be normalised, which will
-* be modified in place.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Local Variables: */
- AstSkyAxis *this; /* Pointer to the SkyAxis structure */
- int centrezero; /* SkyAxis range centred on zero? */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the SkyAxis structure. */
- this = (AstSkyAxis *) this_axis;
-
-/* If the coordinate value is bad, then return it unchanged. Otherwise,
- determine if the SkyAxis range is centred on zero or PI. */
- if ( *value != AST__BAD ) {
- centrezero = astGetAxisCentreZero( this );
-
-/* Wrap the value into the appropriate range. */
- if ( astOK ) *value = centrezero ? palDrange( *value ) :
- palDranrm( *value );
- }
-}
-
-static void AxisNormValues( AstAxis *this_axis, int oper, int nval,
- double *values, int *status ){
-/*
-* Name:
-* astAxisNormValues
-
-* Purpose:
-* Normalise an array of axis coordinate values.
-
-* Type:
-* Public virtual function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* void astAxisNormValues( AstAxis *this, int oper, int nval,
-* double *values )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astAxisNormValues method
-* inherited from the Axis class).
-
-* Description:
-* This function modifies a supplied array of axis values so that
-* they are normalised in the manner indicated by parameter "oper".
-*
-* For a SkyAxis, if "oper" is 0, longitude values are returned in
-* the range [0,2*PI]. If "oper" is 1, longitude values are returned
-* in either the range [0,2*PI] or [-PI,PI]. The choice is made so
-* that the resulting list has the smallest range. Latitude values
-* are always returned in the range [-PI,PI].
-
-* Parameters:
-* this
-* Pointer to the Axis.
-* oper
-* Indicates the type of normalisation to be applied. If zero is
-* supplied, the normalisation will be the same as that performed by
-* function astAxisNorm. If 1 is supplied, the normalisation will be
-* chosen automatically so that the resulting list has the smallest
-* range.
-* nval
-* The number of points in the values array.
-* values
-* On entry, the axis values to be normalised. Modified on exit to
-* hold the normalised values.
-
-* Notes:
-* - Bad axis values, and axis values outside the range -1E6 to +1E6
-* radians (such as DBL_MAX and DBL_MIN) are returned unchanged.
-
-*/
-
-/* Local macros */
-#define VAL_OK(v) ((v)!=AST__BAD&&fabs(v)<1.0E6)
-
-/* Local Variables: */
- AstSkyAxis *this; /* Pointer to the SkyAxis structure */
- double *pv; /* Pointer to next axis value */
- double hi; /* Max axis value after normalisation */
- double lo; /* Min axis value after normalisation */
- double mn1; /* Min value in range [-pi,0] */
- double mn2; /* Min value in range [0,pi] */
- double mn3; /* Min value in range [pi,2pi] */
- double mx1; /* Max value in range [-pi,0] */
- double mx2; /* Max value in range [0,pi] */
- double mx3; /* Max value in range [pi,2pi] */
- double range1; /* Range after normalising to [0,2*pi] */
- double range2; /* Range after normalising to [-pi,pi] */
- double twopi; /* Two PI */
- int centrezero; /* SkyAxis range centred on zero? */
- int i; /* Index of next axis value */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the SkyAxis structure. */
- this = (AstSkyAxis *) this_axis;
-
-/* Oper 0 - always normalise according to the value of the CentreZero
- attribute (i.e. mimic AxisNorm). */
- if( oper == 0 ) {
-
-/* Determine if the SkyAxis range is centred on zero or PI. */
- centrezero = astGetAxisCentreZero( this );
-
-/* Loop over axis values. */
- pv = values;
- for( i = 0; i < nval; i++,pv++ ) {
-
-/* If the coordinate value is bad, or unusually large, then return it
- unchanged. Otherwise, wrap the value into the appropriate range. */
- if( VAL_OK(*pv) ) *pv = centrezero ? palDrange( *pv ) :
- palDranrm( *pv );
- }
-
-/* Oper 1 - choose a range that leaves most values unchanged. */
- } else if( oper == 1 ) {
-
-/* Normalise latitude axes into [-PI,+PI]. */
- if( astGetAxisIsLatitude( this ) ) {
- pv = values;
- for( i = 0; i < nval; i++,pv++ ) {
- if( VAL_OK(*pv) ) *pv = palDrange( *pv );
- }
-
-/* Now deal with longitude axes. */
- } else {
-
-/* First ensure all values are in the range [-PI,2*PI] and find the max
- and min value in each of the three ranges [-PI,0], [0,PI], [PI, 2PI]. */
- twopi = 2*AST__DPI;
- mx1 = -DBL_MAX;
- mn1 = DBL_MAX;
- mx2 = -DBL_MAX;
- mn2 = DBL_MAX;
- mx3 = -DBL_MAX;
- mn3 = DBL_MAX;
-
- pv = values;
- for( i = 0; i < nval; i++,pv++ ) {
- if( VAL_OK(*pv) ) {
- while( *pv > twopi ) *pv -= twopi;
- while( *pv < -AST__DPIBY2 ) *pv += twopi;
-
- if( *pv > AST__DPI ) {
- mx3 = astMAX( mx3, *pv );
- mn3 = astMIN( mn3, *pv );
- } else if( *pv > 0 ) {
- mx2 = astMAX( mx2, *pv );
- mn2 = astMIN( mn2, *pv );
- } else {
- mx1 = astMAX( mx1, *pv );
- mn1 = astMIN( mn1, *pv );
- }
- }
- }
-
-/* What would the range be if we normalised into [0,2.PI] ? */
- if( mx1 != -DBL_MAX ) {
- hi = astMAX( mx2, astMAX( mx1 + twopi, mx3) );
- lo = astMIN( mn2, astMIN( mn1 + twopi, mn3) );
- } else {
- hi = astMAX( mx2, mx3 );
- lo = astMIN( mn2, mn3 );
- }
- range1 = hi - lo;
-
-/* What would the range be if we normalised into [-PI,PI] ? */
- if( mn3 != -DBL_MAX ) {
- hi = astMAX( mx2, astMAX( mx3 - twopi, mx1) );
- lo = astMIN( mn2, astMIN( mn3 - twopi, mn1) );
- } else {
- hi = astMAX( mx2, mx1 );
- lo = astMIN( mn2, mn1 );
- }
- range2 = hi - lo;
-
-/* If [-PI,PI] produces the smaller range, normalise into [-PI,PI]. */
- if( range2 < range1 ) {
- pv = values;
- for( i = 0; i < nval; i++,pv++ ) {
- if( VAL_OK(*pv) ) *pv = palDrange( *pv );
- }
-
-/* Otherwise, normalise all into the range [0,2PI]. */
- } else {
- pv = values;
- for( i = 0; i < nval; i++,pv++ ) {
- if( VAL_OK(*pv) ) *pv = palDranrm( *pv );
- }
- }
- }
-
-/* Report an error if the supplied operation is invalid. */
- } else if( astOK ) {
- astError( AST__INTER, "astAxisNormValues: Invalid oper value %d "
- "supplied (internal AST programming error).", status, oper );
- }
-
-#undef VAL_OK
-}
-
-static double AxisOffset( AstAxis *this_axis, double v1, double dist, int *status ) {
-/*
-*
-* Name:
-* AxisOffset
-
-* Purpose:
-* Add an increment onto a supplied axis value.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* AxisOffset( AstSkyAxis *this, double v1, double dist )
-
-* Class Membership:
-* SkyAxis member function (over-rides the protected astAxisOffset
-* method inherited from the Axis class).
-
-* Description:
-* This function returns an axis value formed by adding a signed axis
-* increment onto a supplied axis value.
-*
-* For a SkyFrame, the result is normalized into the correct angular
-* range (+PI to -PI for latitude axes, and 0 to 2*PI for longitude axes).
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* v1
-* The supplied axis value
-* dist
-* The axis increment
-
-* Returned Value:
-* The axis value which is the specified increment away from v1.
-
-* Notes:
-* - A value of AST__BAD is returned if either axis value is AST__BAD.
-* - A value of AST__BAD will be returned if this function is invoked
-* with the global error status set, or if it should fail for any
-* reason.
-*/
-
-/* Local Variables: */
- double result; /* Returned gap size */
-
-/* Initialise. */
- result = AST__BAD;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Check both axis values are OK, and form the returned axis value. */
- if( v1 != AST__BAD && dist != AST__BAD ) {
- result = v1 + dist;
- AxisNorm( this_axis, &result, status );
- }
-
-/* Return the result. */
- return result;
-}
-
-static void AxisOverlay( AstAxis *template_axis, AstAxis *result, int *status ) {
-/*
-* Name:
-* AxisOverlay
-
-* Purpose:
-* Overlay the attributes of a template SkyAxis on to another Axis.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* void AxisOverlay( AstAxis *template, AstAxis *result, int *status )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astAxisOverlay method inherited
-* from the Axis class).
-
-* Description:
-* This function overlays attributes of a SkyAxis (the "template") on to
-* another Axis, so as to over-ride selected attributes of that second
-* Axis. Normally only those attributes which have been specifically set
-* in the template will be transferred. This implements a form of
-* defaulting, in which an Axis acquires attributes from the template, but
-* retains its original attributes (as the default) if new values have not
-* previously been explicitly set in the template.
-
-* Parameters:
-* template
-* Pointer to the template SkyAxis, for which values should have been
-* explicitly set for any attribute which is to be transferred.
-* result
-* Pointer to the Axis which is to receive the new attribute values.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* void
-*/
-
-/* Local Variables: */
- AstSkyAxis *template; /* Pointer to the SkyAxis structure */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the template SkyAxis structure. */
- template = (AstSkyAxis *) template_axis;
-
-/* Invoke the parent astAstOverlay method to overlay inherited attributes. */
- (*parent_axisoverlay)( template_axis, result, status );
-
-/* Test if the "result" Axis is a SkyAxis (if not, it cannot acquire any
- further attributes, so there is nothing more to do). */
- if ( astIsASkyAxis( result ) && astOK ) {
-
-/* Overlay the Format attribute if it is set in the template. Note that we
- use private member functions (not methods) to access the Format value, since
- derived classes may extend the syntax of this string and we should not
- overlay a string whose syntax cannot be interpreted by the result Axis. */
- if ( TestAxisFormat( template_axis, status ) ) {
- SetAxisFormat( result, GetAxisFormat( template_axis, status ), status );
- }
-
-/* Overlay the AsTime attribute in the same way, but this time using methods
- to access it. */
- if ( astTestAxisAsTime( template ) ) {
- astSetAxisAsTime( result, astGetAxisAsTime( template ) );
- }
-
-/* Also overlay the IsLatitude attribute. */
- if ( astTestAxisIsLatitude( template ) ) {
- astSetAxisIsLatitude( result, astGetAxisIsLatitude( template ) );
- }
-
-/* Also overlay the CentreZero attribute. */
- if ( astTestAxisCentreZero( template ) ) {
- astSetAxisCentreZero( result, astGetAxisCentreZero( template ) );
- }
- }
-}
-
-static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) {
-/*
-* Name:
-* ClearAttrib
-
-* Purpose:
-* Clear an attribute value for a SkyAxis.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* void ClearAttrib( AstObject *this, const char *attrib, int *status )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astClearAttrib protected
-* method inherited from the Axis class).
-
-* Description:
-* This function clears the value of a specified attribute for a
-* SkyAxis, so that the default value will subsequently be used.
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* attrib
-* Pointer to a null-terminated string specifying the attribute
-* name. This should be in lower case with no surrounding white
-* space.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Local Variables: */
- AstSkyAxis *this; /* Pointer to the SkyAxis structure */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the SkyAxis structure. */
- this = (AstSkyAxis *) this_object;
-
-/* Check the attribute name and clear the appropriate attribute. */
-
-/* AsTime. */
-/* ------- */
- if ( !strcmp( attrib, "astime" ) ) {
- astClearAxisAsTime( this );
-
-/* IsLatitude. */
-/* ----------- */
- } else if ( !strcmp( attrib, "islatitude" ) ) {
- astClearAxisIsLatitude( this );
-
-/* CentreZero. */
-/* ----------- */
- } else if ( !strcmp( attrib, "centrezero" ) ) {
- astClearAxisCentreZero( this );
-
-/* If the attribute is still not recognised, pass it on to the parent
- method for further interpretation. */
- } else {
- (*parent_clearattrib)( this_object, attrib, status );
- }
-}
-
-static void ClearAxisFormat( AstAxis *this_axis, int *status ) {
-/*
-* Name:
-* ClearAxisFormat
-
-* Purpose:
-* Clear the Format attribute for a SkyAxis.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* void ClearAxisFormat( AstAxis *this, int *status )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astClearAxisFormat method
-* inherited from the Axis class).
-
-* Description:
-* This function clears the Format attribute of a SkyAxis, as if no value
-* had ever been set for it.
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* void
-*/
-
-/* Local Variables: */
- AstSkyAxis *this; /* Pointer to the SkyAxis structure */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the SkyAxis structure. */
- this = (AstSkyAxis *) this_axis;
-
-/* Free any memory allocated to hold the Format string and reset the string
- pointer to NULL. */
- this->skyformat = astFree( this->skyformat );
-}
-
-static const char *DHmsFormat( const char *fmt, int digs, double value, int *status ) {
-/*
-* Name:
-* DHmsFormat
-
-* Purpose:
-* Format a value representing degrees/hours, minutes and seconds.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* const char *DHmsFormat( const char *fmt, int digs, double value, int *status )
-
-* Class Membership:
-* SkyAxis member function.
-
-* Description:
-* This function formats a value representing an angle in radians
-* into a text string giving degrees/hours, minutes and seconds
-* according to a format specifier supplied. See the "Format
-* Specifier" section for details of the formats available.
-
-* Parameters:
-* fmt
-* Pointer to a null terminated string containing the format
-* specifier.
-* digs
-* The default number of digits of precision to use. This is used
-* if the given format specifier indicates the number of decimal
-* places to use with the string ".*". In this case, the number of
-* decimal places produced will be chosen so that the total number
-* of digits of precision is equal to "digs".
-* double
-* The value to be formatted (in radians).
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Pointer to a null terminated character string containing the
-* formatted value.
-
-* Format Specifier:
-* The format specifier supplied via the "fmt" parameter should
-* contain zero or more of the following characters to specify the
-* format required. These characters may occur in any order, but
-* the following is recommended for clarity:
-*
-* '+'
-* Indicates that a plus sign should be prefixed to positive
-* values. By default, no plus sign is used.
-* 'z'
-* Indicates that leading zeros should be prefixed to the value
-* so that the first field is always of constant width, as would
-* be required in a fixed-width table. (Leading zeros are always
-* prefixed to any fields that follow.) By default, no leading
-* zeros are added.
-* 'i'
-* Use the standard ISO field separator (a colon) between
-* fields. This is the default behaviour.
-* 'b'
-* Use a blank to separate fields.
-* 'l'
-* Use a letter ('d'/'h', 'm' or 's' as appropriate) to separate
-* and identify fields.
-* 'g'
-* As 'l', but escape sequences are included in the returned
-* character string which cause the separators ('h', 'd', 'm', etc)
-* to be drawn as small super-scripts when plotted by the astText
-* or astGrid.
-* 'd'
-* Express the value as an angle and include a degrees
-* field. Expressing the value as an angle is also the default
-* behaviour if neither 'h' nor 't' is given, and expressing it
-* in degrees is the default if neither 'm' nor 's' is given.
-* 'h'
-* Express the value as a time instead of an angle (where 24
-* hours correspond to 360 degrees) and include an hours
-* field. Expressing times in hours is the default if 't' is
-* given without either 'm' or 's'.
-* 'm'
-* Include a minutes field. By default this is not included.
-* 's'
-* Include a seconds field. By default this is not
-* included. This request is ignored if 'd' or 'h' is given,
-* unless a minutes field is also included.
-* 't'
-* Express the value as a time instead of an angle (where 24
-* hours correspond to 360 degrees). This option is ignored if
-* either 'd' or 'h' is given and is intended for use in cases
-* where the value is to be expressed purely in minutes and/or
-* seconds of time (no hours field). If 't' is given without
-* 'd', 'h', 'm' or 's' being present, then it is equivalent to
-* 'h'.
-* '.'
-* Indicates that decimal places are to be given for the final
-* field in the formatted string (whichever field this is). The
-* '.' should be followed immediately by a zero or positive integer
-* which gives the number of decimal places required. The '.' may
-* also be followed by asterisk (i.e. '.*') which causes the number
-* of decimal places to be chosen so that the total number of digits
-* is equal to the value of Digits.
-*
-* Format specifiers are not case sensitive. If several characters
-* make conflicting requests (e.g. if both 'i' and 'l' appear in a
-* format specifier), then the character occurring last takes
-* precedence, except that 'd' and 'h' always override 't'.
-
-* Notes:
-* - The result string may be stored in static memory. Its contents
-* may be over-written or the returned pointer may become invalid
-* following a further invocation of this function. A copy of the
-* string should therefore be made if necessary.
-* - A NULL pointer will be returned if this function is invoked
-* with the global error status set, or if it should fail for any
-* reason.
-
-* Acknowledgements:
-* - This function is a close approximation to a Fortran 77 routine
-* written by Clive Davenhall which implements the system of format
-* specifiers for angles described in his document on the CAT
-* catalogue access library (Starlink User Note 181). Some minor
-* improvements have been made to ensure better behaviour when
-* results are rounded to a specified number of decimal places.
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Pointer to thread-specific global data */
- char *term; /* Pointer to terminator string */
- char sep; /* Field separator character */
- char tbuf[50]; /* Buffer for terminator string */
- const char *result; /* Pointer to result string */
- double absvalue; /* Absolute value in radians */
- double fract; /* Fractional part of final field */
- double idh; /* Integer number of degrees/hours */
- double ifract; /* Fractional part expressed as an integer */
- double imin; /* Integer number of minutes */
- double isec; /* Integer number of seconds */
- double shift; /* Factor for rounding fractional part */
- double test; /* Test value to determine rounding */
- int as_time; /* Format the value as a time? */
- int dh; /* Degrees/hours field required? */
- int lead_zero; /* Add leading zeros? */
- int min; /* Minutes field required? */
- int ndp; /* Number of decimal places */
- int plus; /* Add leading plus sign? */
- int pos; /* Position to add next character */
- int positive; /* Value is positive (or zero)? */
- int sec; /* Seconds field required? */
-
-/* Check the global error status. */
- if ( !astOK ) return NULL;
-
-/* Get a pointer to the thread specific global data structure. */
- astGET_GLOBALS(NULL);
-
-/* Initialise. */
- result = NULL;
-
-/* Check if a bad coordinate value has been given and return an
- appropriate string. */
- if ( value == AST__BAD ) {
- result = "<bad>";
-
-/* Otherwise... */
- } else {
-
-/* Parse the format specifier. */
- ParseDHmsFormat( fmt, digs, &sep, &plus, &lead_zero,
- &as_time, &dh, &min, &sec, &ndp, status );
-
-/* Break the value into fields. */
-/* ---------------------------- */
-/* Restrict the number of decimal places requested, if necessary, so
- that under the worst case the buffer for the result string is not
- likely to overflow. */
- if ( astOK ) {
- if ( ( ndp + 11 ) > AST__SKYAXIS_DHMSFORMAT_BUFF_LEN ) ndp = AST__SKYAXIS_DHMSFORMAT_BUFF_LEN - 11;
-
-/* Some operating systems have a "minus zero" value (for instance
- "-1.2*0" would give "-0"). This value is numerically equivalent to
- zero, but is formated as "-0" instead of "0". The leading minus sign
- confuses the following code, and so ensure now that all zero values
- are the usual "+0". */
- if ( value == 0.0 ) value = 0.0;
-
-/* Determine if the value to be formatted is positive and obtain its
- absolute value in radians. */
- positive = ( value >= 0.0 );
- absvalue = positive ? value : -value;
-
-/* Convert this to an absolute number of degrees or hours, as
- required. */
- fract = absvalue / ( as_time ? hr2rad : deg2rad );
-
-/* If a degrees/hours field is required, extract the whole number of
- degrees/hours and the remaining fractional part of a
- degree/hour. */
- idh = 0.0;
- if ( dh ) fract = modf( fract, &idh );
-
-/* If a minutes field is required, convert the value remaining to
- minutes and extract the whole number of minutes and the remaining
- fractional part of a minute. */
- imin = 0.0;
- if ( min ) fract = modf( fract * 60.0, &imin );
-
-/* If a seconds field is required, convert the value remaining to
- seconds (allowing for the absence of a minutes field if necessary)
- and extract the whole number of seconds and the remaining
- fractional part of a second. */
- isec = 0.0;
- if ( sec ) {
- if ( !min ) fract *= 60.0;
- fract = modf( fract * 60.0, &isec );
- }
-
-/* Round to the required number of decimal places. */
-/* ----------------------------------------------- */
-/* We must now round the fractional part (of whichever field) to the
- required number of decimal places. Calculate the power of 10 that
- brings the least significant digit into the units column. Scale the
- fractional part by this factor and truncate to an integer (but
- stored as a double to prevent possible integer overflow if the
- number of decimal places is excessive). */
- shift = pow( 10.0, (double) ndp );
- ifract = floor( fract * shift );
-
-/* Next we must determine if truncation was adequate, or whether we
- should round upwards instead. This process is more subtle than it
- seems because if a value with a 5 as the final digit is converted
- to radians and then back again, it may no longer end in 5 (because
- it cannot be represented exactly in radians) and so may round
- either up or down. If we want to recover the original (textual)
- value, we must compare the value we are formatting not with a test
- value whose last digit is 5, but with the closest number to this
- that can be represented exactly in radians.
-
- To do this, we add 0.5 to our truncated value, divide by the scale
- factor (to get the truncated fractional part, but now with a
- trailing digit 5 appended) and then combine this fractional part
- with the value of all the other fields. Finally, we convert this
- test value back into radians. */
- test = ( 0.5 + ifract ) / shift;
- if ( sec ) test = ( isec + test ) / 60.0;
- if ( min ) {
- test = ( imin + test ) / 60.0;
- } else if ( sec ) {
- test /= 60.0;
- }
- if ( dh ) test += idh;
- test *= ( as_time ? hr2rad : deg2rad );
-
-/* We now compare the absolute value we are formatting with this test
- value. If it is not smaller than it, we should have rounded up
- instead of truncating the final digit of the fractional part, so
- increment the integer representation of the truncated fractional
- part by 1.0 to compensate. */
- if ( absvalue >= test ) ifract += 1.0;
-
-/* Divide by the scale factor to obtain the correctly rounded
- fractional part. Then check if this fractional part is 1.0. If so,
- rounding has caused it to overflow into the units column of the
- final field, so clear the fractional part. */
- fract = ( ifract / shift );
- if ( fract >= 1.0 ) {
- ifract = 0.0;
-
-/* If a seconds field is present, propagate the overflow up through
- each field in turn, but omitting fields which are not required. Be
- careful about possible rounding errors when comparing integer
- values stored as double. */
- if ( sec ) {
- isec += 1.0;
- if ( ( floor( isec + 0.5 ) > 59.5 ) && min ) {
- isec = 0.0;
- imin += 1.0;
- if ( ( floor( imin + 0.5 ) > 59.5 ) && dh ) {
- imin = 0.0;
- idh += 1.0;
- }
- }
-
-/* Omit the seconds field if it is not present. */
- } else if ( min ) {
- imin += 1.0;
- if ( ( floor( imin + 0.5 ) > 59.5 ) && dh ) {
- imin = 0.0;
- idh += 1.0;
- }
-
-/* If only the degree/hour field is present, simply increment it. */
- } else {
- idh += 1.0;
- }
- }
-
-/* Construct the result string. */
-/* ---------------------------- */
-/* We now have the value of each field and the information about how
- they are to be formatted, so we can combine them into the required
- string. */
-
-/* If each field is either not required or equal to zero, disregard
- any sign. */
- if ( !positive && ( !dh || floor( idh + 0.5 ) < 0.5 ) &&
- ( !min || floor( imin + 0.5 ) < 0.5 ) &&
- ( !sec || floor( isec + 0.5 ) < 0.5 ) &&
- ( floor( ifract + 0.5 ) < 0.5 ) ) {
- positive = 1;
- }
-
-/* Use "pos" to identify where the next character should be
- added. Insert a leading '+' or '-' sign if required. */
- pos = 0;
- if ( !positive ) {
- dhmsformat_buff[ pos++ ] = '-';
- } else if ( plus ) {
- dhmsformat_buff[ pos++ ] = '+';
- }
-
-/* Use "sprintf" to format the degrees/hours field, if required. Set
- the minimum field width according to whether padding with leading
- zeros is required and whether the value represents hours (2 digits)
- or degrees (3 digits). */
- if ( dh ) {
- pos += sprintf( dhmsformat_buff + pos, "%0*.0f",
- lead_zero ? ( as_time ? 2 : 3 ) : 1, idh );
-
-/* If letters are being used as field separators, and there are more
- fields to follow, append "d" or "h" as necessary. */
- if ( min || sec ) {
- if ( sep == 'l' ) {
- dhmsformat_buff[ pos++ ] = ( as_time ? 'h' : 'd' );
- } else if( sep == 'g' ) {
- astTuneC( as_time ? "hrdel":"dgdel", NULL, tbuf,
- sizeof( tbuf ) );
- term = tbuf;
- pos += sprintf( dhmsformat_buff + pos, "%s", term );
- }
- }
- }
-
-/* If a minutes field is required, first add an appropriate non-letter
- field separator if needed. */
- if ( min ) {
- if ( ( sep != 'l' && sep != 'g' ) && dh ) dhmsformat_buff[ pos++ ] = sep;
-
-/* Then format the minutes field with a leading zero to make it two
- digits if necessary. */
- pos += sprintf( dhmsformat_buff + pos, "%0*.0f", ( dh || lead_zero ) ? 2 : 1,
- imin );
-
-/* If letters are being used as field separators, and there is another
- field to follow, append the separator. */
- if ( sec ) {
- if ( sep == 'l' ) {
- dhmsformat_buff[ pos++ ] = 'm';
- } else if( sep == 'g' ) {
- astTuneC( as_time ? "mndel":"amdel", NULL, tbuf,
- sizeof( tbuf ) );
- term = tbuf;
- pos += sprintf( dhmsformat_buff + pos, "%s", term );
- }
- }
- }
-
-/* Similarly, if a seconds field is required, first add an appropriate
- non-letter field separator if needed. */
- if ( sec ) {
- if ( ( sep != 'l' && sep != 'g' ) && ( dh || min ) ) dhmsformat_buff[ pos++ ] = sep;
-
-/* Then format the seconds field with a leading zero to make it two
- digits if necessary. */
- pos += sprintf( dhmsformat_buff + pos, "%0*.0f",
- ( dh || min || lead_zero ) ? 2 : 1, isec );
- }
-
-/* If decimal places are needed, add a decimal point followed by the
- integer representation of the correctly rounded fractional part,
- padded with leading zeros if necessary. */
- if ( ndp > 0 ) {
- dhmsformat_buff[ pos++ ] = '.';
- pos += sprintf( dhmsformat_buff + pos, "%0*.0f", ndp, ifract );
- }
-
-/* If letters are being used as separators, append the appropriate one
- to the final field. */
- if ( sep == 'l' ) {
- dhmsformat_buff[ pos++ ] = ( sec ? 's' : ( min ? 'm' :
- ( as_time ? 'h' : 'd' ) ) );
- } else if ( sep == 'g' ) {
- astTuneC( as_time ? ( sec ? "scdel" : ( min ? "mndel" : "hrdel" ) ) :
- ( sec ? "asdel" : ( min ? "amdel" : "dgdel" ) ),
- NULL, tbuf, sizeof( tbuf ) );
- term = tbuf;
- pos += sprintf( dhmsformat_buff + pos, "%s", term );
- }
-
-/* Terminate the result string and return a pointer to it. */
- dhmsformat_buff[ pos ] = '\0';
- result = dhmsformat_buff;
- }
- }
-
-/* Return the result. */
- return result;
-}
-
-static double DHmsGap( const char *fmt, int digs, double gap, int *ntick, int *status ) {
-/*
-* Name:
-* DHmsGap
-
-* Purpose:
-* Find a "nice" gap for formatted SkyAxis values.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* double DHmsGap( const char *fmt, int digs, double gap, int *ntick, int *status )
-
-* Class Membership:
-* SkyAxis member function.
-
-* Description:
-* This function returns a gap size in radians which produces a
-* nicely spaced series of formatted SkyAxis values, the returned
-* gap size being as close as possible to the supplied target gap
-* size. It also returns a convenient number of divisions into
-* which the gap can be divided.
-
-* Parameters:
-* fmt
-* Pointer to a constant null-terminated string containing the
-* format specifier which will be used to format the SkyAxis
-* values.
-* digs
-* The default number of digits of precision to use. This is used
-* if the given format specifier indicates the number of decimal
-* places to use with the string ".*". In this case, the number of
-* decimal places produced will be chosen so that the total number
-* of digits of precision is equal to "digs".
-* gap
-* The target gap size.
-* ntick
-* Address of an int in which to return a convenient number of
-* divisions into which the gap can be divided.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The nice gap size.
-
-* Notes:
-* - A value of zero is returned if the target gap size is zero.
-* - A negative gap size is returned if the supplied gap size is
-* negative.
-* - A value of zero will be returned if this function is invoked
-* with the global error status set, or if it should fail for any
-* reason.
-*/
-
-/* Local Constants: */
-#define BUFF_LEN 50 /* Length of character buffer */
-
-/* Local Variables: */
- char buff[ BUFF_LEN + 1 ]; /* Buffer for formatted scaled "nice" value */
- char sep; /* Field separator character */
- const double *table; /* Pointer to nice gap table */
- const int *nticks; /* Pointer to number of subdivisions table */
- double field_value[ 3 ]; /* Formatted field values in radians */
- double scale; /* Power of ten scaling factor */
- double scaled_table_value; /* Scaled "nice" value to test against */
- int as_time; /* Format the value as a time? */
- int decimal; /* Use nice decimal gap value? */
- int dh; /* Degrees/hours field required? */
- int field; /* ID of most significant formatted field */
- int i; /* Look-up-table index */
- int iter; /* Iteration count */
- int lead_zero; /* Add leading zeros? */
- int min; /* Minutes field required? */
- int ndp; /* Number of decimal places */
- int plus; /* Add leading plus sign? */
- int positive; /* Value is positive (or zero)? */
- int sec; /* Seconds field required? */
-
-/* Local Data: */
-/* ----------- */
-/* Table of nice decimal gaps. */
- const double dec_table[] = { 1.0, 2.0, 5.0, 5.0, 10.0, -1.0 };
- const int dec_nticks[] = { 5, 4, 5, 5, 5 };
-
-/* Table of nice degrees gaps. */
- const double deg_table[] =
- { 1.0, 2.0, 5.0, 10.0, 30.0, 45.0, 60.0, 90.0, 180.0, 360.0, -1.0 };
- const int deg_nticks[] =
- { 4, 4, 5, 5, 6, 3, 6, 3, 3, 4 };
-
-/* Table of nice hours gaps. */
- const double hr_table[] = { 1.0, 2.0, 3.0, 6.0, 12.0, 24.0, -1.0 };
- const int hr_nticks[] = { 4, 4, 6, 6, 4, 4 };
-
-/* Table of nice minutes or seconds gaps. */
- const double minsec_table[] = { 1.0, 2.0, 5.0, 10.0, 30.0, 60.0, -1.0 };
- const int minsec_nticks[] = { 4, 4, 5, 5, 6, 4 };
-
-/* Check the global error status. */
- if ( !astOK ) return 0.0;
-
-/* Check that the supplied gap size is not zero. */
- if ( gap != 0.0 ) {
-
-/* Parse the format specifier. */
- ParseDHmsFormat( fmt, digs, &sep, &plus, &lead_zero, &as_time, &dh, &min,
- &sec, &ndp, status );
-
-/* If OK, calculate the value of each formatted field in radians. */
- if ( astOK ) {
- field_value[ 0 ] = ( as_time ? hr2rad : deg2rad );
- field_value[ 1 ] = field_value[ 0 ] / 60.0;
- field_value[ 2 ] = field_value[ 0 ] / 3600.0;
-
-/* Determine if the suggested gap size is positive and obtain its
- absolute value. */
- positive = ( gap >= 0.0 );
- if ( !positive ) gap = -gap;
-
-/* Perform two iterations to determine the optimum gap value. This is
- because the method of choosing the gap value depends on the initial
- value. If a nice decimal gap is chosen on the first iteration,
- this may round the suggested gap value downwards, making it
- preferable to choose the gap value using a different method on the
- second iteration. */
- for ( iter = 0; iter < 2; iter++ ) {
-
-/* Decide which is the most significant field that the suggested gap
- value will occupy when formatted. Also decide whether to use a
- special "nice" gap value specific to that field, or simply to use a
- generic nice decimal gap value. Perform all tests on the gap size
- in radians, so as to avoid any rounding problems from conversion
- into degrees/hours, minutes or seconds. */
- decimal = 0;
-
-/* Suggested values exceeding one degree/hour. */
-/* ------------------------------------------- */
- if ( gap > field_value[ 0 ] ) {
-
-/* If a degree/hour field is present, use a special gap value, unless
- the suggested value exceeds the normal range of this field (in
- which case use a decimal gap). */
- if ( dh ) {
- field = 1;
- decimal = ( gap > ( field_value[ 0 ] *
- ( as_time ? 24.0 : 360.0 ) ) );
-
-/* If the most significant field is not degrees/hours, then its normal
- range will be exceeded, so use a decimal gap. */
- } else if ( min ) {
- field = 2;
- decimal = 1;
- } else {
- field = 3;
- decimal = 1;
- }
-
-/* Suggested values exceeding one minute. */
-/* -------------------------------------- */
- } else if ( gap > field_value[ 1 ] ) {
-
-/* If a minutes field is present, the suggested value will lie within
- its normal range, so use a special gap value. */
- if ( min ) {
- field = 2;
-
-/* Otherwise, if the most significant field is seconds, its normal
- range will be exceeded, so use a decimal gap value. */
- } else if ( sec ) {
- field = 3;
- decimal = 1;
-
-/* If only a degrees/hours field is present, then only digits after
- the decimal point can be affected, so use a decimal gap value. */
- } else {
- field = 1;
- decimal = 1;
- }
-
-/* Suggested values exceeding one second. */
-/* -------------------------------------- */
- } else if ( gap > field_value[ 2 ] ) {
-
-/* If a seconds field is present, the suggested value will lie within
- its normal range, so use a special gap value. */
- if ( sec ) {
- field = 3;
-
-/* If the least significant field is degrees/hours or minutes, then
- only digits after the decimal point can be affected, so use a
- decimal gap value. */
- } else if ( min ) {
- field = 2;
- decimal = 1;
- } else {
- field = 1;
- decimal = 1;
- }
-
-/* Suggested values less than one second. */
-/* -------------------------------------- */
- } else {
-
-/* Only digits after the decimal point can be affected, so decide
- which is the least significant field present and use a decimal
- gap. */
- if ( sec ) {
- field = 3;
- } else if ( min ) {
- field = 2;
- } else {
- field = 1;
- }
- decimal = 1;
- }
-
-/* If a decimal gap value is required, select the appropriate table of
- gap values and numbers of subdivisions. */
- if ( decimal ) {
- table = dec_table;
- nticks = dec_nticks;
-
-/* Find a power of ten divisor which scales the suggested value (when
- formatted) into the range 1.0 to 10.0. */
- scale = pow( 10.0,
- floor( log10( gap / field_value[ field - 1 ] ) ) );
-
-/* Look the scaled value up in the table, comparing values in radians
- to avoid rounding problems due to conversion to/from
- degrees/radians, etc. */
- for ( i = 0; table[ i + 1 ] > 0.0; i++ ) {
-
-/* We must be careful about rounding errors here. If, for example, we
- read in a value of 0.15 as the suggested gap value, the scaled
- "nice" value we would be comparing it with would be 0.1 times the
- values in the nice values table. The relevant value in this table
- is 1.5 (i.e. 0.5 * ( 1.0 + 2.0 ) ), so we would compute 0.1 * 1.5
- as the test value. However, this is probably not equal (to machine
- precision) to the number that results when a formatted value of
- 0.15 is read, because 0.1 isn't exactly representable. Since it is
- the formatted appearance of the numbers which matters, we want a
- new scaled nice table containing the numbers that result from
- reading the formatted values 0.1, 0.2, etc. To achieve this effect,
- we format the scaled table value using the default floating point
- precision (which rounds to a relatively small number of decimal
- digits) and then read the value back again. */
- (void ) sprintf( buff, "%g", scale *
- 0.5 * ( table[ i ] + table[ i + 1 ] ) );
- (void) astSscanf( buff, "%lf", &scaled_table_value );
-
-/* Now test the suggested gap value against the scaled table value. */
- if ( gap < ( field_value[ field - 1 ] *
- scaled_table_value ) ) break;
- }
-
-/* Return the nice gap value and the number of subdivisions. */
- gap = scale * field_value[ field - 1 ] * table[ i ];
- if ( ntick ) *ntick = nticks[ i ];
-
-/* If a special gap value appropriate to the field is required, then
- select the table of gap values and numbers of subdivisions
- according to which field we are considering and whether it contains
- degrees or hours. */
- } else {
- if ( field == 1 ) {
- if ( as_time ) {
- table = hr_table;
- nticks = hr_nticks;
- } else {
- table = deg_table;
- nticks = deg_nticks;
- }
- } else {
- table = minsec_table;
- nticks = minsec_nticks;
- }
-
-/* Search the table for a suitable gap. We do not need to format and
- unformat the test value here (as we did above) because the table
- values are being used literally and not being scaled. */
- for ( i = 0; table[ i + 1 ] > 0.0; i++ ) {
- if ( gap < ( field_value[ field - 1 ] *
- 0.5 * ( table[ i ] + table[ i + 1 ] ) ) ) break;
- }
-
-/* Return the nice gap value and the number of subdivisions. */
- gap = field_value[ field - 1 ] * table[ i ];
- if ( ntick ) *ntick = nticks[ i ];
- }
- }
-
-/* After iterations are complete, restore the original sign. */
- if ( !positive ) gap = -gap;
- }
- }
-
-/* If an error occurred, clear the returned value. */
- if ( !astOK ) gap = 0.0;
-
-/* Return the result. */
- return gap;
-
-/* Undefine macros local to this function */
-#undef BUFF_LEN
-}
-
-static const char *DHmsUnit( const char *fmt, int digs, int output, int *status ) {
-/*
-* Name:
-* DHmsUnit
-
-* Purpose:
-* Generate a unit string to describe a formatted angle or time.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* const char *DHmsUnit( const char *fmt, int digs, int output, int *status )
-
-* Class Membership:
-* SkyAxis member function.
-
-* Description:
-* This function generates a string that may be used to describe
-* either (a) the units of an angle or time that has been formatted
-* for output using the DHmsFormat function, or (b) a suitable
-* format to be used for an angle or time that is to be supplied as
-* an input coordinate value.
-
-* Parameters:
-* fmt
-* Pointer to a null terminated string containing the format
-* specifier used to format coordinate values. For details of
-* the syntax of this string, see the DHmsFormat function.
-* digs
-* The default number of digits of precision to use. This is used
-* if the given format specifier indicates the number of decimal
-* places to use with the string ".*". In this case, the number of
-* decimal places produced will be chosen so that the total number
-* of digits of precision is equal to "digs".
-* output
-* If non-zero, the returned string will be in a form suitable
-* for describing the units/format of output produced using
-* DHmsFormat.
-*
-* If zero, the returned string will be in a form suitable for
-* describing a suggested input format, which will subsequently
-* be read using AxisUnformat.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Pointer to a null terminated string containing the unit description.
-
-* Notes:
-* - The result string may be stored in static memory. Its contents
-* may be over-written or the returned pointer may become invalid
-* following a further invocation of this function. A copy of the
-* string should therefore be made if necessary.
-* - A NULL pointer will be returned if this function is invoked
-* with the global error status set, or if it should fail for any
-* reason.
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Pointer to thread-specific global data */
- char dpchar; /* Character to indicate decimal places */
- char sep; /* Field separator character */
- const char *result; /* Pointer to result string */
- const int maxdp = 6; /* Maximum number of decimal places to show */
- int as_time; /* Value formatted as a time? */
- int dh; /* Degrees/hours field required? */
- int dp; /* Loop counter for decimal places */
- int lead_zero; /* Add leading zeros? */
- int min; /* Minutes field required? */
- int ndp; /* Number of decimal places */
- int plus; /* Leading plus sign required? */
- int pos; /* Position to add next character */
- int sec; /* Seconds field required? */
-
-/* Initialise. */
- result = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Get a pointer to the thread specific global data structure. */
- astGET_GLOBALS(NULL);
-
-/* Parse the format specifier. */
- ParseDHmsFormat( fmt, digs, &sep, &plus, &lead_zero, &as_time, &dh, &min,
- &sec, &ndp, status );
-
-/* If the units string is required to describe formatted output and
- the field separators are letters (e.g. giving "01h23m45s" or
- "012d34m56s"), then the units will already be clear so return a
- pointer to an empty units string. */
- if ( astOK ) {
- if ( output && ( sep == 'l' || sep == 'g' ) ) {
- result = "";
-
-/* Otherwise, if the units string is required to describe formatted
- output and there is only one field present, then select an
- appropriate string. */
- } else if ( output && dh && !min && !sec ) {
- result = as_time ? "hours" : "degrees";
-
- } else if ( output && !dh && min && !sec ) {
- result = as_time ? "minutes of time" : "arcminutes";
-
- } else if ( output && !dh && !min && sec ) {
- result = as_time ? "seconds of time" : "arcseconds";
-
-/* If there is more than one field present, or we want to describe how
- to supply formatted input, then we will generate a units string of
- the general form "ddd:mm:ss.sss" or "hh:mm:ss.s" or
- similar. Initialise the output character count and the character to
- be used to represent decimal places. */
- } else {
- pos = 0;
- dpchar = 'd';
-
-/* Decide which field separator to use (use a space if letters were
- requested since it is easier to input). */
- if ( sep == 'l' || sep == 'g' ) sep = ' ';
-
-/* Start with the "ddd" or "hh" field, if required, and update the
- decimal places character appropriately. */
- if ( dh ) {
- pos += sprintf( dhmsunit_buff, "%s", as_time ? "hh" : "ddd" );
- dpchar = as_time ? 'h' : 'd';
- }
-
-/* If a minutes field is present, add a separator if necessary and
- "mm" and update the decimal places character. */
- if ( min ) {
- if ( dh ) dhmsunit_buff[ pos++ ] = sep;
- dhmsunit_buff[ pos++ ] = 'm';
- dhmsunit_buff[ pos++ ] = 'm';
- dpchar = 'm';
- }
-
-/* Repeat this process for the seconds field, if present. */
- if ( sec ) {
- if ( dh || min ) dhmsunit_buff[ pos++ ] = sep;
- dhmsunit_buff[ pos++ ] = 's';
- dhmsunit_buff[ pos++ ] = 's';
- dpchar = 's';
- }
-
-/* If decimal places are present, add a decimal point and then loop to
- add further instances of the decimal places character to represent
- the digits that follow. */
- if ( ndp > 0 ) {
- dhmsunit_buff[ pos++ ] = '.';
- for ( dp = 0; dp < ndp; dp++ ) {
- if ( dp < maxdp ) {
- dhmsunit_buff[ pos++ ] = dpchar;
-
-/* After showing the maximum number of decimal places, simply add an
- ellipsis and quit (otherwise the result gets boring to look at). */
- } else {
- dhmsunit_buff[ pos - 1 ] = '.';
- dhmsunit_buff[ pos - 2 ] = '.';
- dhmsunit_buff[ pos - 3 ] = '.';
- break;
- }
- }
- }
-
-/* Terminate the result string and return a pointer to it. */
- dhmsunit_buff[ pos ] = '\0';
- result = dhmsunit_buff;
- }
- }
-
-/* Return the result. */
- return result;
-}
-
-static int GetObjSize( AstObject *this_object, int *status ) {
-/*
-* Name:
-* GetObjSize
-
-* Purpose:
-* Return the in-memory size of an Object.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* int GetObjSize( AstObject *this, int *status )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astGetObjSize protected
-* method inherited from the parent class).
-
-* Description:
-* This function returns the in-memory size of the supplied SkyAxis,
-* in bytes.
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The Object size, in bytes.
-
-* Notes:
-* - A value of zero will be returned if this function is invoked
-* with the global status set, or if it should fail for any reason.
-*/
-
-/* Local Variables: */
- AstSkyAxis *this; /* Pointer to SkyAxis structure */
- int result; /* Result value to return */
-
-/* Initialise. */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointers to the SkyAxis structure. */
- this = (AstSkyAxis *) this_object;
-
-/* Invoke the GetObjSize method inherited from the parent class, and then
- add on any components of the class structure defined by thsi class
- which are stored in dynamically allocated memory. */
- result = (*parent_getobjsize)( this_object, status );
- result += astTSizeOf( this->skyformat );
-
-/* If an error occurred, clear the result value. */
- if ( !astOK ) result = 0;
-
-/* Return the result, */
- return result;
-}
-
-static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) {
-/*
-* Name:
-* GetAttrib
-
-* Purpose:
-* Get the value of a specified attribute for a SkyAxis.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* const char *GetAttrib( AstObject *this, const char *attrib, int *status )
-
-* Class Membership:
-* SkyAxis member function (over-rides the protected astGetAttrib
-* method inherited from the Axis class).
-
-* Description:
-* This function returns a pointer to the value of a specified
-* attribute for a SkyAxis, formatted as a character string.
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* attrib
-* Pointer to a null-terminated string containing the name of
-* the attribute whose value is required. This name should be in
-* lower case, with all white space removed.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* - Pointer to a null-terminated string containing the attribute
-* value.
-
-* Notes:
-* - The returned string pointer may point at memory allocated
-* within the SkyAxis, or at static memory. The contents of the
-* string may be over-written or the pointer may become invalid
-* following a further invocation of the same function or any
-* modification of the SkyAxis. A copy of the string should
-* therefore be made if necessary.
-* - A NULL pointer will be returned if this function is invoked
-* with the global error status set, or if it should fail for any
-* reason.
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Pointer to thread-specific global data */
- AstSkyAxis *this; /* Pointer to the SkyAxis structure */
- const char *result; /* Pointer value to return */
- int as_time; /* AsTime attribute value */
- int centrezero; /* CentreZero attribute value */
- int is_latitude; /* IsLatitude attribute value */
-
-/* Initialise. */
- result = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Get a pointer to the thread specific global data structure. */
- astGET_GLOBALS(this_object);
-
-/* Obtain a pointer to the SkyAxis structure. */
- this = (AstSkyAxis *) this_object;
-
-/* Compare "attrib" with each recognised attribute name in turn,
- obtaining the value of the required attribute. If necessary, write
- the value into "getattrib_buff" as a null-terminated string in an appropriate
- format. Set "result" to point at the result string. */
-
-/* AsTime. */
-/* ------- */
- if ( !strcmp( attrib, "astime" ) ) {
- as_time = astGetAxisAsTime( this );
- if ( astOK ) {
- (void) sprintf( getattrib_buff, "%d", as_time );
- result = getattrib_buff;
- }
-
-/* IsLatitude. */
-/* ----------- */
- } else if ( !strcmp( attrib, "islatitude" ) ) {
- is_latitude = astGetAxisIsLatitude( this );
- if ( astOK ) {
- (void) sprintf( getattrib_buff, "%d", is_latitude );
- result = getattrib_buff;
- }
-
-/* CentreZero. */
-/* ----------- */
- } else if ( !strcmp( attrib, "centrezero" ) ) {
- centrezero= astGetAxisCentreZero( this );
- if ( astOK ) {
- (void) sprintf( getattrib_buff, "%d", centrezero );
- result = getattrib_buff;
- }
-
-/* If the attribute name was not recognised, pass it on to the parent
- method for further interpretation. */
- } else {
- result = (*parent_getattrib)( this_object, attrib, status );
- }
-
-/* Return the result. */
- return result;
-}
-
-static double GetAxisBottom( AstAxis *this_axis, int *status ) {
-/*
-* Name:
-* GetAxisBottom
-
-* Purpose:
-* Obtain the value of the Bottom attribute for a SkyAxis.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* double GetAxisBottom( AstAxis *this, int *status )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astGetAxisBottom method
-* inherited from the Axis class).
-
-* Description:
-* This function returns a value for the Bottom attribute of a SkyAxis.
-* This attribute indicates the lowest legal value for the axis.
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The atribute value. A suitable default value is supplied if necessary.
-
-* Notes:
-* - A value of -DBL_MAX will be returned if this function is invoked
-* with the global error status set, or if it should fail for any reason.
-*/
-
-/* Local Variables. */
- AstSkyAxis *this; /* Pointer to the SkyAxis structure */
- double result; /* Result to be returned */
-
-/* Check the global error status. */
- if ( !astOK ) return -DBL_MAX;
-
-/* Obtain a pointer to the SkyAxis structure. */
- this = (AstSkyAxis *) this_axis;
-
-/* Check if a value has been set for the Bottom attribute. If so, obtain
- this value. */
- if ( astTestAxisBottom( this ) ) {
- result = (*parent_getaxisbottom)( this_axis, status );
-
-/* Otherwise, supply a default of -pi/2 for latitude axes, and -DBL_MAX
- for longitude axes. */
- } else {
- result = astGetAxisIsLatitude( this ) ? -piby2 : -DBL_MAX;
- }
-
-/* If an error occurred, clear the result value. */
- if ( !astOK ) result = -DBL_MAX;
-
-/* Return the result. */
- return result;
-}
-
-static const char *GetAxisInternalUnit( AstAxis *this, int *status ){
-/*
-* Name:
-* GetAxisInternalUnit
-
-* Purpose:
-* Return the unit string for unformatted Axis values
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "axis.h"
-* const char *GetAxisInternalUnit( AstAxis *this )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astGetAxisInternalUnit method
-* inherited from the Axis class).
-
-* Description:
-* This function returns the axis InternalUnit attribute. For sky
-* axes, the InternalUnit is always "rad" (radians).
-
-* Parameters:
-* this
-* Pointer to the Axis.
-
-* Returned Value:
-* - Pointer to a null-terminated string containing the internal
-* unit string.
-
-* Notes:
-* - The returned pointer points to a static memory buffer. The
-* contents of this buffer will be over-written on each invocation of
-* this function. A copy of the returned string should therefore be
-* taken if it will be needed later.
-* - A NULL pointer will be returned if this function is invoked
-* with the global error status set, or if it should fail for any
-* reason.
-*/
- return "rad";
-}
-
-static double GetAxisTop( AstAxis *this_axis, int *status ) {
-/*
-* Name:
-* GetAxisTop
-
-* Purpose:
-* Obtain the value of the Top attribute for a SkyAxis.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* double GetAxisTop( AstAxis *this, int *status )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astGetAxisTop method
-* inherited from the Axis class).
-
-* Description:
-* This function returns a value for the Top attribute of a SkyAxis.
-* This attribute indicates the highest legal value for the axis.
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The atribute value. A suitable default value is supplied if necessary.
-
-* Notes:
-* - A value of DBL_MAX will be returned if this function is invoked
-* with the global error status set, or if it should fail for any reason.
-*/
-
-/* Local Variables. */
- AstSkyAxis *this; /* Pointer to the SkyAxis structure */
- double result; /* Result to be returned */
-
-/* Check the global error status. */
- if ( !astOK ) return DBL_MAX;
-
-/* Obtain a pointer to the SkyAxis structure. */
- this = (AstSkyAxis *) this_axis;
-
-/* Check if a value has been set for the Top attribute. If so, obtain
- this value. */
- if ( astTestAxisTop( this ) ) {
- result = (*parent_getaxistop)( this_axis, status );
-
-/* Otherwise, supply a default of pi/2 for latitude axes, and DBL_MAX
- for longitude axes. */
- } else {
- result = astGetAxisIsLatitude( this ) ? piby2 : DBL_MAX;
- }
-
-/* If an error occurred, clear the result value. */
- if ( !astOK ) result = DBL_MAX;
-
-/* Return the result. */
- return result;
-}
-
-static int GetAxisDirection( AstAxis *this_axis, int *status ) {
-/*
-* Name:
-* GetAxisDirection
-
-* Purpose:
-* Obtain the value of the Direction attribute for a SkyAxis.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* int GetAxisDirection( AstAxis *this, int *status )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astGetAxisDirection method
-* inherited from the Axis class).
-
-* Description:
-* This function returns a value for the Direction attribute of a SkyAxis.
-* This attribute indicates in which direction the SkyAxis's values should
-* increase when represented on a graph (1 for the conventional direction,
-* 0 for reverse direction).
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Zero or one, according to the attribute setting. A suitable default
-* value is supplied if necessary.
-
-* Notes:
-* - A value of zero will be returned if this function is invoked with the
-* global error status set, or if it should fail for any reason.
-*/
-
-/* Local Variables. */
- AstSkyAxis *this; /* Pointer to the SkyAxis structure */
- int result; /* Result to be returned */
-
-/* Check the global error status. */
- if ( !astOK ) return 0;
-
-/* Obtain a pointer to the SkyAxis structure. */
- this = (AstSkyAxis *) this_axis;
-
-/* Check if a value has been set for the Direction attribute. If so, obtain
- this value. */
- if ( astTestAxisDirection( this ) ) {
- result = (*parent_getaxisdirection)( this_axis, status );
-
-/* Otherwise, supply a default of 1 unless the SkyAxis values are being
- formatted as times (instead of angles) by default. */
- } else {
- result = !astGetAxisAsTime( this );
- }
-
-/* If an error occurred, clear the result value. */
- if ( !astOK ) result = 0;
-
-/* Return the result. */
- return result;
-}
-
-static const char *GetAxisFormat( AstAxis *this_axis, int *status ) {
-/*
-* Name:
-* GetAxisFormat
-
-* Purpose:
-* Obtain a pointer to the Format attribute for a SkyAxis.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* const char *GetAxisFormat( AstAxis *this, int *status )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astGetAxisFormat method inherited
-* from the Axis class).
-
-* Description:
-* This function returns a pointer to the Format attribute associated with
-* a SkyAxis and provides a suitable default if necessary. This string
-* attribute contains the format specifier that will be interpreted by the
-* astAxisFormat method when formatting a value for the SkyAxis. The default
-* Format may depend on other attribute settings, in particular on the
-* Digits and AsTime attributes.
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Pointer to the Format string (null terminated).
-
-* Notes:
-* - The pointer returned may point at memory allocated within the SkyAxis
-* object, or at static memory. The contents of the string may be
-* over-written or the pointer may become invalid following a further
-* invocation of the same function, deletion of the SkyAxis, or assignment
-* of a new Format value. A copy of the string should therefore be made if
-* necessary.
-* - This function will return a NULL pointer if it is invoked with the
-* global error status set, or if it should fail for any reason.
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Pointer to thread-specific global data */
- AstSkyAxis *this; /* Pointer to the SkyAxis structure */
- const char *result; /* Pointer to result string */
- int as_time; /* Format SkyAxis values as times? */
- int digits; /* Number of digits of precision */
-
-/* Check the global error status. */
- if ( !astOK ) return NULL;
-
-/* Get a pointer to the thread specific global data structure. */
- astGET_GLOBALS(this_axis);
-
-/* Initialise. */
- result = NULL;
-
-/* Obtain a pointer to the SkyAxis structure. */
- this = (AstSkyAxis *) this_axis;
-
-/* Obtain a pointer to the Format string stored in the SkyAxis structure. Note
- we do not use a method to obtain this, because we want a string with a
- syntax appropriate to this class, and derived classes may have extended the
- syntax. */
- result = this->skyformat;
-
-/* If no Format string has been set, we must generate a default one. Determine
- how many digits of precision are to be used by default and whether the
- SkyAxis values are to be formatted as times (instead of angles). */
- if ( !result ) {
- digits = astGetAxisDigits( this );
- as_time = astGetAxisAsTime( this );
- if ( astOK ) {
-
-/* If formatting values as times, use the number of digits to select an
- appropriate Format string and obtain a pointer to it. */
- if ( as_time ) {
- if ( digits <= 2 ) {
- result = "h";
- } else if ( digits == 3 ) {
- result = "hm";
- } else if ( digits == 4 ) {
- result = "hm";
- } else if ( digits == 5 ) {
- result = "hms";
- } else if ( digits == 6 ) {
- result = "hms";
-
-/* Construct the Format string in a buffer if necessary. */
- } else {
- (void) sprintf( getaxisformat_buff, "hms.%d", digits - 6 );
- result = getaxisformat_buff;
- }
-
-/* Similarly, select a Format for expressing an angle if necessary. */
- } else {
- if ( digits <= 3 ) {
- result = "d";
- } else if ( digits == 4 ) {
- result = "dm";
- } else if ( digits == 5 ) {
- result = "dm";
- } else if ( digits == 6 ) {
- result = "dms";
- } else if ( digits == 7 ) {
- result = "dms";
- } else {
- (void) sprintf( getaxisformat_buff, "dms.%d", digits - 7 );
- result = getaxisformat_buff;
- }
- }
- }
- }
-
-/* Return the result. */
- return result;
-}
-
-static const char *GetAxisLabel( AstAxis *this_axis, int *status ) {
-/*
-* Name:
-* GetAxisLabel
-
-* Purpose:
-* Obtain a pointer to the Label attribute for a SkyAxis.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* const char *GetAxisLabel( AstAxis *this, int *status )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astGetAxisLabel method inherited
-* from the Axis class).
-
-* Description:
-* This function returns a pointer to the Label attribute associated with
-* a SkyAxis and provides a suitable default if necessary. This string
-* attribute specifies the label to be attached to the SkyAxis when it is
-* represented in (e.g.) a graph. It is intended purely for interpretation
-* by human readers and not by software.
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Pointer to the Label string (null terminated).
-
-* Notes:
-* - The pointer returned may point at memory allocated within the SkyAxis
-* object, or at static memory. The contents of the string may be
-* over-written or the pointer may become invalid following a further
-* invocation of the same function, deletion of the SkyAxis, or assignment
-* of a new Label value. A copy of the string should therefore be made if
-* necessary.
-* - This function will return a NULL pointer if it is invoked with the
-* global error status set, or if it should fail for any reason.
-*/
-
-/* Local Variables: */
- AstSkyAxis *this; /* Pointer to the SkyAxis structure */
- const char *result; /* Pointer value to be returned */
- int as_time; /* SkyAxis values formatted as times? */
-
-/* Check the global error status. */
- if ( !astOK ) return NULL;
-
-/* Initialise. */
- result = NULL;
-
-/* Obtain a pointer to the SkyAxis structure. */
- this = (AstSkyAxis *) this_axis;
-
-/* Test if the Label attribute is set. If so, use the parent astGetAxisLabel
- method to get a pointer to it. */
- if ( astTestAxisLabel( this ) ) {
- result = (*parent_getaxislabel)( this_axis, status );
-
-/* Otherwise, return a pointer to a suitable default string, using the result
- of the astGetAxisAsTime method to determine whether a string describing
- time or angle is more appropriate. */
- } else {
- as_time = astGetAxisAsTime( this );
- if ( !astTestAxisIsLatitude( this ) ) {
- result = as_time ? "Angle on sky expressed as time" :
- "Angle on sky";
- } else if ( astGetAxisIsLatitude( this ) ) {
- result = as_time ? "Sky latitude expressed as time" :
- "Sky latitude";
- } else {
- result = as_time ? "Sky longitude expressed as time" :
- "Sky longitude";
- }
- }
-
-/* If an error occurred, clear the result pointer. */
- if ( !astOK ) result = NULL;
-
-/* Return the result. */
- return result;
-}
-
-static const char *GetAxisSymbol( AstAxis *this_axis, int *status ) {
-/*
-* Name:
-* GetAxisSymbol
-
-* Purpose:
-* Obtain a pointer to the Symbol attribute for a SkyAxis.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* const char *GetAxisSymbol( AstAxis *this, int *status )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astGetAxisSymbol method inherited
-* from the Axis class).
-
-* Description:
-* This function returns a pointer to the Symbol attribute associated with
-* a SkyAxis and provides a suitable default if necessary. This string
-* attribute specifies the symbol to be used to represent coordinate values
-* for the SkyAxis in "short form", such as in algebraic expressions where a
-* full description would be inappropriate.
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Pointer to the Symbol string (null terminated).
-
-* Notes:
-* - The pointer returned may point at memory allocated within the SkyAxis
-* object, or at static memory. The contents of the string may be
-* over-written or the pointer may become invalid following a further
-* invocation of the same function, deletion of the SkyAxis, or assignment
-* of a new Symbol value. A copy of the string should therefore be made if
-* necessary.
-* - This function will return a NULL pointer if it is invoked with the
-* global error status set, or if it should fail for any reason.
-*/
-
-/* Local Variables: */
- AstSkyAxis *this; /* Pointer to the SkyAxis structure */
- const char *result; /* Pointer value to return */
-
-/* Check the global error status. */
- if ( !astOK ) return NULL;
-
-/* Initialise. */
- result = NULL;
-
-/* Obtain a pointer to the SkyAxis structure. */
- this = (AstSkyAxis *) this_axis;
-
-/* Test if the Symbol attribute is set. If so, use the parent astGetAxisSymbol
- method to get a pointer to it. */
- if ( astTestAxisSymbol( this ) ) {
- result = (*parent_getaxissymbol)( this_axis, status );
-
-/* If a value has been set for the IsLatitude attribute, use it to decide
- whether to use "delta" (for latitude) or "alpha" (for longitude). */
- } else if ( astTestAxisIsLatitude( this ) ) {
- result = astGetAxisIsLatitude( this ) ? "delta" : "alpha";
-
-/* Otherwise, use the AsTime attribute to decide whether the SkyAxis is
- likely to be a longitude or latitude axis (the former usually having values
- formatted as times). */
- } else {
- result = astGetAxisAsTime( this ) ? "alpha" : "delta";
- }
-
-/* If an error occurred, clear the result pointer. */
- if ( !astOK ) result = NULL;
-
-/* Return the result. */
- return result;
-}
-
-static const char *GetAxisUnit( AstAxis *this_axis, int *status ) {
-/*
-* Name:
-* GetAxisUnit
-
-* Purpose:
-* Obtain a pointer to the Unit attribute for a SkyAxis.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* const char *GetAxisUnit( AstAxis *this, int *status )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astGetAxisUnit method inherited
-* from the Axis class).
-
-* Description:
-* This function returns a pointer to the Unit attribute associated with
-* a SkyAxis and provides a suitable default if necessary. This string
-* attribute describes the unit used to represent formatted coordinate
-* values on the SkyAxis.
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Pointer to the Unit string (null terminated).
-
-* Notes:
-* - The pointer returned may point at memory allocated within the SkyAxis
-* object, or at static memory. The contents of the string may be
-* over-written or the pointer may become invalid following a further
-* invocation of the same function, deletion of the SkyAxis, or assignment
-* of a new Unit value. A copy of the string should therefore be made if
-* necessary.
-* - This function will return a NULL pointer if it is invoked with the
-* global error status set, or if it should fail for any reason.
-*/
-
-/* Local Variables: */
- AstSkyAxis *this; /* Pointer to the SkyAxis structure */
- const char *fmt; /* Pointer to format specifier */
- const char *result; /* Pointer to result string */
-
-/* Check the global error status. */
- if ( !astOK ) return NULL;
-
-/* Initialise */
- result = NULL;
-
-/* Obtain a pointer to the SkyAxis structure. */
- this = (AstSkyAxis *) this_axis;
-
-/* Test if the Unit attribute is set. If so, invoke the parent astGetAxisUnit
- method to obtain a pointer to it. */
- if ( astTestAxisUnit( this ) ) {
- result = (*parent_getaxisunit)( this_axis, status );
-
-/* If we must provide a default, obtain a pointer to the format specifier used
- to format SkyAxis values. Use a private member function (not a method) to
- access this, in case derived classes have extended the syntax of this
- string. */
- } else {
- fmt = GetAxisFormat( this_axis, status );
-
-/* If the format string starts with a percent, use "rad" as the default units
- string. Otherwise, use the format specifier to generate a matching
- default Unit string and obtain a pointer to it. */
- if ( astOK ) {
- if( fmt[ 0 ] == '%' ) {
- result = "rad";
- } else {
- result = DHmsUnit( fmt, astGetAxisDigits( this_axis ), 1, status );
- }
- }
- }
-
-/* Return the result. */
- return result;
-}
-
-void astInitSkyAxisVtab_( AstSkyAxisVtab *vtab, const char *name, int *status ) {
-/*
-*+
-* Name:
-* astInitSkyAxisVtab
-
-* Purpose:
-* Initialise a virtual function table for a SkyAxis.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* void astInitSkyAxisVtab( AstSkyAxisVtab *vtab, const char *name )
-
-* Class Membership:
-* SkyAxis vtab initialiser.
-
-* Description:
-* This function initialises the component of a virtual function
-* table which is used by the SkyAxis class.
-
-* Parameters:
-* vtab
-* Pointer to the virtual function table. The components used by
-* all ancestral classes will be initialised if they have not already
-* been initialised.
-* name
-* Pointer to a constant null-terminated character string which contains
-* the name of the class to which the virtual function table belongs (it
-* is this pointer value that will subsequently be returned by the Object
-* astClass function).
-*-
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Pointer to thread-specific global data */
- AstAxisVtab *axis; /* Pointer to Axis component of Vtab */
- AstObjectVtab *object; /* Pointer to Object component of Vtab */
- int stat; /* SLALIB status */
-
-/* Check the local error status. */
- if ( !astOK ) return;
-
-/* Get a pointer to the thread specific global data structure. */
- astGET_GLOBALS(NULL);
-
-/* Initialize the component of the virtual function table used by the
- parent class. */
- astInitAxisVtab( (AstAxisVtab *) vtab, name );
-
-/* Store a unique "magic" value in the virtual function table. This
- will be used (by astIsASkyAxis) to determine if an object belongs
- to this class. We can conveniently use the address of the (static)
- class_check variable to generate this unique value. */
- vtab->id.check = &class_check;
- vtab->id.parent = &(((AstAxisVtab *) vtab)->id);
-
-/* Initialise member function pointers. */
-/* ------------------------------------ */
-/* Store pointers to the member functions (implemented here) that provide
- virtual methods for this class. */
- vtab->ClearAxisAsTime = ClearAxisAsTime;
- vtab->ClearAxisIsLatitude = ClearAxisIsLatitude;
- vtab->ClearAxisCentreZero = ClearAxisCentreZero;
- vtab->GetAxisAsTime = GetAxisAsTime;
- vtab->GetAxisIsLatitude = GetAxisIsLatitude;
- vtab->GetAxisCentreZero = GetAxisCentreZero;
- vtab->SetAxisAsTime = SetAxisAsTime;
- vtab->SetAxisIsLatitude = SetAxisIsLatitude;
- vtab->SetAxisCentreZero = SetAxisCentreZero;
- vtab->TestAxisAsTime = TestAxisAsTime;
- vtab->TestAxisIsLatitude = TestAxisIsLatitude;
- vtab->TestAxisCentreZero = TestAxisCentreZero;
-
-/* Save the inherited pointers to methods that will be extended, and
- replace them with pointers to the new member functions. */
- object = (AstObjectVtab *) vtab;
- axis = (AstAxisVtab *) vtab;
- parent_getobjsize = object->GetObjSize;
- object->GetObjSize = GetObjSize;
-
- parent_clearattrib = object->ClearAttrib;
- object->ClearAttrib = ClearAttrib;
- parent_getattrib = object->GetAttrib;
- object->GetAttrib = GetAttrib;
- parent_setattrib = object->SetAttrib;
- object->SetAttrib = SetAttrib;
- parent_testattrib = object->TestAttrib;
- object->TestAttrib = TestAttrib;
-
- parent_axisoverlay = axis->AxisOverlay;
- axis->AxisOverlay = AxisOverlay;
- parent_getaxisdirection = axis->GetAxisDirection;
- axis->GetAxisDirection = GetAxisDirection;
- parent_getaxislabel = axis->GetAxisLabel;
- axis->GetAxisLabel = GetAxisLabel;
- parent_getaxissymbol = axis->GetAxisSymbol;
- axis->GetAxisSymbol = GetAxisSymbol;
- parent_getaxisunit = axis->GetAxisUnit;
- axis->GetAxisUnit = GetAxisUnit;
-
- parent_getaxistop = axis->GetAxisTop;
- axis->GetAxisTop = GetAxisTop;
-
- parent_getaxisbottom = axis->GetAxisBottom;
- axis->GetAxisBottom = GetAxisBottom;
-
- parent_axisformat = axis->AxisFormat;
- axis->AxisFormat = AxisFormat;
-
- parent_axisunformat = axis->AxisUnformat;
- axis->AxisUnformat = AxisUnformat;
-
- parent_axisgap = axis->AxisGap;
- axis->AxisGap = AxisGap;
-
- parent_axisfields = axis->AxisFields;
- axis->AxisFields = AxisFields;
-
-/* Store replacement pointers for methods which will be over-ridden by
- new member functions implemented here. */
- axis->AxisAbbrev = AxisAbbrev;
- axis->AxisIn = AxisIn;
- axis->AxisDistance = AxisDistance;
- axis->AxisOffset = AxisOffset;
- axis->AxisNorm = AxisNorm;
- axis->AxisNormValues = AxisNormValues;
- axis->ClearAxisFormat = ClearAxisFormat;
- axis->GetAxisFormat = GetAxisFormat;
- axis->SetAxisFormat = SetAxisFormat;
- axis->TestAxisFormat = TestAxisFormat;
- axis->GetAxisInternalUnit = GetAxisInternalUnit;
- axis->TestAxisInternalUnit = TestAxisInternalUnit;
-
-/* Declare the destructor, copy constructor and dump function. */
- astSetDelete( vtab, Delete );
- astSetCopy( vtab, Copy );
- astSetDump( vtab, Dump, "SkyAxis", "Celestial coordinate axis" );
-
-/* Initialize constants for converting between hours, degrees and radians. */
- LOCK_MUTEX2
- palDtf2r( 1, 0, 0.0, &hr2rad, &stat );
- palDaf2r( 1, 0, 0.0, &deg2rad, &stat );
- palDaf2r( 180, 0, 0.0, &pi, &stat );
- piby2 = 0.5*pi;
- UNLOCK_MUTEX2
-
-/* If we have just initialised the vtab for the current class, indicate
- that the vtab is now initialised, and store a pointer to the class
- identifier in the base "object" level of the vtab. */
- if( vtab == &class_vtab ) {
- class_init = 1;
- astSetVtabClassIdentifier( vtab, &(vtab->id) );
- }
-}
-
-static void ParseDHmsFormat( const char *fmt, int digs, char *sep, int *plus,
- int *lead_zero, int *as_time, int *dh, int *min,
- int *sec, int *ndp, int *status ) {
-/*
-* Name:
-* ParseDHmsFormat
-
-* Purpose:
-* Parse a format specifier for degrees/hours, minutes and seconds.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* void ParseDHmsFormat( const char *fmt, int digs, char *sep, int *plus,
-* int *lead_zero, int *as_time, int *dh, int *min,
-* int *sec, int *ndp, int *status )
-
-* Class Membership:
-* SkyAxis member function.
-
-* Description:
-* This function parses a SkyAxis format specifier which describes
-* how to convert an angle in radians into a text string with
-* separate fields for degrees/hours, minutes and seconds.
-
-* Parameters:
-* fmt
-* Pointer to a null terminated string containing the format
-* specifier. For details of the syntax of this string, see the
-* DHmsFormat function.
-* digs
-* The default number of digits of precision to use. This is used
-* if the given format specifier indicates the number of decimal
-* places to use with the string ".*". In this case, the returned
-* value for "ndp" will be set to produce the number of digits of
-* precision given by "digs".
-* sep
-* Pointer to a location in which a single character will be
-* returned to indicate which separator should be used to
-* separate the fields. The returned value will be one of ' '
-* (use a blank as the separator), ':' (use a colon as the
-* separator) or 'l' (use one of the letters "hdms" as
-* appropriate) or 'g' (use one of the letters "hdms" but
-* include suitable escape sequences to allow the Plot class to draw
-* the letter as a small super-script).
-* plus
-* Pointer to an int in which a boolean value will be returned
-* to indicate if a plus sign should be prefixed to positive
-* values.
-* lead_zero
-* Pointer to an int in which a boolean value will be returned
-* to indicate if leading zeros should be prefixed to the value
-* so that the first field is always of constant (maximum)
-* width, as would be required in a fixed-width table. Leading
-* zeros are always prefixed to any fields that follow.
-* as_time
-* Pointer to an int in which a boolean value will be returned
-* to indicate whether the value is to be formatted as a time
-* (e.g. in hours) rather than as an angle (in degrees).
-* dh
-* Pointer to an int in which a boolean value will be returned
-* to indicate whether a degrees or hours field is required.
-* min
-* Pointer to an int in which a boolean value will be returned
-* to indicate whether a minutes field is required.
-* sec
-* Pointer to an int in which a boolean value will be returned
-* to indicate whether a seconds field is required.
-* ndp
-* Pointer to an int in which to return the number of digits
-* required following the decimal point in the final field. A
-* value of zero indicates that the decimal point should be
-* omitted. See parameter "digs".
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* void
-
-* Acknowledgements:
-* - This function is a close approximation to a Fortran 77 routine
-* written by Clive Davenhall which implements the system of format
-* specifiers for angles described in his document on the CAT
-* catalogue access library (Starlink User Note 181). It supports
-* the same format specifiers.
-*/
-
-/* Local Variables: */
- int decpos; /* Offset of decimal point */
- int i; /* Loop counter for format characters */
- int ndpval; /* Number of decimal places required */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Initialise. */
- *as_time = -1;
- *lead_zero = 0;
- *dh = 0;
- *min = 0;
- *ndp = 0;
- *plus = 0;
- *sec = 0;
- *sep = ':';
- decpos = -1;
-
-/* Loop to inspect and classify each character. */
- for ( i = 0; fmt[ i ]; i++ ) {
- switch ( fmt[ i ] ) {
-
-/* Note if a '+' sign is needed. */
- case '+':
- *plus = 1;
- break;
-
-/* Note if leading zeros are needed. */
- case 'Z': case 'z':
- *lead_zero = 1;
- break;
-
-/* Set the required separator. Note we only use graphical separators if
- astEscapes indicates that escape sequences are currently being used. */
- case 'I': case 'i':
- *sep = ':';
- break;
- case 'B': case 'b':
- *sep = ' ';
- break;
- case 'L': case 'l':
- *sep = 'l';
- break;
- case 'G': case 'g':
- *sep = astEscapes( -1 ) ? 'g' : 'l';
- break;
-
-/* Note if the value is to be formatted as a time (but not if a
- degrees or hours field has already been specified). */
- case 'T': case 't':
- if ( *as_time == -1 ) *as_time = 1;
- break;
-
-/* Note if a degrees or hours field is required (and hence whether the
- value is to be formatted as a time or an angle). */
- case 'H': case 'h':
- *dh = 1;
- *as_time = 1;
- break;
- case 'D': case 'd':
- *dh = 1;
- *as_time = 0;
- break;
-
-/* Note if a minutes field is required. */
- case 'M': case 'm':
- *min = 1;
- break;
-
-/* Note if a seconds field is required. */
- case 'S': case 's':
- *sec = 1;
- break;
-
-/* Note if decimal places are required. */
- case '.':
- decpos = i;
- }
- }
-
-/* Format the value as an angle by default. */
- if ( *as_time == -1 ) *as_time = 0;
-
-/* Use degrees (or hours) as the default field. */
- if ( !*min && !*sec ) *dh = 1;
-
-/* Omit the seconds field if the degrees/hours field is present but
- the minutes field is not. */
- if ( *dh && !*min ) *sec = 0;
-
-/* Determine the default number of decimal places following the final field.
- This is the number which will be used if the format specifier does not
- indicate how many decimal places should be produced. It is shosen to
- produce the requested total number of digits of precision. */
-
-/* If decimal places are required, attempt to read the integer value
- following the decimal point which specifies how many. If successful,
- and a valid (positive or zero) result was obtained, note its value. If
- an asterisk follows the decimal point, use a value determined by the
- supplied "digs" value. */
- if ( ( decpos >= 0 ) && ( decpos < ( i - 1 ) ) ) {
-
- if ( astSscanf( fmt + decpos + 1, "%d", &ndpval ) == 1 ) {
- if ( ndpval >= 0 ) *ndp = ndpval;
-
- } else if ( fmt[ decpos + 1 ] == '*' ) {
- *ndp = digs;
- if( *as_time ) {
- *ndp = ( digs > 2 ) ? digs : 2;
- if( *dh ) *ndp -= 2;
- } else {
- *ndp = ( digs > 3 ) ? digs : 3;
- if( *dh ) *ndp -= 3;
- }
- if( *min ) *ndp -= 2;
- if( *sec ) *ndp -= 2;
- if( *ndp < 0 ) *ndp = 0;
- }
- }
-}
-
-static void SetAttrib( AstObject *this_object, const char *setting, int *status ) {
-/*
-* Name:
-* SetAttrib
-
-* Purpose:
-* Set an attribute value for a SkyAxis.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* void SetAttrib( AstObject *this, const char *setting, int *status )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astSetAttrib method
-* inherited from the Axis class).
-
-* Description:
-* This function assigns an attribute value for a SkyAxis, the
-* attribute and its value being specified by means of a string of
-* the form:
-*
-* "attribute= value "
-*
-* Here, "attribute" specifies the attribute name and should be in
-* lower case with no white space present. The value to the right
-* of the "=" should be a suitable textual representation of the
-* value to be assigned and this will be interpreted according to
-* the attribute's data type. White space surrounding the value is
-* only significant for string attributes.
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* setting
-* Pointer to a null terminated string specifying the new
-* attribute value.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Local Variables: */
- AstSkyAxis *this; /* Pointer to the SkyAxis structure */
- int as_time; /* Format values as times? */
- int centrezero; /* SkyAxis range centred on zero? */
- int is_latitude; /* SkyAxis is a latitude axis? */
- int len; /* Length of setting string */
- int nc; /* Number of characters read by astSscanf */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the SkyAxis structure. */
- this = (AstSkyAxis *) this_object;
-
-/* Obtain the length of the setting string. */
- len = (int) strlen( setting );
-
-/* Test for each recognised attribute in turn, using "astSscanf" to parse
- the setting string and extract the attribute value (or an offset to
- it in the case of string values). In each case, use the value set
- in "nc" to check that the entire string was matched. Once a value
- has been obtained, use the appropriate method to set it. */
-
-/* AsTime. */
-/* ------- */
- if ( nc = 0,
- ( 1 == astSscanf( setting, "astime= %d %n", &as_time, &nc ) )
- && ( nc >= len ) ) {
- astSetAxisAsTime( this, as_time );
-
-/* IsLatitude. */
-/* ----------- */
- } else if ( nc = 0,
- ( 1 == astSscanf( setting, "islatitude= %d %n", &is_latitude, &nc ) )
- && ( nc >= len ) ) {
- astSetAxisIsLatitude( this, is_latitude );
-
-/* CentreZero. */
-/* ----------- */
- } else if ( nc = 0,
- ( 1 == astSscanf( setting, "centrezero= %d %n", &centrezero, &nc ) )
- && ( nc >= len ) ) {
- astSetAxisCentreZero( this, centrezero );
-
-/* Pass any unrecognised attribute setting to the parent method for further
- interpretation. */
- } else {
- (*parent_setattrib)( this_object, setting, status );
- }
-}
-
-static void SetAxisFormat( AstAxis *this_axis, const char *format, int *status ) {
-/*
-* Name:
-* SetAxisFormat
-
-* Purpose:
-* Set a value for the Format attribute of a SkyAxis.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* void SetAxisFormat( AstAxis *this, const char *format )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astSetAxisFormat method inherited
-* from the Axis class).
-
-* Description:
-* This function sets a new value for the Format attribute of a SkyAxis.
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* format
-* Pointer to a null terminated string containing the new Format value.
-
-* Returned Value:
-* void
-
-* Notes:
-* - For details of the syntax of the Format string, see the DHmsFormat
-* function.
-*/
-
-/* Local Variables: */
- AstSkyAxis *this; /* Pointer to the SkyAxis structure */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the SkyAxis structure. */
- this = (AstSkyAxis *) this_axis;
-
-/* Store a pointer to a copy of the Format string in the SkyAxis structure. */
- this->skyformat = astStore( this->skyformat, format,
- strlen( format ) + (size_t) 1 );
-}
-
-static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) {
-/*
-* Name:
-* TestAttrib
-
-* Purpose:
-* Test if a specified attribute value is set for a SkyAxis.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* int TestAttrib( AstObject *this, const char *attrib, int *status )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astTestAttrib protected
-* method inherited from the Axis class).
-
-* Description:
-* This function returns a boolean result (0 or 1) to indicate
-* whether a value has been set for one of a SkyAxis' attributes.
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* attrib
-* Pointer to a null-terminated string specifying the attribute
-* name. This should be in lower case with no surrounding white
-* space.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* One if a value has been set, otherwise zero.
-
-* Notes:
-* - A value of zero will be returned if this function is invoked
-* with the global status set, or if it should fail for any reason.
-*/
-
-/* Local Variables: */
- AstSkyAxis *this; /* Pointer to the SkyAxis structure */
- int result; /* Result value to return */
-
-/* Initialise. */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the SkyAxis structure. */
- this = (AstSkyAxis *) this_object;
-
-/* Check the attribute name and test the appropriate attribute. */
-
-/* AsTime. */
-/* ------- */
- if ( !strcmp( attrib, "astime" ) ) {
- result = astTestAxisAsTime( this );
-
-/* IsLatitude. */
-/* ----------- */
- } else if ( !strcmp( attrib, "islatitude" ) ) {
- result = astTestAxisIsLatitude( this );
-
-/* CentreZero. */
-/* ----------- */
- } else if ( !strcmp( attrib, "centrezero" ) ) {
- result = astTestAxisCentreZero( this );
-
-/* If the attribute is still not recognised, pass it on to the parent
- method for further interpretation. */
- } else {
- result = (*parent_testattrib)( this_object, attrib, status );
- }
-
-/* Return the result, */
- return result;
-}
-
-static int TestAxisFormat( AstAxis *this_axis, int *status ) {
-/*
-* Name:
-* TestAxisFormat
-
-* Purpose:
-* Test if a value has been set for the Format attribute of a SkyAxis.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* int TestAxisFormat( AstAxis *this, int *status )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astTestAxisFormat method
-* inherited from the Axis class).
-
-* Description:
-* This function returns 0 or 1 to indicate whether a value has been set
-* for the Format attribute of a SkyAxis.
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Zero if no Format value has been set, otherwise one.
-
-* Notes:
-* - This function will return a value of zero if it is invoked with the
-* global error status set, or if it should fail for any reason.
-*/
-
-/* Local Variables: */
- AstSkyAxis *this; /* Pointer to the SkyAxis structure */
- int result; /* Result to be returned */
-
-/* Check the global error status. */
- if ( !astOK ) return 0;
-
-/* Obtain a pointer to the SkyAxis structure. */
- this = (AstSkyAxis *) this_axis;
-
-/* The Format string has been set if the pointer to it is not NULL. */
- result = ( this->skyformat != NULL );
-
-/* Return the result. */
- return result;
-}
-
-static int TestAxisInternalUnit( AstAxis *this, int *status ){
-/*
-* Name:
-* TestAxisInternalUnit
-
-* Purpose:
-* Test if a InternalUnit attribute value is set for an Axis.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "axis.h"
-* int TestAxisInternalUnit( AstAxis *this, int *status )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astTestAxisInternalUnit
-* protected method inherited from the Axis class).
-
-* Description:
-* This function returns a boolean result (0 or 1) to indicate
-* whether a value has been set for the InternalUnit string.
-
-* Parameters:
-* this
-* Pointer to the Axis.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* One if a value has been set, otherwise zero.
-
-* Notes:
-* - A value of zero will be returned if this function is invoked
-* with the global status set, or if it should fail for any reason.
-*/
-
-/* Tell the world that we know what value to use for InternalUnit (i.e.
- "rad"). */
- return 1;
-}
-
-static int AxisUnformat( AstAxis *this_axis, const char *string,
- double *value, int *status ) {
-/*
-* Name:
-* AxisUnformat
-
-* Purpose:
-* Read a formatted coordinate value for a SkyAxis.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* int AxisUnformat( AstAxis *axis, const char *string, double *value, int *status )
-
-* Class Membership:
-* SkyAxis member function (over-rides the astAxisUnformat method
-* inherited from the Axis class).
-
-* Description:
-* This function reads a formatted coordinate value for a SkyAxis
-* (supplied as a string) and returns the equivalent numerical
-* value as a double. It also returns the number of characters read
-* from the string.
-
-* Parameters:
-* this
-* Pointer to the SkyAxis.
-* string
-* Pointer to a constant null-terminated string containing the
-* formatted coordinate value.
-* value
-* Pointer to a double in which the coordinate value read will be
-* returned (in radians).
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The number of characters read from the string to obtain the
-* coordinate value.
-
-* Notes:
-* - Any white space at the beginning of the string will be
-* skipped, as also will any trailing white space following the
-* coordinate value read. The function's return value will reflect
-* this.
-* - A function value of zero (and no coordinate value) will be
-* returned, without error, if the string supplied does not contain
-* a suitably formatted value.
-* - The string "<bad>" is recognised as a special case and will
-* generate the value AST__BAD, without error. The test for this
-* string is case-insensitive and permits embedded white space.
-* - A function result of zero will be returned and no coordinate
-* value will be returned via the "value" pointer if this function
-* is invoked with the global error status set, or if it should
-* fail for any reason.
-*-
-*/
-
-/* Local Constants: */
-#define FMT_LEN 50 /* Length of format buffer */
-
-/* Local Variables: */
- char fmtbuf[ FMT_LEN + 1 ]; /* Buffer for C format specification */
- char fmtsep; /* Format field separator character */
- char last_sep; /* Previous separator character */
- char sep; /* Separator character */
- char sep_used; /* Separator character being used */
- char sign[ 2 ]; /* Sign character as string */
- const char *field_start[ 3 ]; /* Pointer to start of each field */
- const char *fmt; /* Pointer to SkyAxis Format string */
- const char *s; /* Pointer to current reading position */
- const char *string_start; /* Pointer to first significant character */
- double field[ 3 ]; /* Field values */
- double testval; /* Value to test for invalid fields */
- int angle_or_time; /* Value known to be angle or time? */
- int as_time; /* Value is a time (else an angle)? */
- int decimal; /* Decimal point in field? */
- int dh; /* Hours field required? */
- int digs; /* Default no. of digits of precision */
- int exponent; /* Exponent at end of field? */
- int field_id[ 3 ]; /* Field identification (0 = don't know) */
- int final; /* Final field read? */
- int good_sep; /* Separator character valid? */
- int i; /* Loop counter for characters */
- int ifield; /* Loop counter for fields */
- int lead_zero; /* Add leading zeros? */
- int len; /* Significant length of string */
- int m; /* Number of characters read by astSscanf */
- int match; /* Character pattern matches? */
- int min; /* Minutes field required? */
- int n; /* Number of characters read by astSscanf */
- int nc; /* Total no. characters read */
- int nchar; /* Number of characters in erroneous value */
- int ndp; /* Number of decimal places */
- int next_id; /* Next field ID to use (0 = don't know) */
- int nfield; /* Number of fields read */
- int nread; /* No. characters read for current field */
- int plus; /* Add leading plus sign? */
- int positive; /* Value is positive? */
- int sec; /* Seconds field required? */
- int sep_angle_or_time; /* Separator indicates angle or time? */
- int sep_field_id; /* Field ID from separator (0 = don't know) */
- int sep_index; /* Index of separator character in table */
- int sep_len; /* Length of separator plus trailing space */
- int suffix_sep; /* Field has a suffix separator? */
-
-/* Local Data: */
- const char *sep_list = /* List of separator characters recognised */
- " :hHdDmM'sS\"";
-
- const int angle_or_time_list[] = /* Whether separator indicates angle or
- time (1 or 2). Zero => don't know. */
- { 0, 0, 2, 2, 1, 1, 0, 0, 1, 0, 0, 1 };
-
- const int field_id_list[] = /* Whether separator identifies previous field
- (1, 2, or 3). Zero => doesn't identify. */
- { 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3 };
-
- const double fieldvalue[ 3 ] = /* Nominal field values (degrees/hours) */
- { 1.0, 1.0 / 60.0, 1.0 / 3600.0 };
-
-/* Initialise. */
- nc = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return nc;
-
-/* Obtain the SkyAxis Format string. If its starts with a "%" sign, use
- the parent AxisUnformat method inherited from the Axis class. Use
- a private method to obtain the Format string, in case the syntax has been
- over-ridden by a derived class. */
- fmt = GetAxisFormat( this_axis, status );
- if( fmt && fmt[0] == '%' ) {
- nc = (*parent_axisunformat)( this_axis, string, value, status );
-
-/* Otherwise, parse it to determine the default choice of input format. */
- } else if( astOK ){
- digs = astGetAxisDigits( this_axis );
- ParseDHmsFormat( fmt, digs, &fmtsep, &plus, &lead_zero, &as_time, &dh,
- &min, &sec, &ndp, status );
-
-/* Initialise a pointer into the string and advance it to the first
- non-white space character. Save a copy of this pointer. */
- s = string;
- while ( isspace( (int) *s ) ) s++;
- string_start = s;
-
-/* Read sign information. */
-/* ---------------------- */
-/* Attempt to read an optional sign character ("+" or "-"), possibly
- surrounded by white space. Set a flag to indicate if the returned
- value should be positive or not. Increment the string pointer to
- the next significant character. */
- positive = 1;
- n = 0;
- if ( 1 == astSscanf( s, " %1[+-] %n", sign, &n ) ) {
- positive = ( *sign == '+' );
- s += n;
- }
-
-/* Loop to read field information. */
-/* ------------------------------- */
-/* Initialise, then loop to read the values of up to three fields and
- to identify the separators that accompany them. */
- angle_or_time = 0;
- last_sep = '\0';
- next_id = 0;
- nfield = 0;
- sep_used = '\0';
- suffix_sep = 0;
- sep_len = 0;
- for ( ifield = 0; ifield < 3; ifield++ ) {
-
-/* Set the default field value. */
- field[ ifield ] = 0.0;
-
-/* If a prefix separator was identified for the second and subsequent
- fields (when the previous field was being read), then step over the
- prefix, including any following white space. */
- if ( ifield && !suffix_sep ) s += sep_len;
-
-/* Note where in the input string the field's numerical value
- starts. */
- field_start[ ifield ] = s;
-
-/* Each field must consist of a string of digits, possibly surrounded
- by white space, except that an optional decimal point may also be
- present (in which case it indicates the final field). Since we want
- to exclude signs, etc. from these fields, we must first identify a
- valid sequence of digits, before attempting to read them as a number.
- Start by assuming that we will find a decimal point but not an
- exponent. */
- decimal = 1;
- exponent = 0;
-
-/* Match a field and obtain its value. */
-/* ----------------------------------- */
-/* Look for a character sequence like "12.345", or similar, setting a
- flag to identify a match. */
- n = 0;
- match = ( 0 == astSscanf( s, "%*[0123456789].%*[0123456789]%n", &n ) )
- && n;
-
-/* If that failed, then look for a sequence like "12.", or similar. */
- if ( !match ) {
- n = 0;
- match = ( 0 == astSscanf( s, "%*[0123456789].%n", &n ) ) && n;
- }
-
-/* If that also failed, then look for a sequence like ".12", or similar. */
- if ( !match ) {
- n = 0;
- match = ( 0 == astSscanf( s, ".%*[0123456789]%n", &n ) ) && n;
- }
-
-/* If that also failed, then look for a sequence containing digits only. */
- if ( !match ) {
- n = 0;
- match = ( 0 == astSscanf( s, "%*[0123456789]%n", &n ) ) && n;
-
-/* Note we have not found a decimal point. */
- decimal = 0;
- }
-
-/* Now look for numbers that end with an exponent. First check that the
- string starts with a sequence of digits with or without a decimal point. */
- if( match ) {
-
-/* See if the numbers are followed by an exponent with an explicit sign
- character. If so, increment the number of characters in the numerical
- string prefix. */
- m = 0;
- if( ( 0 == astSscanf( s + n, "%*1[Ee]%*1[+-]%*[0123456789]%n", &m ) )
- && m ) {
- n += m;
- exponent = 1;
-
-/* If the above check failed, see if the numbers are followed by an exponent
- without an explicit sign character. If so, increment the number of
- characters in the numerical string prefix. */
- } else {
- m = 0;
- if( ( 0 == astSscanf( s + n, "%*1[Ee]%*[0123456789]%n", &m ) )
- && m ) {
- n += m;
- exponent = 1;
- }
- }
- }
-
-/* If we identified a suitable sequence of characters above, we will
- now read them as a number. To prevent any subsequent characters
- being included as part of this number, the field width must be
- restricted to the length of the sequence we found. Write a format
- specification to read a double with this field width, followed by
- optional white space, and to return the total number of characters
- read. */
- nread = 0;
- if ( match ) {
- (void) sprintf( fmtbuf, "%%%dlf %%n", n );
-
-/* Use this format specification to read the field value. If
- successful, increment the string pointer to the next significant
- character. */
- if ( 1 == astSscanf( s, fmtbuf, field + ifield, &nread ) ) s += nread;
- }
-
-/* Note the total number of characters read up to the end of the
- numerical value in this field (including any following white
- space). */
- nc = s - string;
-
-/* Identify the following separator. */
-/* --------------------------------- */
-/* We will now attempt to identify the field separator (if any) which
- follows the field we have just read. By default, we behave as if
- the separator is a space. Note we have actually found a space (at
- least) if extra white space characters were read as part of the
- field value above. */
- sep = ' ';
- good_sep = ( nread > n );
-
-/* Look for one of the recognised separator characters. If one is
- found, save a copy of it and note we appear (so far) to have a
- valid separator. */
- sep_len = 0;
- if ( *s && strchr( sep_list, *s ) ) {
- sep = *s;
- good_sep = 1;
-
-/* Set "sep_len" to the number of characters associated with the
- separator. This includes any following white space. */
- while ( isspace( (int) s[ ++sep_len ] ) );
- }
-
-/* Identify the separator character by looking it up in the separator
- list (this just uses a space if no valid separator has been
- found). */
- sep_index = strchr( sep_list, sep ) - sep_list;
-
-/* Determine if the separator can be used to identify the field which
- preceded it and if it allows us to determine whether an angle or a
- time is being read. Both of these properties are specified in data
- tables (with zero indicating that the separator didn't supply any
- information). */
- sep_field_id = field_id_list[ sep_index ];
- sep_angle_or_time = angle_or_time_list[ sep_index ];
-
-/* Validate the separator. */
-/* ----------------------- */
-/* Now perform further checks that the separator is valid
- (i.e. conforms to the required syntax). If it appears to identify
- the previous field (i.e. is a "suffix" separator like "m" or "s"),
- then it is valid only if its field ID is no less than the ID value
- that would be used next, based on previous fields (if any), and no
- less than the current field number. This ensures that fields occur
- in the correct order without duplication. */
- if ( good_sep ) {
- if ( sep_field_id ) {
- good_sep = ( sep_field_id >= next_id ) &&
- ( sep_field_id > ifield );
-
-/* Otherwise (i.e. we appear to have a "prefix" separator like ":" or
- " "), it is valid if it is the first one used, or if it matches the
- previous one used. Keep a note of the first such separator used for
- checking subsequent ones. */
- } else {
- good_sep = !sep_used || ( sep == sep_used );
- if ( !sep_used ) sep_used = sep;
- }
- }
-
-/* If the separator seems OK and we don't yet know whether we are reading
- an angle or a time, then use whatever information the separator
- provides about this. */
- if ( good_sep ) {
- if ( !angle_or_time ) {
- angle_or_time = sep_angle_or_time;
-
-/* If we already know whether we are reading an angle or a time and
- the current separator also contains information about this, then
- check that these sources of information are compatible. This
- prevents inconsistent use of angle/time field separators. */
- } else {
- good_sep = !sep_angle_or_time ||
- ( sep_angle_or_time == angle_or_time );
- }
- }
-
-/* Update the count of characters read for this field and note if we
- have identified a valid suffix separator. */
- if ( good_sep ) nread += sep_len;
- suffix_sep = good_sep && sep_field_id;
-
-/* Identify which field was read. */
-/* ------------------------------ */
-/* If we have a valid suffix separator, store the field ID. Also make
- a note of the ID to use for the next field. */
- if ( suffix_sep ) {
- field_id[ ifield ] = sep_field_id;
- next_id = sep_field_id + 1;
-
-/* Step over the separator (plus any following white space) and update
- the total number of characters read (prefix separators are not
- accounted for until we start to read the next field). */
- s += sep_len;
- nc = s - string;;
-
-/* If the separator does not identify the current field, then assign a
- field ID based on the previous field (if any). Update the ID to use
- for the next field, if known. */
- } else {
- field_id[ ifield ] = next_id;
- if ( next_id ) next_id++;
- }
-
-/* Count fields and exit when done. */
-/* -------------------------------- */
-/* If no characters have been read for the current field, then
- disregard the field if: (a) it is the first one (i.e. there is
- nothing to read), or (b) it follows a white space separator
- (because trailing space does not delimit an extra field). In either
- case, we have now read all the fields. Otherwise, increment the
- count of fields read. */
- final = 0;
- if ( !nread && ( !ifield || isspace( (int) last_sep ) ) ) {
- final = 1;
- } else {
- nfield++;
- }
-
-/* We have also read all the fields if: (a) the last one contained a
- decimal point, or (b) the last one ended with an exponent, or (c)
- the next character is not a valid field separator, or (d) we have
- read the seconds field so the next field ID would exceed 3. */
- final = final || decimal || exponent || !good_sep || ( next_id > 3 );
-
-/* Quit reading if we have read the final field. Otherwise, save the
- separator character and attempt to read the next field. */
- if ( final ) break;
- last_sep = sep;
- }
-
-/* Complete the identification of fields. */
-/* -------------------------------------- */
-/* Although we have propagated field IDs from earlier ones to later
- ones in the loop above, we have still not done the reverse. This
- means there there may still be some leading fields which have not
- been positively identified (i.e. still have a field ID of zero). In
- fact, all the fields we have read might still be unidentified at
- this point. */
-
-/* Calculate the field ID that would apply to the final field we have
- read in the absence of any other information. This depends on the
- number of leading fields that are expected to be missing. */
- next_id = nfield + ( dh ? 0 : ( min ? 1 : 2 ) );
- if ( next_id > 3 ) next_id = 3;
-
-/* Loop through the fields in reverse order, propagating any positive
- identifications backwards towards the first field. If no fields
- have been positively identified, then they are simply numbered
- consecutively based on the value calculated above. */
- for ( ifield = nfield - 1; ifield >= 0; ifield-- ) {
- if ( field_id[ ifield ] ) {
- next_id = field_id[ ifield ] - 1;
- } else {
- field_id[ ifield ] = next_id--;
- }
- }
-
-/* Handle inability to read any value. */
-/* ----------------------------------- */
-/* If no fields were read, then check to see if we are trying to read
- the string "<bad>" (or similar) possibly surrounded by, or
- containing, white space. If so, return the coordinate value
- AST__BAD. */
- if ( !nfield ) {
- if ( n = 0,
- ( 0 == astSscanf( string, " < %*1[Bb] %*1[Aa] %*1[Dd] > %n", &n )
- && n ) ) {
- *value = AST__BAD;
- nc = n;
-
-/* If the string still cannot be read, then return a function value of
- zero. */
- } else {
- nc = 0;
- }
-
-/* Finally determine angle or time. */
-/* -------------------------------- */
-/* If one or more fields have been read, check if we know whether to
- interpret the value as an angle or a time (if not, we continue to
- use the default choice obtained from the SkyAxis Format string). */
- } else {
- if ( angle_or_time ) as_time = ( angle_or_time == 2 );
-
-/* Validate field values. */
-/* ---------------------- */
-/* If OK, check all fields except the first one for a valid value (we
- allow the first field to be unconstrained, so that angles and times
- outside the conventional ranges can be represented). We only need
- to test for values over 60.0, since negative values can't be
- read. */
- if ( astOK ) {
- for ( ifield = 1; ifield < nfield; ifield++ ) {
- if ( field[ ifield ] >= 60.0 ) {
-
-/* If a suspect field is found, we must now re-read it. This is
- because values like "59.9999..." are valid, even if they round up
- to 60, whereas "60" isn't. To distinguish these cases, we read the
- digits that occur before the decimal point (if any). Determine how
- many such digits there are. */
- n = 0;
- if ( ( 0 == astSscanf( field_start[ ifield ],
- "%*[0123456789]%n", &n ) ) && n ) {
-
-/* If there are none (this shouldn't happen), the field is
- valid. Otherwise, construct a format specification to read these
- digits as a floating point number. */
- (void) sprintf( fmtbuf, "%%%dlf", n );
-
-/* Read the digits and compare the result with 60.0. Report an error
- and quit if necessary, limiting the string length in the error
- message to include just the significant characters in the value
- read. */
- if ( ( 1 == astSscanf( field_start[ ifield ], fmtbuf,
- &testval ) )
- && ( testval >= 60.0 ) ) {
- nchar = nc - ( string_start - string );
- for ( i = len = 0; i < nchar; i++ ) {
- if ( !isspace( (int) string_start[ i ] ) ) {
- len = i + 1;
- }
- }
- astError( AST__UNFER, "Invalid %s%s value in sky "
- "coordinate \"%.*s\".", status, as_time ? "" : "arc",
- ( field_id[ ifield ] == 2 ) ? "minutes" :
- "seconds",
- len, string_start );
- break;
- }
- }
- }
- }
- }
-
-/* Calculate final result. */
-/* ----------------------- */
-/* If OK, calculate the result by summing the field values and converting
- to radians. */
- if ( astOK ) {
- *value = 0.0;
- for ( ifield = 0; ifield < nfield; ifield++ ) {
- *value += field[ ifield ] *
- fieldvalue[ field_id[ ifield ] - 1 ] *
- ( as_time ? hr2rad : deg2rad );
- }
-
-/* Change sign if necessary. */
- if ( !positive ) *value = - *value;
- }
- }
- }
-
-/* If an error occurred, set the number of characters read to zero. */
- if ( !astOK ) nc = 0;
-
-/* Return the number of characters read. */
- return nc;
-
-/* Undefine macros local to this function. */
-#undef FMT_LEN
-}
-
-/* Functions which access class attributes. */
-/* ---------------------------------------- */
-/* Implement member functions to access the attributes associated with the
- SkyAxis class using the macros defined for this purpose in the "object.h"
- file. For a description of each attribute, see the class interface (in the
- associated .h file). */
-
-/* AsTime. */
-/* ------- */
-/* The value is constrained to be -INT_MAX, 0 or 1, with -INT_MAX for
- "undefined". The default value is 0 unless the "IsLatitude"
- attribute has been explicitly set to 0, in which case "AsTime"
- defaults to 1. */
-astMAKE_CLEAR(SkyAxis,AxisAsTime,as_time,-INT_MAX)
-astMAKE_GET(SkyAxis,AxisAsTime,int,0,( ( this->as_time != -INT_MAX ) ?
- this->as_time :
- ( astTestAxisIsLatitude( this ) &&
- !astGetAxisIsLatitude( this ) ) ))
-astMAKE_SET(SkyAxis,AxisAsTime,int,as_time,( value != 0 ))
-astMAKE_TEST(SkyAxis,AxisAsTime,( this->as_time != -INT_MAX ))
-
-/* IsLatitude. */
-/* ----------- */
-/* The value is constrained to be -INT_MAX, 0 or 1, with -INT_MAX for
- "undefined". The default value is 0. */
-astMAKE_CLEAR(SkyAxis,AxisIsLatitude,is_latitude,-INT_MAX)
-astMAKE_GET(SkyAxis,AxisIsLatitude,int,0,( this->is_latitude != -INT_MAX ?
- this->is_latitude : 0 ))
-astMAKE_SET(SkyAxis,AxisIsLatitude,int,is_latitude,( value != 0 ))
-astMAKE_TEST(SkyAxis,AxisIsLatitude,( this->is_latitude != -INT_MAX ))
-
-/* CentreZero. */
-/* ----------- */
-/* The value is constrained to be -INT_MAX, 0 or 1, with -INT_MAX for
- "undefined". The default value is equal to the value of IsLatitude. */
-astMAKE_CLEAR(SkyAxis,AxisCentreZero,centrezero,-INT_MAX)
-astMAKE_GET(SkyAxis,AxisCentreZero,int,0,( this->centrezero != -INT_MAX ?
- this->centrezero : astGetAxisIsLatitude( this ) ))
-astMAKE_SET(SkyAxis,AxisCentreZero,int,centrezero,( value != 0 ))
-astMAKE_TEST(SkyAxis,AxisCentreZero,( this->centrezero != -INT_MAX ))
-
-/* Copy constructor. */
-/* ----------------- */
-static void Copy( const AstObject *objin, AstObject *objout, int *status ) {
-/*
-* Name:
-* Copy
-
-* Purpose:
-* Copy constructor for SkyAxis objects.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* void Copy( const AstObject *objin, AstObject *objout, int *status )
-
-* Description:
-* This function implements the copy constructor for SkyAxis objects.
-
-* Parameters:
-* objin
-* Pointer to the object to be copied.
-* objout
-* Pointer to the object being constructed.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* void
-
-* Notes:
-* - This constructor makes a deep copy.
-*/
-
-/* Local Variables: */
- AstSkyAxis *in; /* Pointer to input SkyAxis */
- AstSkyAxis *out; /* Pointer to output SkyAxis */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain pointers to the input and output SkyAxis structures. */
- in = (AstSkyAxis *) objin;
- out = (AstSkyAxis *) objout;
-
-/* For safety, first clear any references to the input memory from
- the output SkyAxis. */
- out->skyformat = NULL;
-
-/* Make copies of the allocated strings. */
- if ( in->skyformat ) out->skyformat = astStore( NULL, in->skyformat,
- strlen( in->skyformat ) + (size_t) 1 );
-
-/* If an error occurred, clean up by freeing all memory allocated above. */
- if ( !astOK ) {
- out->skyformat = astFree( out->skyformat );
- }
-}
-
-/* Destructor. */
-/* ----------- */
-static void Delete( AstObject *obj, int *status ) {
-/*
-* Name:
-* Delete
-
-* Purpose:
-* Destructor for SkyAxis objects.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* void Delete( AstObject *obj, int *status )
-
-* Description:
-* This function implements the destructor for SkyAxis objects.
-
-* Parameters:
-* obj
-* Pointer to the object to be deleted.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* void
-
-* Notes:
-* This function attempts to execute even if the global error status is
-* set.
-*/
-
-/* Local Variables: */
- AstSkyAxis *this; /* Pointer to the SkyAxis structure */
-
-/* Obtain a pointer to the SkyAxis structure. */
- this = (AstSkyAxis *) obj;
-
-/* Free all allocated memory. */
- this->skyformat = astFree( this->skyformat );
-}
-
-/* Dump function. */
-/* -------------- */
-static void Dump( AstObject *this_object, AstChannel *channel, int *status ) {
-/*
-* Name:
-* Dump
-
-* Purpose:
-* Dump function for SkyAxis objects.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* void Dump( AstObject *this, AstChannel *channel, int *status )
-
-* Description:
-* This function implements the Dump function which writes out data
-* for the SkyAxis class to an output Channel.
-
-* Parameters:
-* this
-* Pointer to the SkyAxis whose data are being written.
-* channel
-* Pointer to the Channel to which the data are being written.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Local Variables: */
- AstAxis *this_axis; /* Pointer to Axis structure */
- AstSkyAxis *this; /* Pointer to the SkyAxis structure */
- const char *sval; /* Pointer to string value */
- int ival; /* Integer value */
- int set; /* Attribute value set? */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the SkyAxis structure. */
- this = (AstSkyAxis *) this_object;
-
-/* Write out values representing the instance variables for the
- SkyAxis class. Accompany these with appropriate comment strings,
- possibly depending on the values being written.*/
-
-/* In the case of attributes, we first use the appropriate (private)
- Test... member function to see if they are set. If so, we then use
- the (private) Get... function to obtain the value to be written
- out.
-
- For attributes which are not set, we use the astGet... method to
- obtain the value instead. This will supply a default value
- (possibly provided by a derived class which over-rides this method)
- which is more useful to a human reader as it corresponds to the
- actual default attribute value. Since "set" will be zero, these
- values are for information only and will not be read back. */
-
-/* Format. */
-/* ------- */
-/* We must write out the Format value stored locally as it over-rides
- that provided by the Axis class. */
- this_axis = (AstAxis *) this;
- set = TestAxisFormat( this_axis, status );
- sval = set ? GetAxisFormat( this_axis, status ) : astGetAxisFormat( this );
- astWriteString( channel, "Format", set, 0, sval, "Format specifier" );
-
-/* IsLatitude. */
-/* ----------- */
- set = TestAxisIsLatitude( this, status );
- ival = set ? GetAxisIsLatitude( this, status ) : astGetAxisIsLatitude( this );
- astWriteInt( channel, "IsLat", set, 0, ival,
- ival ? "Latitude axis (not longitude)" :
- "Longitude axis (not latitude)" );
-
-/* CentreZero. */
-/* ----------- */
- set = TestAxisCentreZero( this, status );
- ival = set ? GetAxisCentreZero( this, status ) : astGetAxisCentreZero( this );
- astWriteInt( channel, "CnZer", set, 0, ival,
- ival ? "Display axis values in range -PI -> +PI" :
- "Display axis values in range 0 -> 2.PI" );
-
-/* AsTime. */
-/* ------- */
- set = TestAxisAsTime( this, status );
- ival = set ? GetAxisAsTime( this, status ) : astGetAxisAsTime( this );
- astWriteInt( channel, "AsTime", set, 0, ival,
- ival ? "Display values as times (not angles)" :
- "Display values as angles (not times)" );
-}
-
-/* Standard class functions. */
-/* ========================= */
-/* Implement the astIsASkyAxis and astCheckSkyAxis functions using the macros
- defined for this purpose in the "object.h" header file. */
-astMAKE_ISA(SkyAxis,Axis)
-astMAKE_CHECK(SkyAxis)
-
-AstSkyAxis *astSkyAxis_( const char *options, int *status, ...) {
-/*
-*+
-* Name:
-* astSkyAxis
-
-* Purpose:
-* Create a SkyAxis.
-
-* Type:
-* Public function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* AstSkyAxis *astSkyAxis( const char *options, int *status, ... )
-
-* Class Membership:
-* SkyAxis constructor.
-
-* Description:
-* This function creates a new SkyAxis and optionally initialises its
-* attributes.
-
-* Parameters:
-* options
-* Pointer to a null terminated string containing an optional
-* comma-separated list of attribute assignments to be used for
-* initialising the new SkyAxis. The syntax used is the same as for the
-* astSet method and may include "printf" format specifiers identified
-* by "%" symbols in the normal way.
-* status
-* Pointer to the inherited status variable.
-* ...
-* If the "options" string contains "%" format specifiers, then an
-* optional list of arguments may follow it in order to supply values to
-* be substituted for these specifiers. The rules for supplying these
-* are identical to those for the astSet method (and for the C "printf"
-* function).
-
-* Returned Value:
-* A pointer to the new SkyAxis.
-
-* Notes:
-* - A NULL pointer will be returned if this function is invoked with the
-* global error status set, or if it should fail for any reason.
-*-
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Pointer to thread-specific global data */
- AstSkyAxis *new; /* Pointer to new SkyAxis */
- va_list args; /* Variable argument list */
-
-/* Get a pointer to the thread specific global data structure. */
- astGET_GLOBALS(NULL);
-
-/* Check the global error status. */
- if ( !astOK ) return NULL;
-
-/* Initialise the SkyAxis, allocating memory and initialising the
- virtual function table as well if necessary. */
- new = astInitSkyAxis( NULL, sizeof( AstSkyAxis ), !class_init, &class_vtab,
- "SkyAxis" );
-
-/* If successful, note that the virtual function table has been
- initialised. */
- if ( astOK ) {
- class_init = 1;
-
-/* Obtain the variable argument list and pass it along with the
- options string to the astVSet method to initialise the new SkyAxis'
- attributes. */
- va_start( args, status );
- astVSet( new, options, NULL, args );
- va_end( args );
-
-/* If an error occurred, clean up by deleting the new object. */
- if ( !astOK ) new = astDelete( new );
- }
-
-/* Return a pointer to the new SkyAxis. */
- return new;
-}
-
-AstSkyAxis *astSkyAxisId_( const char *options, ... ) {
-/*
-* Name:
-* astSkyAxisId_
-
-* Purpose:
-* Create a SkyAxis.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* AstSkyAxis *astSkyAxisId_( const char *options, ... )
-
-* Class Membership:
-* SkyAxis constructor.
-
-* Description:
-* This function implements the external (public) interface to the
-* astSkyAxis constructor function. It returns an ID value (instead
-* of a true C pointer) to external users, and must be provided
-* because astSkyAxis_ has a variable argument list which cannot be
-* encapsulated in a macro (where this conversion would otherwise
-* occur).
-*
-* The variable argument list also prevents this function from
-* invoking astSkyAxis_ directly, so it must be a re-implementation
-* of it in all respects, except for the final conversion of the
-* result to an ID value.
-
-* Parameters:
-* As for astSkyAxis_.
-
-* Returned Value:
-* The ID value associated with the new SkyAxis.
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Pointer to thread-specific global data */
- AstSkyAxis *new; /* Pointer to new SkyAxis */
- va_list args; /* Variable argument list */
-
- int *status; /* Pointer to inherited status value */
-
-/* Get a pointer to the inherited status value. */
- status = astGetStatusPtr;
-
-/* Get a pointer to the thread specific global data structure. */
- astGET_GLOBALS(NULL);
-
-/* Check the global error status. */
- if ( !astOK ) return NULL;
-
-/* Initialise the SkyAxis, allocating memory and initialising the
- virtual function table as well if necessary. */
- new = astInitSkyAxis( NULL, sizeof( AstSkyAxis ), !class_init, &class_vtab,
- "SkyAxis" );
-
-/* If successful, note that the virtual function table has been
- initialised. */
- if ( astOK ) {
- class_init = 1;
-
-/* Obtain the variable argument list and pass it along with the
- options string to the astVSet method to initialise the new SkyAxis'
- attributes. */
- va_start( args, options );
- astVSet( new, options, NULL, args );
- va_end( args );
-
-/* If an error occurred, clean up by deleting the new object. */
- if ( !astOK ) new = astDelete( new );
- }
-
-/* Return an ID value for the new SkyAxis. */
- return astMakeId( new );
-}
-
-AstSkyAxis *astInitSkyAxis_( void *mem, size_t size, int init,
- AstSkyAxisVtab *vtab, const char *name, int *status ) {
-/*
-*+
-* Name:
-* astInitSkyAxis
-
-* Purpose:
-* Initialise a SkyAxis.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* AstSkyAxis *astInitSkyAxis( void *mem, size_t size, int init,
-* AstSkyAxisVtab *vtab, const char *name )
-
-* Class Membership:
-* SkyAxis initialiser.
-
-* Description:
-* This function is provided for use by class implementations to initialise
-* a new SkyAxis object. It allocates memory (if necessary) to accommodate
-* the SkyAxis plus any additional data associated with the derived class.
-* It then initialises a SkyAxis structure at the start of this memory. If
-* the "init" flag is set, it also initialises the contents of a virtual
-* function table for a SkyAxis at the start of the memory passed via the
-* "vtab" parameter.
-
-* Parameters:
-* mem
-* A pointer to the memory in which the SkyAxis is to be created. This
-* must be of sufficient size to accommodate the SkyAxis data
-* (sizeof(SkyAxis)) plus any data used by the derived class. If a value
-* of NULL is given, this function will allocate the memory itself using
-* the "size" parameter to determine its size.
-* size
-* The amount of memory used by the SkyAxis (plus derived class data).
-* This will be used to allocate memory if a value of NULL is given for
-* the "mem" parameter. This value is also stored in the SkyAxis
-* structure, so a valid value must be supplied even if not required for
-* allocating memory.
-* init
-* A logical flag indicating if the SkyAxis's virtual function table is
-* to be initialised. If this value is non-zero, the virtual function
-* table will be initialised by this function.
-* vtab
-* Pointer to the start of the virtual function table to be associated
-* with the new SkyAxis.
-* name
-* Pointer to a constant null-terminated character string which contains
-* the name of the class to which the new object belongs (it is this
-* pointer value that will subsequently be returned by the astClass
-* method).
-
-* Returned Value:
-* A pointer to the new SkyAxis.
-
-* Notes:
-* - A NULL pointer will be returned if this function is invoked with the
-* global error status set, or if it should fail for any reason.
-*-
-*/
-
-/* Local Variables: */
- AstSkyAxis *new; /* Pointer to the new SkyAxis */
-
-/* Check the global error status. */
- if ( !astOK ) return NULL;
-
-/* If necessary, initialise the virtual function table. */
- if ( init ) astInitSkyAxisVtab( vtab, name );
-
-/* Initialise an Axis structure (the parent class) as the first component
- within the SkyAxis structure, allocating memory if necessary. */
- new = (AstSkyAxis *) astInitAxis( mem, size, 0, (AstAxisVtab *) vtab,
- name );
-
- if ( astOK ) {
-
-/* Initialise the SkyAxis data. */
-/* ---------------------------- */
-/* Initialise all attributes to their "undefined" values. */
- new->as_time = -INT_MAX;
- new->is_latitude = -INT_MAX;
- new->centrezero = -INT_MAX;
- new->skyformat = NULL;
-
-/* If an error occurred, clean up by deleting the new SkyAxis. */
- if ( !astOK ) new = astDelete( new );
- }
-
-/* Return a pointer to the new SkyAxis. */
- return new;
-}
-
-AstSkyAxis *astLoadSkyAxis_( void *mem, size_t size,
- AstSkyAxisVtab *vtab, const char *name,
- AstChannel *channel, int *status ) {
-/*
-*+
-* Name:
-* astLoadSkyAxis
-
-* Purpose:
-* Load a SkyAxis.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "skyaxis.h"
-* AstSkyAxis *astLoadSkyAxis( void *mem, size_t size,
-* AstSkyAxisVtab *vtab, const char *name,
-* AstChannel *channel )
-
-* Class Membership:
-* SkyAxis loader.
-
-* Description:
-* This function is provided to load a new SkyAxis using data read
-* from a Channel. It first loads the data used by the parent class
-* (which allocates memory if necessary) and then initialises a
-* SkyAxis structure in this memory, using data read from the input
-* Channel.
-*
-* If the "init" flag is set, it also initialises the contents of a
-* virtual function table for a SkyAxis at the start of the memory
-* passed via the "vtab" parameter.
-
-
-* Parameters:
-* mem
-* A pointer to the memory into which the SkyAxis is to be
-* loaded. This must be of sufficient size to accommodate the
-* SkyAxis data (sizeof(SkyAxis)) plus any data used by derived
-* classes. If a value of NULL is given, this function will
-* allocate the memory itself using the "size" parameter to
-* determine its size.
-* size
-* The amount of memory used by the SkyAxis (plus derived class
-* data). This will be used to allocate memory if a value of
-* NULL is given for the "mem" parameter. This value is also
-* stored in the SkyAxis structure, so a valid value must be
-* supplied even if not required for allocating memory.
-*
-* If the "vtab" parameter is NULL, the "size" value is ignored
-* and sizeof(AstSkyAxis) is used instead.
-* vtab
-* Pointer to the start of the virtual function table to be
-* associated with the new SkyAxis. If this is NULL, a pointer
-* to the (static) virtual function table for the SkyAxis class
-* is used instead.
-* name
-* Pointer to a constant null-terminated character string which
-* contains the name of the class to which the new object
-* belongs (it is this pointer value that will subsequently be
-* returned by the astGetClass method).
-*
-* If the "vtab" parameter is NULL, the "name" value is ignored
-* and a pointer to the string "SkyAxis" is used instead.
-
-* Returned Value:
-* A pointer to the new SkyAxis.
-
-* Notes:
-* - A null pointer will be returned if this function is invoked
-* with the global error status set, or if it should fail for any
-* reason.
-*-
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Pointer to thread-specific global data */
- AstSkyAxis *new; /* Pointer to the new SkyAxis */
-
-/* Initialise. */
- new = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return new;
-
-/* Get a pointer to the thread specific global data structure. */
- astGET_GLOBALS(channel);
-
-/* If a NULL virtual function table has been supplied, then this is
- the first loader to be invoked for this SkyAxis. In this case the
- SkyAxis belongs to this class, so supply appropriate values to be
- passed to the parent class loader (and its parent, etc.). */
- if ( !vtab ) {
- size = sizeof( AstSkyAxis );
- vtab = &class_vtab;
- name = "SkyAxis";
-
-/* If required, initialise the virtual function table for this class. */
- if ( !class_init ) {
- astInitSkyAxisVtab( vtab, name );
- class_init = 1;
- }
- }
-
-/* Invoke the parent class loader to load data for all the ancestral
- classes of the current one, returning a pointer to the resulting
- partly-built SkyAxis. */
- new = astLoadAxis( mem, size, (AstAxisVtab *) vtab, name, channel );
-
- if ( astOK ) {
-
-/* Read input data. */
-/* ================ */
-/* Request the input Channel to read all the input data appropriate to
- this class into the internal "values list". */
- astReadClassData( channel, "SkyAxis" );
-
-/* Now read each individual data item from this list and use it to
- initialise the appropriate instance variable(s) for this class. */
-
-/* In the case of attributes, we first read the "raw" input value,
- supplying the "unset" value as the default. If a "set" value is
- obtained, we then use the appropriate (private) Set... member
- function to validate and set the value properly. */
-
-/* Format. */
-/* ------- */
-/* Note that string values do not require any additional processing. */
- new->skyformat = astReadString( channel, "format", NULL );
-
-/* IsLatitude. */
-/* ----------- */
- new->is_latitude = astReadInt( channel, "islat", -INT_MAX );
- if ( TestAxisIsLatitude( new, status ) ) {
- SetAxisIsLatitude( new, new->is_latitude, status );
- }
-
-/* CentreZero. */
-/* ----------- */
- new->centrezero = astReadInt( channel, "cnzer", -INT_MAX );
- if ( TestAxisCentreZero( new, status ) ) {
- SetAxisCentreZero( new, new->centrezero, status );
- }
-
-/* AsTime. */
-/* ------- */
- new->as_time = astReadInt( channel, "astime", -INT_MAX );
- if ( TestAxisAsTime( new, status ) ) SetAxisAsTime( new, new->as_time, status );
-
-/* If an error occurred, clean up by deleting the new SkyAxis. */
- if ( !astOK ) new = astDelete( new );
- }
-
-/* Return the new SkyAxis pointer. */
- return new;
-}
-
-/* Virtual function interfaces. */
-/* ============================ */
-/* These provide the external interface to the virtual functions defined by
- this class. Each simply checks the global error status and then locates and
- executes the appropriate member function, using the function pointer stored
- in the object's virtual function table (this pointer is located using the
- astMEMBER macro defined in "object.h").
-
- Note that the member function may not be the one defined here, as it may
- have been over-ridden by a derived class. However, it should still have the
- same interface. */
-
-/* (No more to define at present.) */
-
-
-
-
-