summaryrefslogtreecommitdiffstats
path: root/ast/channel.c
diff options
context:
space:
mode:
authorWilliam Joye <wjoye@cfa.harvard.edu>2019-05-10 18:41:55 (GMT)
committerWilliam Joye <wjoye@cfa.harvard.edu>2019-05-10 18:41:55 (GMT)
commit75fab9d80911f74aaab738fa9ab8a4f9b0f57a6b (patch)
tree8d0d428ac62291f834ea8927bfa82c115ff1689d /ast/channel.c
parent0609bafa2688ce94fbfdc1ea496b20c3fac732f1 (diff)
downloadblt-75fab9d80911f74aaab738fa9ab8a4f9b0f57a6b.zip
blt-75fab9d80911f74aaab738fa9ab8a4f9b0f57a6b.tar.gz
blt-75fab9d80911f74aaab738fa9ab8a4f9b0f57a6b.tar.bz2
upgrade ast 8.7.1
Diffstat (limited to 'ast/channel.c')
-rw-r--r--ast/channel.c6458
1 files changed, 0 insertions, 6458 deletions
diff --git a/ast/channel.c b/ast/channel.c
deleted file mode 100644
index 9219502..0000000
--- a/ast/channel.c
+++ /dev/null
@@ -1,6458 +0,0 @@
-/*
-*class++
-* Name:
-* Channel
-
-* Purpose:
-* Basic (textual) I/O channel.
-
-* Constructor Function:
-c astChannel
-f AST_CHANNEL
-
-* Description:
-* The Channel class implements low-level input/output for the AST
-* library. Writing an Object to a Channel will generate a textual
-* representation of that Object, and reading from a Channel will
-* create a new Object from its textual representation.
-*
-* Normally, when you use a Channel, you should provide "source"
-c and "sink" functions which connect it to an external data store
-f and "sink" routines which connect it to an external data store
-* by reading and writing the resulting text. By default, however,
-* a Channel will read from standard input and write to standard
-* output. Alternatively, a Channel can be told to read or write from
-* specific text files using the SinkFile and SourceFile attributes,
-* in which case no sink or source function need be supplied.
-
-* Inheritance:
-* The Channel class inherits from the Object class.
-
-* Attributes:
-* In addition to those attributes common to all Objects, every
-* Channel also has the following attributes:
-*
-* - Comment: Include textual comments in output?
-* - Full: Set level of output detail
-* - Indent: Indentation increment between objects
-* - ReportLevel: Selects the level of error reporting
-* - SinkFile: The path to a file to which the Channel should write
-* - Skip: Skip irrelevant data?
-* - SourceFile: The path to a file from which the Channel should read
-* - Strict: Generate errors instead of warnings?
-
-* Functions:
-c In addition to those functions applicable to all Objects, the
-c following functions may also be applied to all Channels:
-f In addition to those routines applicable to all Objects, the
-f following routines may also be applied to all Channels:
-*
-c - astWarnings: Return warnings from the previous read or write
-c - astPutChannelData: Store data to pass to source or sink functions
-c - astRead: Read an Object from a Channel
-c - astWrite: Write an Object to a Channel
-f - AST_WARNINGS: Return warnings from the previous read or write
-f - AST_READ: Read an Object from a Channel
-f - AST_WRITE: Write an Object to a Channel
-
-* Copyright:
-* Copyright (C) 1997-2006 Council for the Central Laboratory of the
-* Copyright (C) 2009 Science & Technology Facilities Council.
-* All Rights Reserved.
-* Research Councils
-
-* 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)
-
-* History:
-* 12-AUG-1996 (RFWS):
-* Original version.
-* 6-SEP-1996:
-* Finished initial implementation.
-* 11-DEC-1996 (RFWS):
-* Added support for foreign language source and sink functions.
-* 28-APR-1997 (RFWS):
-* Prevent "-0" being written (use "0" instead).
-* 27-NOV-2002 (DSB):
-* Added astWriteInvocations.
-* 8-JAN-2003 (DSB):
-* - Changed private InitVtab method to protected astInitChannelVtab
-* method.
-* - Modified to use protected Vtab initialisation methods when
-* loading an Object.
-* 1-NOV-2003 (DSB):
-* Change the initialiser so that it accepts source and sink
-* wrapper functions as arguments (for use by derived classes).
-* 16-AUG-2006 (DSB):
-* - Document non-destructive nature of unsuccessful astRead calls
-* on a FitsChan.
-* 3-OCT-2008 (DSB):
-* Added "Strict" attribute.
-* 11-DEC-2008 (DSB):
-* Added astPutChannelData and astChannelData functions.
-* 16-JAN-2009 (DSB):
-* Added astAddWarning and astWarnings.
-* 11-JUN-2009 (DSB):
-* Enable astChannelData to be used from within astRead.
-* 7-DEC-2009 (DSB):
-* Added Indent attribute.
-* 12-FEB-2010 (DSB):
-* Represent AST__BAD externally using the string "<bad>".
-* 23-JUN-2011 (DSB):
-* Added attributes SinkFile and SourceFile.
-* 2-OCT-2012 (DSB):
-* Report an error if an Inf or NaN value is read from the external
-* source.
-*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 Channel
-
-/* Define a string containing the maximum length of keywords used to
- identify values in the external representation of data. This is
- deliberately kept small so as to simplify integration with
- standards such as FITS. */
-#define MAX_NAME "8"
-
-/* Max length of string returned by GetAttrib */
-#define GETATTRIB_BUFF_LEN 50
-
-/* String used to represent AST__BAD externally. */
-#define BAD_STRING "<bad>"
-
-/* Include files. */
-/* ============== */
-/* Interface definitions. */
-/* ---------------------- */
-
-#include "globals.h" /* Thread-safe global data access */
-#include "error.h" /* Error reporting facilities */
-#include "memory.h" /* Memory allocation facilities */
-#include "object.h" /* Base Object class */
-#include "channel.h" /* Interface definition for this class */
-#include "loader.h" /* Interface to the global loader */
-#include "keymap.h" /* Storing arbitrary data in an AST Object */
-#include "pointset.h" /* For AST__BAD */
-
-/* Error code definitions. */
-/* ----------------------- */
-#include "ast_err.h" /* AST error codes */
-
-/* C header files. */
-/* --------------- */
-#include <ctype.h>
-#include <errno.h>
-#include <float.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.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 const char *(* parent_getattrib)( AstObject *, const char *, int * );
-static int (* parent_testattrib)( AstObject *, const char *, int * );
-static void (* parent_clearattrib)( AstObject *, const char *, int * );
-static void (* parent_setattrib)( AstObject *, const char *, int * );
-
-/* 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->AstReadClassData_Msg = 0; \
- globals->GetAttrib_Buff[ 0 ] = 0; \
- globals->Items_Written = 0; \
- globals->Current_Indent = 0; \
- globals->Nest = -1; \
- globals->Nwrite_Invoc = 0; \
- globals->Object_Class = NULL; \
- globals->Values_List = NULL; \
- globals->Values_Class = NULL; \
- globals->Values_OK = NULL; \
- globals->End_Of_Object = NULL; \
- globals->Channel_Data = NULL;
-
-/* Create the function that initialises global data for this module. */
-astMAKE_INITGLOBALS(Channel)
-
-/* Define macros for accessing each item of thread specific global data. */
-#define class_init astGLOBAL(Channel,Class_Init)
-#define class_vtab astGLOBAL(Channel,Class_Vtab)
-#define astreadclassdata_msg astGLOBAL(Channel,AstReadClassData_Msg)
-#define getattrib_buff astGLOBAL(Channel,GetAttrib_Buff)
-#define items_written astGLOBAL(Channel,Items_Written)
-#define current_indent astGLOBAL(Channel,Current_Indent)
-#define nest astGLOBAL(Channel,Nest)
-#define nwrite_invoc astGLOBAL(Channel,Nwrite_Invoc)
-#define object_class astGLOBAL(Channel,Object_Class)
-#define values_list astGLOBAL(Channel,Values_List)
-#define values_class astGLOBAL(Channel,Values_Class)
-#define values_ok astGLOBAL(Channel,Values_OK)
-#define end_of_object astGLOBAL(Channel,End_Of_Object)
-#define channel_data astGLOBAL(Channel,Channel_Data)
-
-
-
-static pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
-#define LOCK_MUTEX2 pthread_mutex_lock( &mutex2 );
-#define UNLOCK_MUTEX2 pthread_mutex_unlock( &mutex2 );
-
-static pthread_mutex_t mutex3 = PTHREAD_MUTEX_INITIALIZER;
-#define LOCK_MUTEX3 pthread_mutex_lock( &mutex3 );
-#define UNLOCK_MUTEX3 pthread_mutex_unlock( &mutex3 );
-
-/* If thread safety is not needed, declare and initialise globals at static
- variables. */
-#else
-
-/* Contextual error message reported in astReadClassData? */
-static int astreadclassdata_msg = 0;
-
-/* Buffer returned by GetAttrib. */
-static char getattrib_buff[ GETATTRIB_BUFF_LEN + 1 ];
-
-/* Count of the number of output items written since the last "Begin"
- or "IsA" item. */
-static int items_written = 0;
-
-/* Amount of indentation to be applied to the next output item. */
-static int current_indent = 0;
-
-/* Nesting level, used to keep track of data associated with building
- Objects when they contain other Objects. */
-static int nest = -1;
-
-/* The number of times astWrite has been invoked. */
-static int nwrite_invoc = 0;
-
-/* Pointer to a user-supplied block of memory to be made available to
- source or sink functions via the astChannelData function. */
-static void *channel_data = NULL;
-
-/***
- The following items are all pointers to dynamically allocated
- arrays (stacks) that grow as necessary to accommodate one element
- for each level of nesting (one more than the value of "nest").
-***/
-
-/* Stack of pointers to null-terminated character strings giving the
- names of the classes of the Objects being built at each nesting
- level. */
-static char **object_class = NULL;
-
-/* Stack of pointers to the elements designated as the "heads" of
- circular, doubly linked lists of name-value associations. */
-static AstChannelValue **values_list = NULL;
-
-/* Stack of pointers to null-terminated character strings giving the
- names of the classes for which the values held in the values lists
- are intended. */
-static char **values_class = NULL;
-
-/* Stack of flags indicating whether the values held in the values
- lists are intended for the class loaders currently executing to
- build Objects at each nesting level. */
-static int *values_ok = NULL;
-
-/* Stack of flags indicating whether "End" items have been read for
- the Objects being built at each nesting level. */
-static int *end_of_object = NULL;
-
-
-/* Define the class virtual function table and its initialisation flag
- as static variables. */
-static AstChannelVtab class_vtab; /* Virtual function table */
-static int class_init = 0; /* Virtual function table initialised? */
-#define LOCK_MUTEX2
-#define UNLOCK_MUTEX2
-#define LOCK_MUTEX3
-#define UNLOCK_MUTEX3
-
-#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. */
-AstChannel *astChannelForId_( const char *(*)( void ),
- char *(*)( const char *(*)( void ), int * ),
- void (*)( const char * ),
- void (*)( void (*)( const char * ),
- const char *, int * ),
- const char *, ... );
-AstChannel *astChannelId_( const char *(*)( void ), void (*)( const char * ), const char *, ... );
-
-/* Prototypes for Private Member Functions. */
-/* ======================================== */
-static AstObject *Read( AstChannel *, int * );
-static AstObject *ReadObject( AstChannel *, const char *, AstObject *, int * );
-static AstChannelValue *FreeValue( AstChannelValue *, int * );
-static AstChannelValue *LookupValue( const char *, int * );
-static AstKeyMap *Warnings( AstChannel *, int * );
-static char *GetNextText( AstChannel *, int * );
-static char *InputTextItem( AstChannel *, int * );
-static char *ReadString( AstChannel *, const char *, const char *, int * );
-static char *SourceWrap( const char *(*)( void ), int * );
-static const char *GetAttrib( AstObject *, const char *, int * );
-static double ReadDouble( AstChannel *, const char *, double, int * );
-static int GetComment( AstChannel *, int * );
-static int GetFull( AstChannel *, int * );
-static int GetSkip( AstChannel *, int * );
-static int GetStrict( AstChannel *, int * );
-static int ReadInt( AstChannel *, const char *, int, int * );
-static int TestAttrib( AstObject *, const char *, int * );
-static int TestComment( AstChannel *, int * );
-static int TestFull( AstChannel *, int * );
-static int TestSkip( AstChannel *, int * );
-static int TestStrict( AstChannel *, int * );
-static int Use( AstChannel *, int, int, int * );
-static int Write( AstChannel *, AstObject *, int * );
-static void AddWarning( AstChannel *, int, const char *, const char *, int * );
-static void AppendValue( AstChannelValue *, AstChannelValue **, int * );
-static void ClearAttrib( AstObject *, const char *, int * );
-static void ClearComment( AstChannel *, int * );
-static void ClearFull( AstChannel *, int * );
-static void ClearSkip( AstChannel *, int * );
-static void ClearStrict( AstChannel *, int * );
-static void ClearValues( AstChannel *, int * );
-static void Copy( const AstObject *, AstObject *, int * );
-static void Delete( AstObject *, int * );
-static void Dump( AstObject *, AstChannel *, int * );
-static void GetNextData( AstChannel *, int, char **, char **, int * );
-static void OutputTextItem( AstChannel *, const char *, int * );
-static void PutChannelData( AstChannel *, void *, int * );
-static void PutNextText( AstChannel *, const char *, int * );
-static void ReadClassData( AstChannel *, const char *, int * );
-static void RemoveValue( AstChannelValue *, AstChannelValue **, int * );
-static void SetAttrib( AstObject *, const char *, int * );
-static void SetComment( AstChannel *, int, int * );
-static void SetFull( AstChannel *, int, int * );
-static void SetSkip( AstChannel *, int, int * );
-static void SetStrict( AstChannel *, int, int * );
-static void SinkWrap( void (*)( const char * ), const char *, int * );
-static void Unquote( AstChannel *, char *, int * );
-static void WriteBegin( AstChannel *, const char *, const char *, int * );
-static void WriteDouble( AstChannel *, const char *, int, int, double, const char *, int * );
-static void WriteEnd( AstChannel *, const char *, int * );
-static void WriteInt( AstChannel *, const char *, int, int, int, const char *, int * );
-static void WriteIsA( AstChannel *, const char *, const char *, int * );
-static void WriteObject( AstChannel *, const char *, int, int, AstObject *, const char *, int * );
-static void WriteString( AstChannel *, const char *, int, int, const char *, const char *, int * );
-
-static int GetReportLevel( AstChannel *, int * );
-static int TestReportLevel( AstChannel *, int * );
-static void ClearReportLevel( AstChannel *, int * );
-static void SetReportLevel( AstChannel *, int, int * );
-
-static int GetIndent( AstChannel *, int * );
-static int TestIndent( AstChannel *, int * );
-static void ClearIndent( AstChannel *, int * );
-static void SetIndent( AstChannel *, int, int * );
-
-static const char *GetSourceFile( AstChannel *, int * );
-static int TestSourceFile( AstChannel *, int * );
-static void ClearSourceFile( AstChannel *, int * );
-static void SetSourceFile( AstChannel *, const char *, int * );
-
-static const char *GetSinkFile( AstChannel *, int * );
-static int TestSinkFile( AstChannel *, int * );
-static void ClearSinkFile( AstChannel *, int * );
-static void SetSinkFile( AstChannel *, const char *, int * );
-
-/* Member functions. */
-/* ================= */
-static void AddWarning( AstChannel *this, int level, const char *msg,
- const char *method, int *status ) {
-/*
-*+
-* Name:
-* astAddWarning
-
-* Purpose:
-* Add a warning to a Channel.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "channel.h"
-* void astAddWarning( AstChannel *this, int level, const char *msg,
-* const char *method, int status, ... )
-
-* Class Membership:
-* Channel method.
-
-* Description:
-* This function stores a warning message inside a Channel. These
-* messages can be retirieved using astWarnings.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-* level
-* Ignore the warning if the ReportLevel attribute value is less
-* than "level".
-* msg
-* The wanting message to store. It may contain printf format
-* specifiers. If a NULL pointer is supplied, all warnings
-* currently stored in the Channel are removed.
-* method
-* The method name.
-* status
-* Inherited status value.
-* ...
-* Extra values to substitute into the message string as
-* replacements for the printf format specifiers.
-*-
-
-* Note: The expansion of the printf format specifiers is done in the
-* astAddWarning_ wrapper function. The AddWarning functions defined by
-* each class receives the fully expanded message and does not have a
-* variable argument list. The variable argument list is included in the
-* above prologue in order to document the wrapper function.
-
-*/
-
-/* Local Variables: */
- int i; /* Message index */
- char *a; /* Pointer to copy of message */
-
-/* If a NULL pointer was supplied, free all warnings currently in the
- Channel. Do this before checking the inherited status so that it works
- even if an error has occurred. */
- if( !msg ) {
- for( i = 0; i < this->nwarn; i++ ) {
- (this->warnings)[ i ] = astFree( (this->warnings)[ i ] );
- }
- this->warnings = astFree( this->warnings );
- this->nwarn = 0;
- return;
- }
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Only proceed if the message level is sufficiently important. */
- if( astGetReportLevel( this ) >= level ) {
-
-/* If we are being strict, issue an error rather than a warning. */
- if( astGetStrict( this ) ) {
- if( astOK ) {
- astError( AST__BADIN, "%s(%s): %s", status, method,
- astGetClass( this ), msg );
- }
-
-/* Otherwise, we store a copy of the message in the Channel. */
- } else {
-
-/* Allocate memory and store a copy of th supplied string in it. */
- a = astStore( NULL, msg, strlen( msg ) + 1 );
-
-/* Expand the array of warning pointers in ther Channel structure. */
- this->warnings = astGrow( this->warnings, this->nwarn + 1,
- sizeof( char * ) );
-
-/* If all is OK so far, store the new warning pointer, and increment the
- number of warnings in the Channel. */
- if( astOK ) {
- (this->warnings)[ (this->nwarn)++ ] = a;
-
-/* Otherwise, attempt to free the memory holding the copy of the warning. */
- } else {
- a = astFree( a );
- }
- }
- }
-}
-
-static void AppendValue( AstChannelValue *value, AstChannelValue **head, int *status ) {
-/*
-* Name:
-* AppendValue
-
-* Purpose:
-* Append a Value structure to a list.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "channel.h"
-* void AppendValue( AstChannelValue *value, AstChannelValue **head, int *status )
-
-* Class Membership:
-* Channel member function.
-
-* Description:
-* This function appends a Value structure to a doubly linked
-* circular list of such structures. The new list element is
-* inserted just in front of the element occupying the "head of
-* list" position (i.e. it becomes the new last element in the
-* list).
-
-* Parameters:
-* value
-* Pointer to the new element. This must not already be in the
-* list.
-* head
-* Address of a pointer to the element at the head of the list
-* (this pointer should be NULL if the list is initially
-* empty). This pointer will only be updated if a new element is
-* being added to an empty list.
-* status
-* Pointer to the inherited status variable.
-
-* Notes:
-* - This function does not perform error chacking and does not
-* generate errors.
-*/
-
-/* If the list is initially empty, the sole new element points at
- itself. */
- if ( !*head ) {
- value->flink = value;
- value->blink = value;
-
-/* Update the list head to identify the new element. */
- *head = value;
-
-/* Otherwise, insert the new element in front of the element at the
- head of the list. */
- } else {
- value->flink = *head;
- value->blink = ( *head )->blink;
- ( *head )->blink = value;
- value->blink->flink = value;
- }
-}
-
-void *astChannelData_( void ) {
-/*
-c++
-* Name:
-* astChannelData
-
-* Purpose:
-* Return a pointer to user-supplied data stored with a Channel.
-
-* Type:
-* Public macro.
-
-* Synopsis:
-* #include "channel.h"
-* void *astChannelData
-
-* Class Membership:
-* Channel macro.
-
-* Description:
-* This macro is intended to be used within the source or sink
-* functions associated with a Channel. It returns any pointer
-* previously stored in the Channel (that is, the Channel that has
-* invoked the source or sink function) using astPutChannelData.
-*
-* This mechanism is a thread-safe alternative to passing file
-* descriptors, etc, via static global variables.
-
-* Returned Value:
-* astChannelData
-* The pointer previously stored with the Channel using
-* astPutChannelData. A NULL pointer will be returned if no such
-* pointer has been stored with the Channel.
-
-* Applicability:
-* Channel
-* This macro applies to all Channels.
-
-* Notes:
-* - This routine is not available in the Fortran 77 interface to
-* the AST library.
-c--
-*/
- astDECLARE_GLOBALS
- astGET_GLOBALS(NULL);
- return channel_data;
-}
-
-static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) {
-/*
-* Name:
-* ClearAttrib
-
-* Purpose:
-* Clear an attribute value for a Channel.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "channel.h"
-* void ClearAttrib( AstObject *this, const char *attrib, int *status )
-
-* Class Membership:
-* Channel member function (over-rides the astClearAttrib protected
-* method inherited from the Object class).
-
-* Description:
-* This function clears the value of a specified attribute for a
-* Channel, so that the default value will subsequently be used.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-* 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: */
- AstChannel *this; /* Pointer to the Channel structure */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the Channel structure. */
- this = (AstChannel *) this_object;
-
-/* Check the attribute name and clear the appropriate attribute. */
-
-/* Comment. */
-/* -------- */
- if ( !strcmp( attrib, "comment" ) ) {
- astClearComment( this );
-
-/* Full. */
-/* ----- */
- } else if ( !strcmp( attrib, "full" ) ) {
- astClearFull( this );
-
-/* Indent. */
-/* ------- */
- } else if ( !strcmp( attrib, "indent" ) ) {
- astClearIndent( this );
-
-/* ReportLevel. */
-/* ------------ */
- } else if ( !strcmp( attrib, "reportlevel" ) ) {
- astClearReportLevel( this );
-
-/* Skip. */
-/* ----- */
- } else if ( !strcmp( attrib, "skip" ) ) {
- astClearSkip( this );
-
-/* SourceFile. */
-/* ----------- */
- } else if ( !strcmp( attrib, "sourcefile" ) ) {
- astClearSourceFile( this );
-
-/* SinkFile. */
-/* --------- */
- } else if ( !strcmp( attrib, "sinkfile" ) ) {
- astClearSinkFile( this );
-
-/* Strict. */
-/* ------- */
- } else if ( !strcmp( attrib, "strict" ) ) {
- astClearStrict( 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 ClearValues( AstChannel *this, int *status ) {
-/*
-* Name:
-* ClearValues
-
-* Purpose:
-* Clear the current values list.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "channel.h"
-* void ClearValues( AstChannel *this, int *status )
-
-* Class Membership:
-* Channel member function.
-
-* Description:
-* This function clears any (un-read) Value structures remaining in
-* the current values list (i.e. at the current nesting level). It
-* should be invoked after all required values have been read.
-*
-* If the values list has not been read, or if any remaining values
-* are found (i.e. the list is not empty) then this indicates an
-* unrecognised input class or an input value that has not been
-* read by a class loader. This implies an error in the loader, or
-* bad input data, so an error is reported.
-*
-* All resources used by any remaining Value structures are freed
-* and the values list is left in an empty state.
-
-* Parameters:
-* this
-* Pointer to the Channel being read. This is only used for
-* constructing error messages. It must not be NULL.
-* status
-* Pointer to the inherited status variable.
-
-* Notes:
-* - This function attempts to execute even if the global error
-* status is set on entry, although no further error report will be
-* made if it subsequently fails under these circumstances.
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Declare the thread specific global data */
- AstChannelValue **head; /* Address of pointer to values list */
- AstChannelValue *value; /* Pointer to value list element */
-
-/* Get a pointer to the structure holding thread-specific global data. */
- astGET_GLOBALS(this);
-
-/* If "values_class" is non-NULL, then the values list has previously
- been filled with Values for a class. */
- if ( values_class[ nest ] ) {
-
-/* If "values_ok" is zero, however, then these Values have not yet
- been read by a class loader. This must be due to a bad class name
- associated with them or because the class data are not available in
- the correct order. If we are using strict error reporting, then report
- an error (unless the error status is already set). */
- if ( astGetStrict( this ) && !values_ok[ nest ] && astOK ) {
- astError( AST__BADIN,
- "astRead(%s): Invalid class structure in input data.", status,
- astGetClass( this ) );
- astError( AST__BADIN,
- "Class \"%s\" is invalid or out of order within a %s.", status,
- values_class[ nest ], object_class[ nest ] );
- }
-
-/* Free the memory holding the class string. */
- values_class[ nest ] = astFree( values_class[ nest ] );
- }
-
-/* Reset the "values_ok" flag. */
- values_ok[ nest ] = 0;
-
-/* Now clear any Values remaining in the values list. Obtain the
- address of the pointer to the head of this list (at the current
- nesting level) and loop to remove Values from the list while it is
- not empty. */
- head = values_list + nest;
- while ( *head ) {
-
-/* Obtain a pointer to the first element. */
- value = *head;
-
-/* Issue a warning. */
- if ( value->is_object ) {
- astAddWarning( this, 1, "The Object \"%s = <%s>\" was "
- "not recognised as valid input.", "astRead", status,
- value->name, astGetClass( value->ptr.object ) );
- } else {
- astAddWarning( this, 1, "The value \"%s = %s\" was not "
- "recognised as valid input.", "astRead", status,
- value->name, value->ptr.string );
- }
-
-/* Remove the Value structure from the list (which updates the head of
- list pointer) and free its resources. */
- RemoveValue( value, head, status );
- value = FreeValue( value, status );
- }
-}
-
-static AstChannelValue *FreeValue( AstChannelValue *value, int *status ) {
-/*
-* Name:
-* FreeValue
-
-* Purpose:
-* Free a dynamically allocated Value structure.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "channel.h"
-* AstChannelValue *FreeValue( AstChannelValue *value, int *status )
-
-* Class Membership:
-* Channel member function.
-
-* Description:
-* This function frees a dynamically allocated Value structure,
-* releasing all resources used by it. The structure contents must
-* have been correctly initialised.
-
-* Parameters:
-* value
-* Pointer to the Value structure to be freed.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A NULL pointer is always returned.
-
-* Notes:
-* - This function attempts to execute even if the global error
-* status is set on entry, although no further error report will be
-* made if it subsequently fails under these circumstances.
-*/
-
-/* Check that a non-NULL pointer has been supplied. */
- if ( value ) {
-
-/* If the "name" component has been allocated, then free it. */
- if ( value->name ) value->name = astFree( value->name );
-
-/* If the "ptr" component identifies an Object, then annul the Object
- pointer. */
- if ( value->is_object ) {
- if ( value->ptr.object ) {
- value->ptr.object = astAnnul( value->ptr.object );
- }
-
-/* Otherwise, if it identifies a string, then free the string. */
- } else {
- if ( value->ptr.string ) {
- value->ptr.string = astFree( value->ptr.string );
- }
- }
-
-/* Free the Value structure itself. */
- value = astFree( value );
- }
-
-/* Return a NULL pointer. */
- return NULL;
-}
-
-static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) {
-/*
-* Name:
-* GetAttrib
-
-* Purpose:
-* Get the value of a specified attribute for a Channel.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "channel.h"
-* const char *GetAttrib( AstObject *this, const char *attrib, int *status )
-
-* Class Membership:
-* Channel member function (over-rides the protected astGetAttrib
-* method inherited from the Object class).
-
-* Description:
-* This function returns a pointer to the value of a specified
-* attribute for a Channel, formatted as a character string.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-* 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 Channel, 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 Channel. 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 /* Declare the thread specific global data */
- AstChannel *this; /* Pointer to the Channel structure */
- const char *result; /* Pointer value to return */
- int comment; /* Comment attribute value */
- int full; /* Full attribute value */
- int indent; /* Indent attribute value */
- int report_level; /* ReportLevel attribute value */
- int skip; /* Skip attribute value */
- int strict; /* Report errors insead of warnings? */
-
-/* Initialise. */
- result = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Get a pointer to the structure holding thread-specific global data. */
- astGET_GLOBALS(this_object);
-
-/* Obtain a pointer to the Channel structure. */
- this = (AstChannel *) 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. */
-
-/* Comment. */
-/* -------- */
- if ( !strcmp( attrib, "comment" ) ) {
- comment = astGetComment( this );
- if ( astOK ) {
- (void) sprintf( getattrib_buff, "%d", comment );
- result = getattrib_buff;
- }
-
-/* Full. */
-/* ----- */
- } else if ( !strcmp( attrib, "full" ) ) {
- full = astGetFull( this );
- if ( astOK ) {
- (void) sprintf( getattrib_buff, "%d", full );
- result = getattrib_buff;
- }
-
-/* Indent. */
-/* ------- */
- } else if ( !strcmp( attrib, "indent" ) ) {
- indent = astGetIndent( this );
- if ( astOK ) {
- (void) sprintf( getattrib_buff, "%d", indent );
- result = getattrib_buff;
- }
-
-/* ReportLevel. */
-/* ------------ */
- } else if ( !strcmp( attrib, "reportlevel" ) ) {
- report_level = astGetReportLevel( this );
- if ( astOK ) {
- (void) sprintf( getattrib_buff, "%d", report_level );
- result = getattrib_buff;
- }
-
-/* Skip. */
-/* ----- */
- } else if ( !strcmp( attrib, "skip" ) ) {
- skip = astGetSkip( this );
- if ( astOK ) {
- (void) sprintf( getattrib_buff, "%d", skip );
- result = getattrib_buff;
- }
-
-/* SourceFile. */
-/* ----------- */
- } else if ( !strcmp( attrib, "sourcefile" ) ) {
- result = astGetSourceFile( this );
-
-/* SinkFile. */
-/* --------- */
- } else if ( !strcmp( attrib, "sinkfile" ) ) {
- result = astGetSinkFile( this );
-
-/* Strict. */
-/* ------- */
- } else if ( !strcmp( attrib, "strict" ) ) {
- strict = astGetStrict( this );
- if ( astOK ) {
- (void) sprintf( getattrib_buff, "%d", strict );
- 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 void GetNextData( AstChannel *this, int skip, char **name,
- char **val, int *status ) {
-/*
-*+
-* Name:
-* astGetNextData
-
-* Purpose:
-* Read the next item of data from a data source.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "channel.h"
-* void astGetNextData( AstChannel *this, int skip, char **name,
-* char **val )
-
-* Class Membership:
-* Channel method.
-
-* Description:
-* This function reads the next item of input data from a data
-* source associated with a Channel and returns the result.
-*
-* It is layered conceptually on the astGetNextText method, but
-* instead of returning the raw input text, it decodes it and
-* returns name/value pairs ready for use. Note that in some
-* derived classes, where the data are not stored as text, this
-* function may not actually use astGetNextText, but will access
-* the data directly.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-* skip
-* A non-zero value indicates that a new Object is to be read,
-* and that all input data up to the next "Begin" item are to be
-* skipped in order to locate it. This is useful if the data
-* source contains AST objects interspersed with other data (but
-* note that these other data cannot appear inside AST Objects,
-* only between them).
-*
-* A zero value indicates that all input data are significant
-* and the next item will therefore be read and an attempt made
-* to interpret it whatever it contains. Any other data
-* inter-mixed with AST Objects will then result in an error.
-* name
-* An address at which to store a pointer to a null-terminated
-* dynamically allocated string containing the name of the next
-* item in the input data stream. This name will be in lower
-* case with no surrounding white space. It is the callers
-* responsibilty to free the memory holding this string (using
-* astFree) when it is no longer required.
-*
-* A NULL pointer value will be returned (without error) to
-* indicate when there are no further input data items to be
-* read.
-* val
-* An address at which to store a pointer to a null-terminated
-* dynamically allocated string containing the value associated
-* with the next item in the input data stream. No case
-* conversion is performed on this string and all white space is
-* potentially significant. It is the callers responsibilty to
-* free the memory holding this string (using astFree) when it
-* is no longer required.
-*
-* The returned pointer will be NULL if an Object data item is
-* read (see the "Data Representation" section).
-
-* Data Representation:
-* The returned data items fall into the following categories:
-*
-* - Begin: Identified by the name string "begin", this indicates
-* the start of an Object definition. The associated value string
-* gives the class name of the Object being defined.
-*
-* - IsA: Identified by the name string "isa", this indicates the
-* end of the data associated with a particular class structure
-* within the definiton of a larger Object. The associated value
-* string gives the name of the class whose data have just been
-* read.
-*
-* - End: Identified by the name string "end", this indicates the
-* end of the data associated with a complete Object
-* definition. The associated value string gives the class name of
-* the Object whose definition is being ended.
-*
-* - Non-Object: Identified by any other name string plus a
-* non-NULL "val" pointer, this gives the value of a non-Object
-* structure component (instance variable). The name identifies
-* which instance variable it is (within the context of the class
-* whose data are being read) and the value is encoded as a string.
-*
-* - Object: Identified by any other name string plus a NULL "val"
-* pointer, this identifies the value of an Object structure
-* component (instance variable). The name identifies which
-* instance variable it is (within the context of the class whose
-* data are being read) and the value is given by subsequent data
-* items (so the next item should be a "Begin" item).
-
-* Notes:
-* - NULL pointer values will be returned if this function is
-* invoked with the global error status set, or if it should fail
-* for any reason.
-* - This method is provided primarily so that derived classes may
-* over-ride it in order to read from alternative data sources. It
-* provides a higher-level interface than astGetNextText, so is
-* suitable for classes that either need to read textual data in a
-* different format, or to read from non-textual data sources.
-*-
-*/
-
-/* Local Variables: */
- char *line; /* Pointer to input text line */
- int done; /* Data item read? */
- int i; /* Loop counter for string characters */
- int len; /* Length of input text line */
- int nc1; /* Offset to start of first field */
- int nc2; /* Offset to end of first field */
- int nc3; /* Offset to start of second field */
- int nc; /* Number of charaters read by "astSscanf" */
-
-/* Initialise the returned values. */
- *name = NULL;
- *val = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Read the next input line as text (the loop is needed to allow
- initial lines to be skipped if the "skip" flag is set). */
- done = 0;
- while ( !done && ( line = InputTextItem( this, status ) ) && astOK ) {
-
-/* If OK, determine the line length. */
- len = strlen( line );
-
-/* Non-Object value. */
-/* ----------------- */
-/* Test for lines of the form " name = value" (or similar), where the
- name is no more than MAX_NAME characters long (the presence of a
- value on the right hand side indicates that this is a non-Object
- value, encoded as a string). Ignore these lines if the "skip" flag
- is set. */
- if ( nc = 0,
- ( !skip
- && ( 0 == astSscanf( line,
- " %n%*" MAX_NAME "[^ \t=]%n = %n%*[^\n]%n",
- &nc1, &nc2, &nc3, &nc ) )
- && ( nc >= len ) ) ) {
-
-/* Note we have found a data item. */
- done = 1;
-
-/* Extract the name and value fields. */
- *name = astString( line + nc1, nc2 - nc1 );
- *val = astString( line + nc3, len - nc3 );
-
-/* If OK, truncate the value to remove any trailing white space. */
- if ( astOK ) {
- i = len - nc3 - 1;
- while ( ( i >= 0 ) && isspace( ( *val )[ i ] ) ) i--;
- ( *val )[ i + 1 ] = '\0';
-
-/* Also remove any quotes from the string. */
- Unquote( this, *val, status );
- }
-
-/* Object value. */
-/* ------------- */
-/* Test for lines of the form " name = " (or similar), where the name
- is no more than MAX_NAME characters long (the absence of a value on
- the right hand side indicates that this is an Object, whose
- definition follows on subsequent input lines). Ignore these lines
- if the "skip" flag is set. */
- } else if ( nc = 0,
- ( !skip
- && ( 0 == astSscanf( line,
- " %n%*" MAX_NAME "[^ \t=]%n = %n",
- &nc1, &nc2, &nc ) )
- && ( nc >= len ) ) ) {
-
-/* Note we have found a data item. */
- done = 1;
-
-/* Extract the name field but leave the value pointer as NULL. */
- *name = astString( line + nc1, nc2 - nc1 );
-
-/* Begin. */
-/* ------ */
-/* Test for lines of the form " Begin Class " (or similar). */
- } else if ( nc = 0,
- ( ( 0 == astSscanf( line,
- " %*1[Bb]%*1[Ee]%*1[Gg]%*1[Ii]%*1[Nn] %n%*s%n %n",
- &nc1, &nc2, &nc ) )
- && ( nc >= len ) ) ) {
-
-/* Note we have found a data item. */
- done = 1;
-
-/* Set the returned name to "begin" and extract the associated class
- name for the value. Store both of these in dynamically allocated
- strings. */
- *name = astString( "begin", 5 );
- *val = astString( line + nc1, nc2 - nc1 );
-
-/* IsA. */
-/* ---- */
-/* Test for lines of the form " IsA Class " (or similar). Ignore these
- lies if the "skip" flag is set. */
- } else if ( nc = 0,
- ( !skip
- && ( 0 == astSscanf( line,
- " %*1[Ii]%*1[Ss]%*1[Aa] %n%*s%n %n",
- &nc1, &nc2, &nc ) )
- && ( nc >= len ) ) ) {
-
-/* Note we have found a data item. */
- done = 1;
-
-/* Set the returned name to "isa" and extract the associated class
- name for the value. */
- *name = astString( "isa", 3 );
- *val = astString( line + nc1, nc2 - nc1 );
-
-/* End. */
-/* ---- */
-/* Test for lines of the form " End Class " (or similar). Ignore these
- lines if the "skip" flag is set. */
- } else if ( nc = 0,
- ( !skip
- && ( 0 == astSscanf( line,
- " %*1[Ee]%*1[Nn]%*1[Dd] %n%*s%n %n",
- &nc1, &nc2, &nc ) )
- && ( nc >= len ) ) ) {
-
-/* Note we have found a data item. */
- done = 1;
-
-/* If found, set the returned name to "end" and extract the associated
- class name for the value. */
- *name = astString( "end", 3 );
- *val = astString( line + nc1, nc2 - nc1 );
-
-/* If the input line didn't match any of the above and the "skip" flag
- is not set, then report an error. */
- } else if ( !skip ) {
- astError( AST__BADIN,
- "astRead(%s): Cannot interpret the input data: \"%s\".", status,
- astGetClass( this ), line );
- }
-
-/* Free the memory holding the input data as text. */
- line = astFree( line );
- }
-
-/* If successful, convert the name to lower case. */
- if ( astOK && *name ) {
- for ( i = 0; ( *name )[ i ]; i++ ) {
- ( *name )[ i ] = tolower( ( *name )[ i ] );
- }
- }
-
-/* If an error occurred, ensure that any memory allocated is freed and
- that NULL pointer values are returned. */
- if ( !astOK ) {
- *name = astFree( *name );
- *val = astFree( *val );
- }
-}
-
-static char *GetNextText( AstChannel *this, int *status ) {
-/*
-*+
-* Name:
-* GetNextText
-
-* Purpose:
-* Read the next line of input text from a data source.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "channel.h"
-* char *astGetNextText( AstChannel *this )
-
-* Class Membership:
-* Channel method.
-
-* Description:
-* This function reads the next "raw" input line of text from the
-* data source associated with a Channel.
-*
-* Each line is returned as a pointer to a null-terminated string
-* held in dynamic memory, and it is the caller's responsibility to
-* free this memory (using astFree) when it is no longer
-* required. A NULL pointer is returned if there are no more input
-* lines to be read.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-
-* Returned Value:
-* Pointer to a null-terminated string containing the input line
-* (held in dynamically allocated memory, which must be freed by
-* the caller when no longer required). A NULL pointer is returned
-* if there are no more input lines to be read.
-
-* 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.
-* - This method is provided primarily so that derived classes may
-* over-ride it in order to read from alternative (textual) data
-* sources.
-*-
-*/
-
-/* Local Constants: */
-#define MIN_CHARS 81 /* Initial size for allocating memory */
-#define ERRBUF_LEN 80
-
-/* Local Variables: */
- FILE *fd; /* Input file descriptor */
- char *errstat; /* Pointer for system error message */
- char *line; /* Pointer to line data to be returned */
- char errbuf[ ERRBUF_LEN ]; /* Buffer for system error message */
- const char *sink_file; /* Path to output sink file */
- const char *source_file; /* Path to source file */
- int c; /* Input character */
- int len; /* Length of input line */
- int readstat; /* "errno" value set by "getchar" */
- int size; /* Size of allocated memory */
-
-/* Initialise. */
- line = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return line;
-
-/* If the SourceFile attribute of the Channel specifies an input file,
- but no input file has yet been opened, open it now. Report an error if
- it is the same as the sink file. */
- if( astTestSourceFile( this ) && !this->fd_in ) {
- source_file = astGetSourceFile( this );
-
- if( this->fd_out ) {
- sink_file = astGetSinkFile( this );
- if( astOK && !strcmp( sink_file, source_file ) ) {
- astError( AST__RDERR, "astRead(%s): Failed to open input "
- "SourceFile '%s' - the file is currently being used "
- "as the output SinkFile.", status, astGetClass( this ),
- source_file );
- }
- }
-
- if( astOK ) {
- this->fd_in = fopen( source_file, "r" );
- if( !this->fd_in ) {
- if ( errno ) {
-#if HAVE_STRERROR_R
- strerror_r( errno, errbuf, ERRBUF_LEN );
- errstat = errbuf;
-#else
- errstat = strerror( errno );
-#endif
- astError( AST__RDERR, "astRead(%s): Failed to open input "
- "SourceFile '%s' - %s.", status, astGetClass( this ),
- source_file, errstat );
- } else {
- astError( AST__RDERR, "astRead(%s): Failed to open input "
- "SourceFile '%s'.", status, astGetClass( this ),
- source_file );
- }
- }
-
- }
- }
-
-/* Source function defined, but no input file. */
-/* ------------------------------------------- */
-/* If no active input file descriptor is stored in the Channel, but
- a source function (and its wrapper function) is defined for the
- Channel, use the wrapper function to invoke the source function to
- read a line of input text. This is returned in a dynamically
- allocated string. */
- if ( !this->fd_in && this->source && this->source_wrap ) {
-
-/* About to call an externally supplied function which may not be
- thread-safe, so lock a mutex first. Also store the channel data
- pointer in a global variable so that it can be accessed in the source
- function using macro astChannelData. */
- astStoreChannelData( this );
- LOCK_MUTEX3;
- line = ( *this->source_wrap )( this->source, status );
- UNLOCK_MUTEX3;
-
-/* Input file defined, or no source function. */
-/* ------------------------------------------ */
-/* Read the line from the input file or from standard input. */
- } else if( astOK ) {
- c = '\0';
- len = 0;
- size = 0;
-
-/* Choose the file descriptor to use. */
- fd = this->fd_in ? this->fd_in : stdin;
-
-/* Loop to read input characters, saving any "errno" value that may be
- set by "getchar" if an error occurs. Quit if an end of file (or
- error) occurs or if a newline character is read. */
- while ( errno = 0, c = getc( fd ), readstat = errno,
- ( c != EOF ) && ( c != '\n' ) ) {
-
-/* If no memory has yet been allocated to hold the line, allocate some
- now, using MIN_CHARS as the initial line length. */
- if ( !line ) {
- line = astMalloc( sizeof( char ) * (size_t) MIN_CHARS );
- size = MIN_CHARS;
-
-/* If memory has previously been allocated, extend it when necessary
- to hold the new input character (plus a terminating null) and note
- the new size. */
- } else if ( ( len + 2 ) > size ) {
- line = astGrow( line, len + 2, sizeof( char ) );
- if ( !astOK ) break;
- size = (int) astSizeOf( line );
- }
-
-/* Store the character just read. */
- line[ len++ ] = c;
- }
-
-/* If the above loop completed without setting the global error
- status, check the last character read and use "ferror" to see if a
- read error occurred. If so, report the error, using the saved
- "errno" value (but only if one was set). */
- if ( astOK && ( c == EOF ) && ferror( fd ) ) {
- if ( readstat ) {
-#if HAVE_STRERROR_R
- strerror_r( readstat, errbuf, ERRBUF_LEN );
- errstat = errbuf;
-#else
- errstat = strerror( readstat );
-#endif
- astError( AST__RDERR,
- "astRead(%s): Read error on standard input - %s.", status,
- astGetClass( this ), errstat );
- } else {
- astError( AST__RDERR,
- "astRead(%s): Read error on standard input.", status,
- astGetClass( this ) );
- }
- }
-
-/* If an empty line has been read, allocate memory to hold an empty
- string. */
- if ( !line && ( c == '\n' ) ) {
- line = astMalloc( sizeof( char ) );
- }
-
-/* If memory has been allocated and there has been no error,
- null-terminate the string of input characters. */
- if ( line ) {
- if ( astOK ) {
- line[ len ] = '\0';
-
-/* If there has been an error, free the allocated memory. */
- } else {
- line = astFree( line );
- }
- }
- }
-
-
-/* Return the result pointer. */
- return line;
-
-/* Undefine macros local to this function. */
-#undef MIN_CHARS
-#undef ERRBUF_LEN
-}
-
-static AstKeyMap *Warnings( AstChannel *this, int *status ){
-/*
-*++
-* Name:
-c astWarnings
-f AST_WARNINGS
-
-* Purpose:
-* Returns any warnings issued by the previous read or write operation.
-
-* Type:
-* Public virtual function.
-
-* Synopsis:
-c #include "channel.h"
-c AstKeyMap *astWarnings( AstChannel *this )
-f RESULT = AST_WARNINGS( THIS, STATUS )
-
-* Class Membership:
-* Channel member function.
-
-* Description:
-* This function returns an AST KeyMap object holding the text of any
-* warnings issued as a result of the previous invocation of the
-c astRead or astWrite
-f AST_READ or AST_WRITE
-* function on the Channel. If no warnings were issued, a
-c a NULL value
-f AST__NULL
-* will be returned.
-*
-* Such warnings are non-fatal and will not prevent the
-* read or write operation succeeding. However, the converted object
-* may not be identical to the original object in all respects.
-* Differences which would usually be deemed as insignificant in most
-* usual cases will generate a warning, whereas more significant
-* differences will generate an error.
-*
-* The "Strict" attribute allows this warning facility to be switched
-* off, so that a fatal error is always reported for any conversion
-* error.
-
-* Parameters:
-c this
-f THIS = INTEGER (Given)
-* Pointer to the Channel.
-f STATUS = INTEGER (Given and Returned)
-f The global status.
-
-* Returned Value:
-c astWarnings()
-f AST_WARNINGS = INTEGER
-* A pointer to the KeyMap holding the warning messages, or
-c NULL
-f AST__NULL
-* if no warnings were issued during the previous read operation.
-
-* Applicability:
-* Channel
-* The basic Channel class generates a warning when ever an
-* un-recognised item is encountered whilst reading an Object from
-* an external data source. If Strict is zero (the default), then
-* unexpected items in the Object description are simply ignored,
-* and any remaining items are used to construct the returned
-* Object. If Strict is non-zero, an error will be reported and a
-* NULL Object pointer returned if any unexpected items are
-* encountered.
-*
-* As AST continues to be developed, new attributes are added
-* occasionally to selected classes. If an older version of AST is
-* used to read external Object descriptions created by a more
-* recent version of AST, then the Channel class will, by default,
-* ignore the new attributes, using the remaining attributes to
-* construct the Object. This is usually a good thing. However,
-* since external Object descriptions are often stored in plain
-* text, it is possible to edit them using a text editor. This
-* gives rise to the possibility of genuine errors in the
-* description due to finger-slips, typos, or simple
-* mis-understanding. Such inappropriate attributes will be ignored
-* if Strict is left at its default zero value. This will cause the
-* mis-spelled attribute to revert to its default value,
-* potentially causing subtle changes in the behaviour of
-* application software. If such an effect is suspected, the Strict
-* attribute can be set non-zero, resulting in the erroneous
-* attribute being identified in an error message.
-* FitsChan
-* The returned KeyMap will contain warnings for all conditions
-* listed in the Warnings attribute.
-* XmlChan
-* Reports conversion errors that result in what are usally
-* insignificant changes.
-
-* Notes:
-* - The returned KeyMap uses keys of the form "Warning_1",
-* "Warning_2", etc.
-* - A value of
-c NULL will be returned if this function is invoked with the AST
-c error status set,
-f AST__NULL will be returned if this function is invoked with STATUS
-f set to an error value,
-* or if it should fail for any reason.
-*--
-*/
-
-/* Local Variables: */
- AstKeyMap *result;
- char key[ 20 ];
- int i;
-
-/* Check the global status, and supplied keyword name. */
- result = NULL;
- if( !astOK ) return result;
-
-/* Check there are some warnings to return. */
- if( this->nwarn && this->warnings ) {
-
-/* Create the KeyMap. */
- result = astKeyMap( "", status );
-
-/* Loop round all warnings, adding them into the KeyMap. */
- for( i = 0; i < this->nwarn; i++ ){
- sprintf( key, "Warning_%d", i + 1 );
- astMapPut0C( result, key, (this->warnings)[ i ], " " );
- }
- }
-
-/* Return the KeyMap. */
- return result;
-}
-
-AstChannel *astInitChannel_( void *mem, size_t size, int init,
- AstChannelVtab *vtab, const char *name,
- const char *(* source)( void ),
- char *(* source_wrap)( const char *(*)( void ), int * ),
- void (* sink)( const char * ),
- void (* sink_wrap)( void (*)( const char * ),
- const char *, int * ), int *status ) {
-/*
-*+
-* Name:
-* astInitChannel
-
-* Purpose:
-* Initialise a Channel.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "channel.h"
-* AstChannel *astInitChannel( void *mem, size_t size, int init,
-* AstChannelVtab *vtab, const char *name,
-* const char *(* source)( void ),
-* char *(* source_wrap)( const char *(*)( void ), int * ),
-* void (* sink)( const char * ),
-* void (* sink_wrap)( void (*)( const char * ),
-* const char *, int * ) )
-
-* Class Membership:
-* Channel initialiser.
-
-* Description:
-* This function is provided for use by class implementations to
-* initialise a new Channel object. It allocates memory (if
-* necessary) to accommodate the Channel plus any additional data
-* associated with the derived class. It then initialises a
-* Channel 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 Channel at the start of the memory passed
-* via the "vtab" parameter.
-
-* Parameters:
-* mem
-* A pointer to the memory in which the Channel is to be
-* initialised. This must be of sufficient size to accommodate
-* the Channel data (sizeof(Channel)) 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 Channel (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 Channel structure, so a valid value must be
-* supplied even if not required for allocating memory.
-* init
-* A boolean flag indicating if the Channel'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 Channel.
-* 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).
-* source
-* Pointer to a "source" function which will be used to obtain
-* lines of input text. Generally, this will be obtained by
-* casting a pointer to a source function which is compatible
-* with the "source_wrap" wrapper function (below). The pointer
-* should later be cast back to its original type by the
-* "source_wrap" function before the function is invoked.
-*
-* If "source" is NULL, the Channel will read from standard
-* input instead.
-* source_wrap
-* Pointer to a function which can be used to invoke the
-* "source" function supplied (above). This wrapper function is
-* necessary in order to hide variations in the nature of the
-* source function, such as may arise when it is supplied by a
-* foreign (non-C) language interface.
-*
-* The single parameter of the "source_wrap" function is a
-* pointer to the "source" function, and it should cast this
-* function pointer (as necessary) and invoke the function with
-* appropriate arguments to obtain the next line of input
-* text. The "source_wrap" function should then return a pointer
-* to a dynamically allocated, null terminated string containing
-* the text that was read. The string will be freed (using
-* astFree) when no longer required and the "source_wrap"
-* function need not concern itself with this. A NULL pointer
-* should be returned if there is no more input to read.
-*
-* If "source_wrap" is NULL, the Channel will read from standard
-* input instead.
-* sink
-* Pointer to a "sink" function which will be used to deliver
-* lines of output text. Generally, this will be obtained by
-* casting a pointer to a sink function which is compatible with
-* the "sink_wrap" wrapper function (below). The pointer should
-* later be cast back to its original type by the "sink_wrap"
-* function before the function is invoked.
-*
-* If "sink" is NULL, the Channel will write to standard output
-* instead.
-* sink_wrap
-* Pointer to a function which can be used to invoke the "sink"
-* function supplied (above). This wrapper function is necessary
-* in order to hide variations in the nature of the sink
-* function, such as may arise when it is supplied by a foreign
-* (non-C) language interface.
-*
-* The first parameter of the "sink_wrap" function is a pointer
-* to the "sink" function, and the second parameter is a pointer
-* to a const, null-terminated character string containing the
-* text to be written. The "sink_wrap" function should cast the
-* "sink" function pointer (as necessary) and invoke the
-* function with appropriate arguments to deliver the line of
-* output text. The "sink_wrap" function then returns void.
-*
-* If "sink_wrap" is NULL, the Channel will write to standard
-* output instead.
-
-* Returned Value:
-* A pointer to the new Channel.
-
-* 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: */
- AstChannel *new; /* Pointer to new Channel */
-
-/* Check the global status. */
- if ( !astOK ) return NULL;
-
-/* If necessary, initialise the virtual function table. */
- if ( init ) astInitChannelVtab( vtab, name );
-
-/* Initialise an Object structure (the parent class) as the first
- component within the Channel structure, allocating memory if
- necessary. */
- new = (AstChannel *) astInitObject( mem, size, 0,
- (AstObjectVtab *) vtab, name );
-
- if ( astOK ) {
-
-/* Initialise the Channel data. */
-/* ---------------------------- */
-/* Save the pointers to the source and sink functions and the wrapper
- functions that invoke them. */
- new->source = source;
- new->source_wrap = source_wrap;
- new->sink = sink;
- new->sink_wrap = sink_wrap;
-
-/* Indicate no input or output files have been associated with the
- Channel. */
- new->fd_in = NULL;
- new->fn_in = NULL;
- new->fd_out = NULL;
- new->fn_out = NULL;
-
-/* Set all attributes to their undefined values. */
- new->comment = -INT_MAX;
- new->full = -INT_MAX;
- new->indent = -INT_MAX;
- new->report_level = -INT_MAX;
- new->skip = -INT_MAX;
- new->strict = -INT_MAX;
- new->data = NULL;
- new->warnings = NULL;
- new->nwarn = 0;
-
-/* If an error occurred, clean up by deleting the new object. */
- if ( !astOK ) new = astDelete( new );
- }
-
-/* Return a pointer to the new object. */
- return new;
-}
-
-void astInitChannelVtab_( AstChannelVtab *vtab, const char *name, int *status ) {
-/*
-*+
-* Name:
-* astInitChannelVtab
-
-* Purpose:
-* Initialise a virtual function table for a Channel.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "channel.h"
-* void astInitChannelVtab( AstChannelVtab *vtab, const char *name )
-
-* Class Membership:
-* Channel vtab initialiser.
-
-* Description:
-* This function initialises the component of a virtual function
-* table which is used by the Channel 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 */
- AstObjectVtab *object; /* Pointer to Object component of Vtab */
-
-/* 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. */
- astInitObjectVtab( (AstObjectVtab *) vtab, name );
-
-/* Store a unique "magic" value in the virtual function table. This
- will be used (by astIsAChannel) 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 = &(((AstObjectVtab *) vtab)->id);
-
-/* Initialise member function pointers. */
-/* ------------------------------------ */
-/* Store pointers to the member functions (implemented here) that
- provide virtual methods for this class. */
- vtab->AddWarning = AddWarning;
- vtab->ClearComment = ClearComment;
- vtab->ClearFull = ClearFull;
- vtab->ClearSkip = ClearSkip;
- vtab->ClearStrict = ClearStrict;
- vtab->GetComment = GetComment;
- vtab->GetFull = GetFull;
- vtab->GetNextData = GetNextData;
- vtab->GetNextText = GetNextText;
- vtab->GetSkip = GetSkip;
- vtab->GetStrict = GetStrict;
- vtab->Warnings = Warnings;
- vtab->PutNextText = PutNextText;
- vtab->Read = Read;
- vtab->ReadClassData = ReadClassData;
- vtab->ReadDouble = ReadDouble;
- vtab->ReadInt = ReadInt;
- vtab->ReadObject = ReadObject;
- vtab->ReadString = ReadString;
- vtab->SetComment = SetComment;
- vtab->SetFull = SetFull;
- vtab->SetSkip = SetSkip;
- vtab->SetStrict = SetStrict;
- vtab->TestComment = TestComment;
- vtab->TestFull = TestFull;
- vtab->TestSkip = TestSkip;
- vtab->TestStrict = TestStrict;
- vtab->Write = Write;
- vtab->WriteBegin = WriteBegin;
- vtab->WriteDouble = WriteDouble;
- vtab->WriteEnd = WriteEnd;
- vtab->WriteInt = WriteInt;
- vtab->WriteIsA = WriteIsA;
- vtab->WriteObject = WriteObject;
- vtab->WriteString = WriteString;
- vtab->PutChannelData = PutChannelData;
-
- vtab->ClearReportLevel = ClearReportLevel;
- vtab->GetReportLevel = GetReportLevel;
- vtab->SetReportLevel = SetReportLevel;
- vtab->TestReportLevel = TestReportLevel;
-
- vtab->ClearIndent = ClearIndent;
- vtab->GetIndent = GetIndent;
- vtab->SetIndent = SetIndent;
- vtab->TestIndent = TestIndent;
-
- vtab->ClearSourceFile = ClearSourceFile;
- vtab->GetSourceFile = GetSourceFile;
- vtab->SetSourceFile = SetSourceFile;
- vtab->TestSourceFile = TestSourceFile;
-
- vtab->ClearSinkFile = ClearSinkFile;
- vtab->GetSinkFile = GetSinkFile;
- vtab->SetSinkFile = SetSinkFile;
- vtab->TestSinkFile = TestSinkFile;
-
-/* Save the inherited pointers to methods that will be extended, and
- replace them with pointers to the new member functions. */
- object = (AstObjectVtab *) vtab;
-
- 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;
-
-/* Declare the destructor and copy constructor. */
- astSetDelete( (AstObjectVtab *) vtab, Delete );
- astSetCopy( (AstObjectVtab *) vtab, Copy );
-
-/* Declare the Dump function for this class. There is no destructor or
- copy constructor. */
- astSetDump( vtab, Dump, "Channel", "Basic I/O Channel" );
-
-/* 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 char *InputTextItem( AstChannel *this, int *status ) {
-/*
-* Name:
-* InputTextItem
-
-* Purpose:
-* Read the next item from a data source as text.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "channel.h"
-* char *InputTextItem( AstChannel *this )
-
-* Class Membership:
-* Channel member function.
-
-* Description:
-* This function reads the next input data item as text from the
-* data source associated with a Channel. It is similar to the
-* astGetNextText method (which it invokes), except that it strips
-* off any comments along with leading and trailing white
-* space. Input lines which are empty or do not contain significant
-* characters (e.g. all comment) are skipped, so that only
-* significant lines are returned.
-*
-* Each line is returned as a pointer to a null-terminated string
-* held in dynamic memory, and it is the caller's responsibility to
-* free this memory (using astFree) when it is no longer
-* required. A NULL pointer is returned if there are no more input
-* lines to be read.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-
-* Returned Value:
-* Pointer to a null-terminated string containing the input line
-* (held in dynamically allocated memory, which must be freed by
-* the caller when no longer required). A NULL pointer is returned
-* if there are no more input lines to be read.
-
-* 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: */
- char *line; /* Pointer to line data to be returned */
- int i; /* Loop counter for line characters */
- int j; /* Counter for characters */
- int len; /* Length of result line */
- int nonspace; /* Non-space character encountered? */
- int quoted; /* Character is inside quotes? */
-
-/* Initialise. */
- line = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return line;
-
-/* Loop to read input lines until one is found which contains useful
- characters or end of file is reached (or a read error occurs). */
- while ( !line && ( line = astGetNextText( this ) ) && astOK ) {
-
-/* Loop to remove comments and leading and trailing white space. */
- len = 0;
- nonspace = 0;
- quoted = 0;
- for ( i = j = 0; line[ i ]; i++ ) {
-
-/* Note quote characters and ignore all text after the first unquoted
- comment character. */
- if ( line[ i ] == '"' ) quoted = !quoted;
- if ( ( line[ i ] == '#' ) && !quoted ) break;
-
-/* Note the first non-space character and ignore everything before
- it. */
- if ( ( nonspace = nonspace || !isspace( line[ i ] ) ) ) {
-
-/* Move each character to its new position in the string. */
- line[ j++ ] = line[ i ];
-
-/* Note the final length of the string (ignoring trailing spaces). */
- if ( !isspace( line[ i ] ) ) len = j;
- }
- }
-
-/* If the string is not empty, terminate it. */
- if ( len ) {
- line[ len ] = '\0';
-
-/* Otherwise, free the memory used for the string so that another
- input line will be read. */
- } else {
- line = astFree( line );
- }
- }
-
-/* Return the result pointer. */
- return line;
-
-/* Undefine macros local to this function. */
-#undef MIN_CHARS
-}
-
-static AstChannelValue *LookupValue( const char *name, int *status ) {
-/*
-* Name:
-* LookupValue
-
-* Purpose:
-* Look up a Value structure by name.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "channel.h"
-* AstChannelValue *LookupValue( const char *name )
-
-* Class Membership:
-* Channel member function.
-
-* Description:
-* This function searches the current values list (i.e. at the
-* current nesting level) to identify a Value structure with a
-* specified name. If one is found, it is removed from the list and
-* a pointer to it is returned. If no suitable Value can be found,
-* a NULL pointer is returned instead.
-
-* Parameters:
-* name
-* Pointer to a constant null-terminated character string
-* containing the name of the required Value. This must be in
-* lower case with no surrounding white space. Note that names
-* longer than NAME_MAX characters will not match any Value.
-
-* Returned value:
-* Pointer to the required Value structure, or NULL if no suitable
-* Value exists.
-
-* Notes:
-* - The returned pointer refers to a dynamically allocated
-* structure and it is the callers responsibility to free this when
-* no longer required. The FreeValue function must be used for this
-* purpose.
-* - 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 /* Declare the thread specific global data */
- AstChannelValue **head; /* Address of head of list pointer */
- AstChannelValue *result; /* Pointer value to return */
- AstChannelValue *value; /* Pointer to list element */
-
-/* Initialise. */
- result = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Get a pointer to the structure holding thread-specific global data. */
- astGET_GLOBALS(NULL);
-
-/* Check that the "values_ok" flag is set. If not, the Values in the
- values list belong to a different class to that of the current
- class loader, so we cannot return any Value. */
- if ( values_ok[ nest ] ) {
-
-/* Obtain the address of the current "head of list" pointer for the
- values list (at the current nesting level). */
- head = values_list + nest;
-
-/* Obtain the head of list pointer itself and check the list is not
- empty. */
- if ( ( value = *head ) ) {
-
-/* Loop to inspect each list element. */
- while ( 1 ) {
-
-/* If a name match is found, remove the element from the list, return
- a pointer to it and quit searching. */
- if ( !strcmp( name, value->name ) ) {
- RemoveValue( value, head, status );
- result = value;
- break;
- }
-
-/* Follow the list until we return to the head. */
- value = value->flink;
- if ( value == *head ) break;
- }
- }
- }
-
-/* Return the result. */
- return result;
-}
-
-static void OutputTextItem( AstChannel *this, const char *line, int *status ) {
-/*
-* Name:
-* OutputTextItem
-
-* Purpose:
-* Output a data item formatted as text.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "channel.h"
-* void OutputTextItem( AstChannel *this, const char *line, int *status )
-
-* Class Membership:
-* Channel member function.
-
-* Description:
-* This function outputs a data item formatted as a text string to
-* a data sink associated with a Channel. It keeps track of the
-* number of items written.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-* line
-* Pointer to a constant null-terminated string containing the
-* data item to be output (no newline character should be
-* appended).
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Declare the thread specific global data */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Get a pointer to the structure holding thread-specific global data. */
- astGET_GLOBALS(this);
-
-/* Write out the line of text using the astPutNextText method (which
- may be over-ridden). */
- astPutNextText( this, line );
-
-/* If successful, increment the count of items written. */
- if ( astOK ) items_written++;
-}
-
-static void PutChannelData( AstChannel *this, void *data, int *status ) {
-/*
-c++
-* Name:
-* astPutChannelData
-
-* Purpose:
-* Store arbitrary data to be passed to a source or sink function.
-
-* Type:
-* Public function.
-
-* Synopsis:
-* #include "channel.h"
-* void astPutChannelData( AstChannel *this, void *data )
-
-* Class Membership:
-* Channel method.
-
-* Description:
-* This function stores a supplied arbitrary pointer in the Channel.
-* When a source or sink function is invoked by the Channel, the
-* invoked function can use the astChannelData macro to retrieve the
-* pointer. This provides a thread-safe alternative to passing file
-* descriptors, etc, via global static variables.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-* data
-* A pointer to be made available to the source and sink functions
-* via the astChannelData macro. May be NULL.
-
-* Applicability:
-* Channel
-* All Channels have this function.
-
-* Notes:
-* - This routine is not available in the Fortran 77 interface to
-* the AST library.
-c--
-*/
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Store the pointer. */
- this->data = data;
-}
-
-static void PutNextText( AstChannel *this, const char *line, int *status ) {
-/*
-*+
-* Name:
-* astPutNextText
-
-* Purpose:
-* Write a line of output text to a data sink.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "channel.h"
-* void astPutNextText( AstChannel *this, const char *line )
-
-* Class Membership:
-* Channel method.
-
-* Description:
-* This function writes an output line of text to a data sink
-* associated with a Channel.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-* line
-* Pointer to a constant null-terminated string containing the
-* line of output text to be written (no newline character
-* should be appended).
-
-* Notes:
-* - This method is provided primarily so that derived classes may
-* over-ride it in order to write to alternative (textual) data
-* sinks.
-*-
-*/
-
-/* Local Constants: */
-#define ERRBUF_LEN 80
-
-/* Local Variables: */
- char *errstat; /* Pointer for system error message */
- char errbuf[ ERRBUF_LEN ]; /* Buffer for system error message */
- const char *sink_file; /* Path to output sink file */
- const char *source_file; /* Path to output source file */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* If the SinkFile attribute of the Channel specifies an output file,
- but no output file has yet been opened, open it now. Report an error
- if it is the same as the source file. */
- if( astTestSinkFile( this ) && !this->fd_out ) {
- sink_file = astGetSinkFile( this );
-
- if( this->fd_out ) {
- source_file = astGetSourceFile( this );
- if( astOK && !strcmp( sink_file, source_file ) ) {
- astError( AST__WRERR, "astWrite(%s): Failed to open output "
- "SinkFile '%s' - the file is currently being used "
- "as the input SourceFile.", status, astGetClass( this ),
- sink_file );
- }
- }
-
- if( astOK ) {
- this->fd_out = fopen( sink_file, "w" );
- if( !this->fd_out ) {
- if ( errno ) {
-#if HAVE_STRERROR_R
- strerror_r( errno, errbuf, ERRBUF_LEN );
- errstat = errbuf;
-#else
- errstat = strerror( errno );
-#endif
- astError( AST__WRERR, "astWrite(%s): Failed to open output "
- "SinkFile '%s' - %s.", status, astGetClass( this ),
- sink_file, errstat );
- } else {
- astError( AST__WRERR, "astWrite(%s): Failed to open output "
- "SinkFile '%s'.", status, astGetClass( this ),
- sink_file );
- }
- }
- }
- }
-
-/* Check no error occurred above. */
- if( astOK ) {
-
-/* If an active output file descriptor is stored in the channel, write
- the text to it, with a newline appended. */
- if( this->fd_out ) {
- (void) fprintf( this->fd_out, "%s\n", line );
-
-/* Otherwise, if a sink function (and its wrapper function) is defined for
- the Channel, use the wrapper function to invoke the sink function to
- output the text line. Since we are about to call an externally supplied
- function which may not be thread-safe, lock a mutex first. Also store
- the channel data pointer in a global variable so that it can be accessed
- in the source function using macro astChannelData. */
- } else if ( this->sink && this->sink_wrap ) {
- astStoreChannelData( this );
- LOCK_MUTEX2;
- ( *this->sink_wrap )( *this->sink, line, status );
- UNLOCK_MUTEX2;
-
-/* Otherwise, simply write the text to standard output with a newline
- appended. */
- } else {
- (void) printf( "%s\n", line );
- }
- }
-}
-
-static AstObject *Read( AstChannel *this, int *status ) {
-/*
-*++
-* Name:
-c astRead
-f AST_READ
-
-* Purpose:
-* Read an Object from a Channel.
-
-* Type:
-* Public function.
-
-* Synopsis:
-c #include "channel.h"
-c AstObject *astRead( AstChannel *this )
-f RESULT = AST_READ( THIS, STATUS )
-
-* Class Membership:
-* Channel method.
-
-* Description:
-* This function reads the next Object from a Channel and returns a
-* pointer to the new Object.
-
-* Parameters:
-c this
-f THIS = INTEGER (Given)
-* Pointer to the Channel.
-f STATUS = INTEGER (Given and Returned)
-f The global status.
-
-* Returned Value:
-c astRead()
-f AST_READ = INTEGER
-* A pointer to the new Object. The class to which this will
-* belong is determined by the input data, so is not known in
-* advance.
-
-* Applicability:
-* FitsChan
-c All successful use of astRead on a FitsChan is destructive, so that
-f All successful use of AST_READ on a FitsChan is destructive, so that
-* FITS header cards are consumed in the process of reading an Object,
-* and are removed from the FitsChan (this deletion can be prevented
-* for specific cards by calling the FitsChan
-c astRetainFits function).
-f AST_RETAINFITS routine).
-* An unsuccessful call of
-c astRead
-f AST_READ
-* (for instance, caused by the FitsChan not containing the necessary
-* FITS headers cards needed to create an Object) results in the
-* contents of the FitsChan being left unchanged.
-* StcsChan
-* The AST Object returned by a successful use of
-c astRead
-f AST_READ
-* on an StcsChan, will be either a Region or a KeyMap, depending
-* on the values of the StcsArea, StcsCoords and StcsProps
-* attributes. See the documentation for these attributes for further
-* information.
-
-* Notes:
-* - A null Object pointer (AST__NULL) will be returned, without
-* error, if the Channel contains no further Objects to be read.
-* - A null Object pointer will also be returned if this function
-c is invoked with the AST error status set, or if it should fail
-f is invoked with STATUS set to an error value, or if it should fail
-* for any reason.
-*--
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Declare the thread specific global data */
- AstLoaderType *loader; /* Pointer to loader for Object */
- AstObject *new; /* Pointer to new Object */
- char *class; /* Pointer to Object class name string */
- char *name; /* Pointer to data item name */
- int skip; /* Skip non-AST data? */
- int top; /* Reading top-level Object definition? */
-
-/* Initialise. */
- new = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return new;
-
-/* Get a pointer to the structure holding thread-specific global data. */
- astGET_GLOBALS(this);
-
-/* Determine if we are reading a top-level (i.e. user-level) Object
- definition, as opposed to the definition of an Object contained
- within another Object. This is indicated by the current nesting
- level. */
- top = ( nest == -1 );
-
-/* If reading a top-level object, determine if data lying in between
- Object definitions in the input data stream are to be skipped. */
- skip = ( top && astGetSkip( this ) );
-
-/* Read the next input data item. If we are reading a top-level Object
- definition, skip any unrelated data beforehand. Otherwise read the
- data strictly as it comes (there should be no unrelated data
- embedded within Object definitions themselves). */
- astGetNextData( this, skip, &name, &class );
-
-/* If no suitable data item was found (and no error occurred), we have
- reached the end of data. For a top-level Object a NULL Object
- pointer is simply returned, but for a nested Object this indicates
- that part of the Object definition is missing, so report an
- error. */
- if ( astOK ) {
- if ( !name ) {
- if ( !top ) {
- astError( AST__EOCHN,
- "astRead(%s): End of input encountered while trying to "
- "read an AST Object.", status, astGetClass( this ) );
- }
-
-/* If a data item was found, check it is a "Begin" item. If not, there
- is a data item missing, so report an error and free all memory. */
- } else if ( strcmp( name, "begin" ) ) {
- astError( AST__BADIN,
- "astRead(%s): Missing \"Begin\" when expecting an Object.", status,
- astGetClass( this ) );
- name = astFree( name );
- if ( class ) class = astFree( class );
-
-/* If the required "Begin" item was found, free the memory used for the
- name string. */
- } else {
- name = astFree( name );
-
-/* Use the associated class name to locate the loader for that
- class. This function will then be used to build the Object. */
- loader = astGetLoader( class, status );
-
-/* Extend all necessary stack arrays to accommodate entries for the
- next nesting level (this allocates space if none has yet been
- allocated). */
- end_of_object = astGrow( end_of_object, nest + 2, sizeof( int ) );
- object_class = astGrow( object_class, nest + 2, sizeof( char * ) );
- values_class = astGrow( values_class, nest + 2, sizeof( char * ) );
- values_list = astGrow( values_list, nest + 2, sizeof( AstChannelValue * ) );
- values_ok = astGrow( values_ok, nest + 2, sizeof( int ) );
-
-/* If an error occurred, free the memory used by the class string,
- which will not now be used. */
- if ( !astOK ) {
- class = astFree( class );
-
-/* Otherwise, increment the nesting level and initialise the new stack
- elements for this new level. This includes clearing the
- "end_of_object" flag so that ReadClassData can read more data, and
- storing the class name of the object we are about to read. */
- } else {
- nest++;
- end_of_object[ nest ] = 0;
- object_class[ nest ] = class;
- values_class[ nest ] = NULL;
- values_list[ nest ] = NULL;
- values_ok[ nest ] = 0;
-
-/* Invoke the loader, which reads the Object definition from the input
- data stream and builds the Object. Supply NULL/zero values to the
- loader so that it will substitute values appropriate to its own
- class. */
- new = (*loader)( NULL, (size_t) 0, NULL, NULL, this, status );
-
-/* Clear the values list for the current nesting level. If the list
- has not been read or any Values remain in it, an error will
- result. */
- ClearValues( this, status );
-
-/* If no error has yet occurred, check that the "end_of_object" flag
- has been set. If not, the input data were not correctly terminated,
- so report an error. */
- if ( astOK && !end_of_object[ nest ] ) {
- astError( AST__BADIN,
- "astRead(%s): Unexpected end of input (missing end "
- "of %s).", status,
- astGetClass( this ), object_class[ nest ] );
- }
-
-/* If an error occurred, report contextual information. Only do this
- for top-level Objects to avoid multple messages. */
- if ( !astOK && top ) {
- astError( astStatus, "Error while reading a %s from a %s.", status,
- class, astGetClass( this ) );
- }
-
-/* Clear the Object's class string, freeing the associated memory
- (note this is the memory allocated for the "class" string
- earlier). */
- object_class[ nest ] = astFree( object_class[ nest ] );
-
-/* Restore the previous nesting level. */
- nest--;
- }
-
-/* Once the top-level Object has been built, free the memory used by
- the stack arrays. */
- if ( top ) {
- end_of_object = astFree( end_of_object );
- object_class = astFree( object_class );
- values_class = astFree( values_class );
- values_list = astFree( values_list );
- values_ok = astFree( values_ok );
- }
- }
- }
-
-/* If an error occurred, clean up by deleting the new Object and
- return a NULL pointer. */
- if ( !astOK ) new = astDelete( new );
-
-/* Return the pointer to the new Object. */
- return new;
-}
-
-static void ReadClassData( AstChannel *this, const char *class, int *status ) {
-/*
-*+
-* Name:
-* astReadClassData
-
-* Purpose:
-* Read values from a data source for a class loader.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "channel.h"
-* void astReadClassData( AstChannel *this, const char *class )
-
-* Class Membership:
-* Channel method.
-
-* Description:
-* This function reads the data for a class from the data source
-* associated with a Channel, so as to provide values for
-* initialising the instance variables of that class as part of
-* building a complete Object. This function should be invoked by
-* the loader for each class immediately before it attempts to read
-* these values.
-*
-* The values read are placed into the current values list by this
-* function. They may then be read from this list by the class
-* loader making calls to astReadDouble, astReadInt, astReadObject
-* and astReadString. The order in which values are read by the
-* loader is unimportant (although using the same order for reading
-* as for writing will usually be more efficient) and values are
-* removed from the list as they are read.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-* class
-* A pointer to a constant null-terminated string containing the
-* name of the class whose loader is requesting the data (note
-* this is not usually the same as the class name of the Object
-* being built). This value allows the class structure of the
-* input data to be validated.
-*-
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Declare the thread specific global data */
- AstObject *object; /* Pointer to new Object */
- AstChannelValue *value; /* Pointer to Value structure */
- char *name; /* Pointer to data item name string */
- char *val; /* Pointer to data item value string */
- int done; /* All class data read? */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Get a pointer to the structure holding thread-specific global data. */
- astGET_GLOBALS(this);
-
-/* If the "values_ok" flag is set, this indicates that the values list
- (at the current nesting level) has been filled by a previous
- invocation of this function and has then been read by the
- appropriate class loader. In this case, clear any entries which may
- remain in the current values list. If any such entries are found,
- they represent input data that were not read, so an error will
- result. */
- if ( values_ok[ nest ] ) ClearValues( this, status );
-
-/* If "values_class" is non-NULL, this indicates that the values list
- (at the current nesting level) has been filled by a previous
- invocation of this function, but that the values belong to a class
- whose loader has not yet tried to read them. In this case, we must
- continue to keep the values until they are needed, so we do not
- read any more input data this time. */
- if ( values_class[ nest ] ) {
-
-/* If the class to which the previously saved values belong matches
- the class we now want values for, set the "values_ok" flag. This
- then allows the values to be accessed (by LookupValue). */
- values_ok[ nest ] = !strcmp( values_class[ nest ], class );
-
-/* If the current values list is empty, we must read in values for the
- next class that appears in the input data. However, first check
- that the "end_of_object" flag has not been set. If it has, we have
- already reached the end of this Object's data, so there is some
- kind of problem with the order in which class loaders have been
- invoked. This will probably never happen, but report an error if
- necessary. */
- } else if ( end_of_object[ nest ] ) {
- astError( AST__LDERR,
- "astRead(%s): Invalid attempt to read further %s data "
- "following an end of %s.", status,
- astGetClass( this ), class, object_class[ nest ] );
- astError( AST__LDERR,
- "Perhaps the wrong class loader has been invoked?" , status);
-
-/* If we need new values, loop to read input data items until the end
- of the data for a class is reached. */
- } else {
- done = 0;
- while ( astOK && !done ) {
-
-/* Read the next input data item. */
- astGetNextData( this, 0, &name, &val );
- if ( astOK ) {
-
-/* Unexpected end of input. */
-/* ------------------------ */
-/* If no "name" value is returned, we have reached the end of the
- input data stream without finding the required end of class
- terminator, so report an error. */
- if ( !name ) {
- astError( AST__EOCHN,
- "astRead(%s): Unexpected end of input (missing end "
- "of %s).", status,
- astGetClass( this ), object_class[ nest ] );
-
-/* "IsA" item. */
-/* ----------- */
-/* Otherwise, if an "IsA" item was read, it indicates the end of the
- data for a class. Store the pointer to the name of this class in
- "values_class" and note whether this is the class whose data we
- wanted in "values_ok". If the data we have read do not belong to
- the class we wanted, they will simply be kept until the right class
- comes looking for them. */
- } else if ( !strcmp( name, "isa" ) ) {
- values_class[ nest ] = val;
- values_ok[ nest ] = !strcmp( val, class );
-
-/* Free the memory holding the name string. */
- name = astFree( name );
-
-/* Note we have finished reading class data. */
- done = 1;
-
-/* "End" item. */
-/* ----------- */
-/* If an "End" item was read, it indicates the end of the data both
- for a class and for the current Object definition as a whole. Set
- the "end_of_object" flag (for the current nesting level) which
- prevents any further data being read for this Object. This flag is
- also used (by Read) to check that an "End" item was actually
- read. */
- } else if ( !strcmp( name, "end" ) ) {
- end_of_object[ nest ] = 1;
-
-/* Check that the class name in the "End" item matches that of the
- Object being built. If so, store the pointer to the name of this
- class in "values_class" and note whether this is the class whose
- data we wanted in "values_ok". If the data we have read do not
- belong to the class we wanted, they will simply be kept until the
- right class comes looking for them. */
- if ( !strcmp( val, object_class[ nest ] ) ) {
- values_class[ nest ] = val;
- values_ok[ nest ] = !strcmp( class, val );
-
-/* If the "End" item contains the wrong class name (i.e. not matching
- the corresponding "Begin" item), then report an error. */
- } else {
- astError( AST__BADIN,
- "astRead(%s): Bad class structure in input data.", status,
- astGetClass( this ) );
- astError( AST__BADIN,
- "End of %s read when expecting end of %s.", status,
- val, object_class[ nest ] );
-
-/* Free the memory used by the class string, which will not now be
- used. */
- val = astFree( val );
- }
-
-/* Free the memory holding the name string. */
- name = astFree( name );
-
-/* Note we have finished reading class data. */
- done = 1;
-
-/* String value. */
-/* ------------- */
-/* If any other name is obtained and "val" is not NULL, we have read a
- non-Object value, encoded as a string. Allocate memory for a Value
- structure to describe it. */
- } else if ( val ) {
- value = astMalloc( sizeof( AstChannelValue ) );
- if ( astOK ) {
-
-/* Store pointers to the name and value string in the Value structure
- and note this is not an Object value. */
- value->name = name;
- value->ptr.string = val;
- value->is_object = 0;
-
-/* Append the Value structure to the values list for the current
- nesting level. */
- AppendValue( value, values_list + nest, status );
-
-/* If an error occurred, free the memory holding the "name" and "val"
- strings. */
- } else {
- name = astFree( name );
- val = astFree( val );
- }
-
-/* Object value. */
-/* ------------- */
-/* If "val" is NULL, we have read an Object item, and the Object
- definition should follow. Allocate memory for a Value structure to
- describe it. */
- } else {
- value = astMalloc( sizeof( AstChannelValue ) );
-
-/* Invoke astRead to read the Object definition from subsequent data
- items and to build the Object, returning a pointer to it. This will
- result in recursive calls to the current function, but as these
- will use higher nesting levels they will not interfere with the
- current invocation. */
- astreadclassdata_msg = 0;
- object = astRead( this );
- if ( astOK ) {
-
-/* Store pointers to the name and Object in the Value structure and
- note this is an Object value. */
- value->name = name;
- value->ptr.object = object;
- value->is_object = 1;
-
-/* Append the Value structure to the values list for the current
- nesting level. */
- AppendValue( value, values_list + nest, status );
-
-/* If an error occurred, report a contextual error maessage and set
- the "astreadclassdata_msg" flag (this prevents multiple messages if this function is
- invoked recursively to deal with nested Objects). */
- } else {
- if ( !astreadclassdata_msg ) {
- astError( astStatus,
- "Failed to read the \"%s\" Object value.", status,
- name );
- astreadclassdata_msg = 1;
- }
-
-/* Free the memory holding the "name" string and any Value structure
- that was allocated. */
- name = astFree( name );
- value = astFree( value );
- }
- }
- }
- }
- }
-}
-
-static double ReadDouble( AstChannel *this, const char *name, double def, int *status ) {
-/*
-*+
-* Name:
-* astReadDouble
-
-* Purpose:
-* Read a double value as part of loading a class.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "channel.h"
-* double astReadDouble( AstChannel *this, const char *name, double def )
-
-* Class Membership:
-* Channel method.
-
-* Description:
-* This function searches the current values list of a Channel to
-* identify a double value with a specified name. If such a value
-* is found, it is returned, otherwise a default value is returned
-* instead.
-*
-* This function should only be invoked from within the loader
-* function associated with a class, in order to return a double
-* value to be assigned to an instance variable. It must be
-* preceded by a call to the astReadClassData function, which loads
-* the values associated with the class into the current values
-* list from the input data source.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-* name
-* Pointer to a constant null-terminated character string
-* containing the name of the required value. This must be in
-* lower case with no surrounding white space. Note that names
-* longer than 6 characters will not match any value.
-* def
-* If no suitable value can be found (e.g. it is absent from the
-* data stream being read), then this value will be returned
-* instead.
-
-* Returned Value:
-* The required value, or the default if the value was not found.
-
-* Notes:
-* - A value of 0.0 will be returned if this function is invoked
-* with the global error status set, or if it should fail for any
-* reason.
-*-
-*/
-
-/* Local Variables: */
- AstChannelValue *value; /* Pointer to required Value structure */
- double result; /* Value to be returned */
- int nc; /* Number of characters read by astSscanf */
-
-/* Initialise. */
- result = 0.0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Search for a Value structure with the required name in the current
- values list.*/
- value = LookupValue( name, status );
- if ( astOK ) {
-
-/* If a Value was found, check that it describes a string (as opposed
- to an Object). */
- if ( value ) {
- if ( !value->is_object ) {
-
-/* If so, then attempt to decode the string to give a double value,
- checking that the entire string is read (and checking for the magic string
- used to represent bad values). If this fails, then the wrong name has
- probably been given, or the input data are corrupt, so report an error. */
- nc = 0;
- if ( ( 0 == astSscanf( value->ptr.string, " " BAD_STRING " %n",
- &nc ) )
- && ( nc >= (int) strlen( value->ptr.string ) ) ) {
- result = AST__BAD;
-
- } else if ( !( ( 1 == astSscanf( value->ptr.string, " %lf %n",
- &result, &nc ) )
- && ( nc >= (int) strlen( value->ptr.string ) ) ) ) {
- astError( AST__BADIN,
- "astRead(%s): The value \"%s = %s\" cannot "
- "be read as a double precision floating point "
- "number.", status, astGetClass( this ),
- value->name, value->ptr.string );
-
- } else if( !astISFINITE( result ) ) {
- astError( AST__BADIN,
- "astRead(%s): Illegal double precision floating "
- "point value \"%s\" read for \"%s\".", status,
- astGetClass( this ), value->ptr.string, value->name );
-
- }
-
-/* Report a similar error if the Value does not describe a string. */
- } else {
- astError( AST__BADIN,
- "astRead(%s): The Object \"%s = <%s>\" cannot "
- "be read as a double precision floating point number.", status,
- astGetClass( this ),
- value->name, astGetClass( value->ptr.object ) );
- }
-
-/* Free the Value structure and the resources it points at. */
- value = FreeValue( value, status );
-
-/* If no suitable Value structure was found, then use the default
- value instead. */
- } else {
- result = def;
- }
- }
-
-/* Return the result. */
- return result;
-}
-
-static int ReadInt( AstChannel *this, const char *name, int def, int *status ) {
-/*
-*+
-* Name:
-* astReadInt
-
-* Purpose:
-* Read an int value as part of loading a class.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "channel.h"
-* int astReadInt( AstChannel *this, const char *name, int def )
-
-* Class Membership:
-* Channel method.
-
-* Description:
-* This function searches the current values list of a Channel to
-* identify an int value with a specified name. If such a value is
-* found, it is returned, otherwise a default value is returned
-* instead.
-*
-* This function should only be invoked from within the loader
-* function associated with a class, in order to return an int
-* value to be assigned to an instance variable. It must be
-* preceded by a call to the astReadClassData function, which loads
-* the values associated with the class into the current values
-* list from the input data source.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-* name
-* Pointer to a constant null-terminated character string
-* containing the name of the required value. This must be in
-* lower case with no surrounding white space. Note that names
-* longer than 6 characters will not match any value.
-* def
-* If no suitable value can be found (e.g. it is absent from the
-* data stream being read), then this value will be returned
-* instead.
-
-* Returned Value:
-* The required value, or the default if the value was not found.
-
-* 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: */
- AstChannelValue *value; /* Pointer to required Value structure */
- int nc; /* Number of characters read by astSscanf */
- int result; /* Value to be returned */
-
-/* Initialise. */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Search for a Value structure with the required name in the current
- values list.*/
- value = LookupValue( name, status );
- if ( astOK ) {
-
-/* If a Value was found, check that it describes a string (as opposed
- to an Object). */
- if ( value ) {
- if ( !value->is_object ) {
-
-/* If so, then attempt to decode the string to give an int value,
- checking that the entire string is read. If this fails, then the
- wrong name has probably been given, or the input data are corrupt,
- so report an error. */
- nc = 0;
- if ( !( ( 1 == astSscanf( value->ptr.string, " %d %n",
- &result, &nc ) )
- && ( nc >= (int) strlen( value->ptr.string ) ) ) ) {
- astError( AST__BADIN,
- "astRead(%s): The value \"%s = %s\" cannot "
- "be read as an integer.", status, astGetClass( this ),
- value->name, value->ptr.string );
- }
-
-/* Report a similar error if the Value does not describe a string. */
- } else {
- astError( AST__BADIN,
- "astRead(%s): The Object \"%s = <%s>\" cannot "
- "be read as an integer.", status, astGetClass( this ),
- value->name, astGetClass( value->ptr.object ) );
- }
-
-/* Free the Value structure and the resources it points at. */
- value = FreeValue( value, status );
-
-/* If no suitable Value structure was found, then use the default
- value instead. */
- } else {
- result = def;
- }
- }
-
-/* Return the result. */
- return result;
-}
-
-static AstObject *ReadObject( AstChannel *this, const char *name,
- AstObject *def, int *status ) {
-/*
-*+
-* Name:
-* astReadObject
-
-* Purpose:
-* Read a (sub)Object as part of loading a class.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "channel.h"
-* AstObject *astReadObject( AstChannel *this, const char *name,
-* AstObject *def )
-
-* Class Membership:
-* Channel method.
-
-* Description:
-* This function searches the current values list of a Channel to
-* identify an Object with a specified name. If such an Object is
-* found, a pointer to it is returned, otherwise a default pointer
-* is returned instead.
-*
-* This function should only be invoked from within the loader
-* function associated with a class, in order to return an Object
-* pointer value to be assigned to an instance variable. It must be
-* preceded by a call to the astReadClassData function, which loads
-* the values associated with the class into the current values
-* list from the input data source.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-* name
-* Pointer to a constant null-terminated character string
-* containing the name of the required Object. This must be in
-* lower case with no surrounding white space. Note that names
-* longer than 6 characters will not match any Object.
-* def
-* If no suitable Object can be found (e.g. the Object is absent
-* from the data stream being read), then a clone of this
-* default Object pointer will be returned instead (or NULL if
-* this default pointer is NULL).
-
-* Returned Value:
-* A pointer to the Object, or a clone of the default pointer if
-* the Object was not found.
-
-* 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: */
- AstObject *result; /* Pointer value to return */
- AstChannelValue *value; /* Pointer to required Value structure */
-
-/* Initialise. */
- result = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Search for a Value structure with the required name in the current
- values list.*/
- value = LookupValue( name, status );
- if ( astOK ) {
-
-/* If a Value was found, check that it describes an Object (as opposed to
- a string). */
- if ( value ) {
- if ( value->is_object ) {
-
-/* If so, then extract the Object pointer, replacing it with NULL. */
- result = value->ptr.object;
- value->ptr.object = NULL;
-
-/* If the Value does not describe an Object, then the wrong name has
- probably been given, or the input data are corrupt, so report an
- error. */
- } else {
- astError( AST__BADIN,
- "astRead(%s): The value \"%s = %s\" cannot be "
- "read as an Object.", status, astGetClass( this ),
- value->name, value->ptr.string );
- }
-
-/* Free the Value structure and the resources it points at. */
- value = FreeValue( value, status );
-
-/* If no suitable Value structure was found, clone the default
- pointer, if given. */
- } else if ( def ) {
- result = astClone( def );
- }
- }
-
-/* Return the result. */
- return result;
-}
-
-static char *ReadString( AstChannel *this, const char *name,
- const char *def, int *status ) {
-/*
-*+
-* Name:
-* astReadString
-
-* Purpose:
-* Read a string value as part of loading a class.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "channel.h"
-* char *astReadString( AstChannel *this, const char *name,
-* const char *def )
-
-* Class Membership:
-* Channel method.
-
-* Description:
-* This function searches the current values list of a Channel to
-* identify a string value with a specified name. If such a value
-* is found, a pointer to the string is returned, otherwise a
-* pointer to a copy of a default string is returned instead.
-*
-* This function should only be invoked from within the loader
-* function associated with a class, in order to return a string
-* pointer value to be assigned to an instance variable. It must be
-* preceded by a call to the astReadClassData function, which loads
-* the values associated with the class into the current values
-* list from the input data source.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-* name
-* Pointer to a constant null-terminated character string
-* containing the name of the required value. This must be in
-* lower case with no surrounding white space. Note that names
-* longer than 6 characters will not match any value.
-* def
-* If no suitable string can be found (e.g. the value is absent
-* from the data stream being read), then a dynamically
-* allocated copy of the null-terminated string pointed at by
-* "def" will be made, and a pointer to this copy will be
-* returned instead (or NULL if this default pointer is NULL).
-
-* Returned Value:
-* A pointer to a dynamically allocated null-terminated string
-* containing the value required, or to a copy of the default
-* string if the value was not found (or NULL if the "def" pointer
-* was NULL).
-
-* Notes:
-* - It is the caller's responsibility to arrange for the memory
-* holding the returned string to be freed (using astFree) when it
-* is no longer required.
-* - 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: */
- AstChannelValue *value; /* Pointer to required Value structure */
- char *result; /* Pointer value to return */
-
-/* Initialise. */
- result = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Search for a Value structure with the required name in the current
- values list.*/
- value = LookupValue( name, status );
- if ( astOK ) {
-
-/* If a Value was found, check that it describes a string (as opposed
- to an Object). */
- if ( value ) {
- if ( !value->is_object ) {
-
-/* If so, then extract the string pointer, replacing it with NULL. */
- result = value->ptr.string;
- value->ptr.string = NULL;
-
-/* If the Value does not describe a string, then the wrong name has
- probably been given, or the input data are corrupt, so report an
- error. */
- } else {
- astError( AST__BADIN,
- "astRead(%s): The Object \"%s = <%s>\" cannot "
- "be read as a string.", status, astGetClass( this ),
- value->name, astGetClass( value->ptr.object ) );
- }
-
-/* Free the Value structure and the resources it points at. */
- value = FreeValue( value, status );
-
-/* If no suitable Value structure was found, then make a dynamic copy
- of the default string (if given) and return a pointer to this. */
- } else if ( def ) {
- result = astStore( NULL, def, strlen( def ) + (size_t) 1 );
- }
- }
-
-/* Return the result. */
- return result;
-}
-
-static void RemoveValue( AstChannelValue *value, AstChannelValue **head, int *status ) {
-/*
-* Name:
-* RemoveValue
-
-* Purpose:
-* Remove a Value structure from a circular linked list.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "channel.h"
-* void RemoveValue( AstChannelValue *value, AstChannelValue **head, int *status );
-
-* Class Membership:
-* Channel member function.
-
-* Description:
-* This function removes a Value structure from a doubly linked
-* circular list of such structures. The "head of list" pointer is
-* updated to point at the element following the one removed.
-
-* Parameters:
-* value
-* Pointer to the structure to be removed (note that this must
-* actually be in the list, although this function does not
-* check).
-* head
-* Address of a pointer to the element at the head of the
-* list. This pointer will be updated to point at the list
-* element that follows the one removed. If the list becomes
-* empty, the pointer will be set to NULL.
-* status
-* Pointer to the inherited status variable.
-
-* Notes:
-* - This function does not perform error chacking and does not
-* generate errors.
-*/
-
-/* Remove the Value structure from the list by re-establishing links
- between the elements on either side of it. */
- value->blink->flink = value->flink;
- value->flink->blink = value->blink;
-
-/* Update the head of list pointer to identify the following
- element. */
- *head = value->flink;
-
-/* If the head of list identifies the removed element, then note that
- the list is now empty. */
- if ( *head == value ) *head = NULL;
-
-/* Make the removed element point at itself. */
- value->flink = value;
- value->blink = value;
-}
-
-static void SetAttrib( AstObject *this_object, const char *setting, int *status ) {
-/*
-* Name:
-* SetAttrib
-
-* Purpose:
-* Set an attribute value for a Channel.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "channel.h"
-* void SetAttrib( AstObject *this, const char *setting )
-
-* Class Membership:
-* Channel member function (over-rides the astSetAttrib protected
-* method inherited from the Object class).
-
-* Description:
-* This function assigns an attribute value for a Channel, 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 Channel.
-* setting
-* Pointer to a null terminated string specifying the new attribute
-* value.
-*/
-
-/* Local Variables: */
- AstChannel *this; /* Pointer to the Channel structure */
- int comment; /* Comment attribute value */
- int full; /* Full attribute value */
- int indent; /* Indent attribute value */
- int len; /* Length of setting string */
- int nc; /* Number of characters read by "astSscanf" */
- int report_level; /* Skip attribute value */
- int skip; /* Skip attribute value */
- int sourcefile; /* Offset of SourceFile string */
- int sinkfile; /* Offset of SinkFile string */
- int strict; /* Report errors instead of warnings? */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the Channel structure. */
- this = (AstChannel *) 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. */
-
-/* Comment. */
-/* ---------*/
- if ( nc = 0,
- ( 1 == astSscanf( setting, "comment= %d %n", &comment, &nc ) )
- && ( nc >= len ) ) {
- astSetComment( this, comment );
-
-/* Full. */
-/* ----- */
- } else if ( nc = 0,
- ( 1 == astSscanf( setting, "full= %d %n", &full, &nc ) )
- && ( nc >= len ) ) {
- astSetFull( this, full );
-
-/* Indent. */
-/* ------- */
- } else if ( nc = 0,
- ( 1 == astSscanf( setting, "indent= %d %n", &indent, &nc ) )
- && ( nc >= len ) ) {
- astSetIndent( this, indent );
-
-/* ReportLavel. */
-/* ------------ */
- } else if ( nc = 0,
- ( 1 == astSscanf( setting, "reportlevel= %d %n", &report_level, &nc ) )
- && ( nc >= len ) ) {
- astSetReportLevel( this, report_level );
-
-/* Skip. */
-/* ----- */
- } else if ( nc = 0,
- ( 1 == astSscanf( setting, "skip= %d %n", &skip, &nc ) )
- && ( nc >= len ) ) {
- astSetSkip( this, skip );
-
-/* SinkFile. */
-/* --------- */
- } else if ( nc = 0,
- ( 0 == astSscanf( setting, "sinkfile=%n%*[^\n]%n", &sinkfile, &nc ) )
- && ( nc >= len ) ) {
- astSetSinkFile( this, setting + sinkfile );
-
-/* SourceFile. */
-/* ----------- */
- } else if ( nc = 0,
- ( 0 == astSscanf( setting, "sourcefile=%n%*[^\n]%n", &sourcefile, &nc ) )
- && ( nc >= len ) ) {
- astSetSourceFile( this, setting + sourcefile );
-
-/* Strict. */
-/* ------- */
- } else if ( nc = 0,
- ( 1 == astSscanf( setting, "strict= %d %n", &strict, &nc ) )
- && ( nc >= len ) ) {
- astSetStrict( this, strict );
-
-/* If the attribute is still not recognised, pass it on to the parent
- method for further interpretation. */
- } else {
- (*parent_setattrib)( this_object, setting, status );
- }
-}
-
-static void SinkWrap( void (* sink)( const char * ), const char *line, int *status ) {
-/*
-* Name:
-* SinkWrap
-
-* Purpose:
-* Wrapper function to invoke a C Channel sink function.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "channel.h"
-* void SinkWrap( void (* sink)( const char * ), const char *line, int *status )
-
-* Class Membership:
-* Channel member function.
-
-* Description:
-* This function invokes the sink function whose pointer is
-* supplied in order to write an output line to an external data
-* store.
-
-* Parameters:
-* sink
-* Pointer to a sink function, whose single parameter is a
-* pointer to a const, null-terminated string containing the
-* text to be written, and which returns void. This is the form
-* of Channel sink function employed by the C language interface
-* to the AST library.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Invoke the sink function. */
- ( *sink )( line );
-}
-
-static char *SourceWrap( const char *(* source)( void ), int *status ) {
-/*
-* Name:
-* SourceWrap
-
-* Purpose:
-* Wrapper function to invoke a C Channel source function.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "channel.h"
-* char *SourceWrap( const char *, int *status(* source)( void ) )
-
-* Class Membership:
-* Channel member function.
-
-* Description:
-* This function invokes the source function whose pointer is
-* supplied in order to read the next input line from an external
-* data store. It then returns a pointer to a dynamic string
-* containing a copy of the text that was read.
-
-* Parameters:
-* source
-* Pointer to a source function, with no parameters, that
-* returns a pointer to a const, null-terminated string
-* containing the text that it read. This is the form of Channel
-* source function employed by the C language interface to the
-* AST library.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A pointer to a dynamically allocated, null terminated string
-* containing a copy of the text that was read. This string must be
-* freed by the caller (using astFree) when no longer required.
-*
-* A NULL pointer will be returned if there is no more input text
-* to read.
-
-* Notes:
-* - A NULL pointer value 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 *result; /* Pointer value to return */
- const char *line; /* Pointer to input line */
-
-/* Initialise. */
- result = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Invoke the source function to read the next input line and return a
- pointer to the resulting string. */
- line = ( *source )();
-
-/* If a string was obtained, make a dynamic copy of it and save the
- resulting pointer. */
- if ( line ) result = astString( line, (int) strlen( line ) );
-
-/* Return the result. */
- return result;
-}
-
-void astStoreChannelData_( AstChannel *this, int *status ) {
-/*
-*+
-* Name:
-* astStoreChannelData
-
-* Purpose:
-* Store the Channel's channel-data pointer in a thread-specific
-* global variable.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "channel.h"
-* astStoreChannelData( AstChannel *this )
-
-* Class Membership:
-* Channel method.
-
-* Description:
-* This function stores the Channel's channel-data pointer (if any)
-* established by the previous call to astPutChannelData, in a
-* thread-specific global variable from where the astChannelData macro
-* can access it.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-*-
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Declare the thread specific global data */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Get a pointer to the structure holding thread-specific global data. */
- astGET_GLOBALS(this);
-
-/* Store the pointer int he global variable. */
- channel_data = this->data;
-}
-
-static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) {
-/*
-* Name:
-* TestAttrib
-
-* Purpose:
-* Test if a specified attribute value is set for a Channel.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "channel.h"
-* int TestAttrib( AstObject *this, const char *attrib, int *status )
-
-* Class Membership:
-* Channel member function (over-rides the astTestAttrib protected
-* method inherited from the Object class).
-
-* Description:
-* This function returns a boolean result (0 or 1) to indicate whether
-* a value has been set for one of a Channel's attributes.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-* 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: */
- AstChannel *this; /* Pointer to the Channel structure */
- int result; /* Result value to return */
-
-/* Initialise. */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the Channel structure. */
- this = (AstChannel *) this_object;
-
-/* Check the attribute name and test the appropriate attribute. */
-
-/* Comment. */
-/* -------- */
- if ( !strcmp( attrib, "comment" ) ) {
- result = astTestComment( this );
-
-/* Full. */
-/* ----- */
- } else if ( !strcmp( attrib, "full" ) ) {
- result = astTestFull( this );
-
-/* Indent. */
-/* ------- */
- } else if ( !strcmp( attrib, "indent" ) ) {
- result = astTestIndent( this );
-
-/* ReportLevel. */
-/* ------------ */
- } else if ( !strcmp( attrib, "reportlevel" ) ) {
- result = astTestReportLevel( this );
-
-/* Skip. */
-/* ----- */
- } else if ( !strcmp( attrib, "skip" ) ) {
- result = astTestSkip( this );
-
-/* SourceFile. */
-/* ----------- */
- } else if ( !strcmp( attrib, "sourcefile" ) ) {
- result = astTestSourceFile( this );
-
-/* SinkFile. */
-/* ----------- */
- } else if ( !strcmp( attrib, "sinkfile" ) ) {
- result = astTestSinkFile( this );
-
-/* Strict. */
-/* ------- */
- } else if ( !strcmp( attrib, "strict" ) ) {
- result = astTestStrict( 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 void Unquote( AstChannel *this, char *str, int *status ) {
-/*
-* Name:
-* Unquote
-
-* Purpose:
-* Remove quotes from a (possibly) quoted string.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "channel.h"
-* void Unquote( AstChannel *this, char *str, int *status )
-
-* Class Membership:
-* Channel member function.
-
-* Description:
-* This function removes one layer of quote characters (") from a
-* string which is possibly quoted. Any quotes within quotes (which
-* should have been doubled when the string was originally quoted)
-* are also converted back to single quotes again.
-*
-* The quotes need not start or end at the ends of the string, and
-* there may be any number of quoted sections within the string. No
-* error results if the string does not contain any quotes at all
-* (it is simply returned unchanged), but an error results if any
-* unmatched quotes are found.
-
-* Parameters:
-* this
-* Pointer to a Channel. This is only used for constructing error
-* messages and has no influence on the string processing.
-* str
-* Pointer to the null-terminated string to be processed. This
-* is modified in place. The new string starts at the same
-* location as the original but has a new null character
-* appended if necessary (it will usually be shorter than the
-* original).
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Local Variables: */
- int i; /* Loop counter for "input" characters */
- int j; /* Counter for "output" characters */
- int quoted; /* Inside a quoted string? */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Loop to inspect each character in the string. */
- quoted = 0;
- for ( i = j = 0; str[ i ]; i++ ) {
-
-/* Non-quote characters are simply copied to their new location in the
- string. */
- if ( str[ i ] != '"' ) {
- str[ j++ ] = str[ i ];
-
-/* If a quote character '"' is encountered and we are not already in a
- quoted string, then note the start of a quoted string (and discard
- the quote). */
- } else if ( !quoted ) {
- quoted = 1;
-
-/* If a quote character is encountered inside a quoted string, then
- check if the next character is also a quote. If so, convert this
- double quote to a single one. */
- } else if ( str[ i + 1 ] == '"' ) {
- str[ j++ ] = '"';
- i++;
-
-/* If a single quote character is encountered inside a quoted string,
- then note the end of the quoted string (and discard the quote). */
- } else {
- quoted = 0;
- }
- }
-
-/* Append a null to terminate the processed string. */
- str[ j ] = '\0';
-
-/* If the "quoted" flag is still set, then there were unmatched
- quotes, so report an error. */
- if ( quoted ) {
- astError( AST__UNMQT,
- "astRead(%s): Unmatched quotes in input data: %s.", status,
- astGetClass( this ), str );
- }
-}
-
-static int Use( AstChannel *this, int set, int helpful, int *status ) {
-/*
-* Name:
-* Use
-
-* Purpose:
-* Decide whether to write a value to a data sink.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "channel.h"
-* int Use( AstChannel *this, int set, int helpful, int *status )
-
-* Class Membership:
-* Channel member function.
-
-* Description:
-* This function decides whether a value supplied by a class "Dump"
-* function, via a call to one of the astWrite... protected
-* methods, should actually be written to the data sink associated
-* with a Channel.
-*
-* This decision is based on the settings of the "set" and
-* "helpful" flags supplied to the astWrite... method, plus the
-* attribute settings of the Channel.
-
-* Parameters:
-* this
-* A pointer to the Channel.
-* set
-* The "set" flag supplied.
-* helpful
-* The "helpful" value supplied.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* One if the value should be written out, otherwise zero.
-
-* 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: */
- int full; /* Full attribute value */
- int result; /* Result value to be returned */
-
-/* Check the global error status. */
- if ( !astOK ) return 0;
-
-/* If "set" is non-zero, then so is the result ("set" values must
- always be written out). */
- result = ( set != 0 );
-
-/* Otherwise, obtain the value of the Channel's Full attribute. */
- if ( !set ) {
- full = astGetFull( this );
-
-/* If Full is positive, display all values, if zero, display only
- "helpful" values, if negative, display no (un-"set") values. */
- if ( astOK ) result = ( ( helpful && ( full > -1 ) ) || ( full > 0 ) );
- }
-
-/* Return the result. */
- return result;
-}
-
-static int Write( AstChannel *this, AstObject *object, int *status ) {
-/*
-*++
-* Name:
-c astWrite
-f AST_WRITE
-
-* Purpose:
-* Write an Object to a Channel.
-
-* Type:
-* Public function.
-
-* Synopsis:
-c #include "channel.h"
-c int astWrite( AstChannel *this, AstObject *object )
-f RESULT = AST_WRITE( THIS, OBJECT, STATUS )
-
-* Class Membership:
-* Channel method.
-
-* Description:
-* This function writes an Object to a Channel, appending it to any
-* previous Objects written to that Channel.
-
-* Parameters:
-c this
-f THIS = INTEGER (Given)
-* Pointer to the Channel.
-c object
-f OBJECT = INTEGER (Given)
-* Pointer to the Object which is to be written.
-f STATUS = INTEGER (Given and Returned)
-f The global status.
-
-* Returned Value:
-c astWrite()
-f AST_WRITE = INTEGER
-* The number of Objects written to the Channel by this
-c invocation of astWrite (normally, this will be one).
-f invocation of AST_WRITE (normally, this will be one).
-
-* Applicability:
-* FitsChan
-* If the FitsChan uses a foreign encoding (e.g. FITS-WCS) rather
-* than the native AST encoding, then storing values in the
-* FitsChan for keywords NAXIS1, NAXIS2, etc., before invoking
-c astWrite
-f AST_WRITE
-* can help to produce a successful write.
-
-* Notes:
-* - A value of zero will be returned if this function is invoked
-c with the AST error status set, or if it should fail for any
-f with STATUS set to an error value, or if it should fail for any
-* reason.
-* - Invoking this function will usually cause the sink function
-* associated with the channel to be called in order to transfer a
-* textual description of the supplied object to some external data
-* store. However, the FitsChan class behaves differently. Invoking
-* this function on a FitsChan causes new FITS header cards to be
-* added to an internal buffer (the sink function is not invoked).
-* This buffer is written out through the sink function only when the
-* FitsChan is deleted.
-*--
-*/
-
-/* Check the global error status. */
- if ( !astOK ) return 0;
-
-/* The work of this function is actually performed by the protected
- astDump method of the Object. The fact that this is further
- encapsulated within the astWrite method (which belongs to the
- Channel) is simply a trick to allow it to be over-ridden either by
- a derived Channel, or a derived Object (or both), and hence to
- adapt to the nature of either argument. */
- astDump( object, this );
-
-/* Return the number of Objects written. */
- return astOK ? 1 : 0;
-}
-
-static void WriteBegin( AstChannel *this, const char *class,
- const char *comment, int *status ) {
-/*
-*+
-* Name:
-* astWriteBegin
-
-* Purpose:
-* Write a "Begin" data item to a data sink.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "channel.h"
-* void astWriteBegin( AstChannel *this, const char *class,
-* const char *comment )
-
-* Class Membership:
-* Channel method.
-
-* Description:
-* This function writes a "Begin" data item to the data sink
-* associated with a Channel, so as to begin the output of a new
-* Object definition.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-* class
-* Pointer to a constant null-terminated string containing the
-* name of the class to which the Object belongs.
-* comment
-* Pointer to a constant null-terminated string containing a
-* textual comment to be associated with the "Begin"
-* item. Normally, this will describe the purpose of the Object.
-
-* Notes:
-* - The comment supplied may not actually be used, depending on
-* the nature of the Channel supplied.
-*-
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Declare the thread specific global data */
- char *line; /* Pointer to dynamic output string */
- int i; /* Loop counter for indentation characters */
- int nc; /* Number of output characters */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Get a pointer to the structure holding thread-specific global data. */
- astGET_GLOBALS(this);
-
-/* Start building a dynamic string with an initial space. Then add
- further spaces to suit the current indentation level. */
- line = astAppendString( NULL, &nc, " " );
- for ( i = 0; i < current_indent; i++ ) {
- line = astAppendString( line, &nc, " " );
- }
-
-/* Append the "Begin" keyword followed by the class name. */
- line = astAppendString( line, &nc, "Begin " );
- line = astAppendString( line, &nc, class );
-
-/* If required, also append the comment. */
- if ( astGetComment( this ) && *comment ) {
- line = astAppendString( line, &nc, " \t# " );
- line = astAppendString( line, &nc, comment );
- }
-
-/* Write out the resulting line of text. */
- OutputTextItem( this, line, status );
-
-/* Free the dynamic string. */
- line = astFree( line );
-
-/* Increment the indentation level and clear the count of items written
- for this Object. */
- current_indent += astGetIndent( this );
- items_written = 0;
-}
-
-static void WriteDouble( AstChannel *this, const char *name,
- int set, int helpful,
- double value, const char *comment, int *status ) {
-/*
-*+
-* Name:
-* astWriteDouble
-
-* Purpose:
-* Write a double value to a data sink.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "channel.h"
-* void astWriteDouble( AstChannel *this, const char *name,
-* int set, int helpful,
-* double value, const char *comment )
-
-* Class Membership:
-* Channel method.
-
-* Description:
-* This function writes a named double value, representing the
-* value of a class instance variable, to the data sink associated
-* with a Channel. It is intended for use by class "Dump" functions
-* when writing out class information which will subsequently be
-* re-read.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-* name
-* Pointer to a constant null-terminated string containing the
-* name to be used to identify the value in the external
-* representation. This will form the key for identifying it
-* again when it is re-read. The name supplied should be unique
-* within its class.
-*
-* Mixed case may be used and will be preserved in the external
-* representation (where possible) for cosmetic effect. However,
-* case is not significant when re-reading values.
-*
-* It is recommended that a maximum of 6 alphanumeric characters
-* (starting with an alphabetic character) be used. This permits
-* maximum flexibility in adapting to standard external data
-* representations (e.g. FITS).
-* set
-* If this is zero, it indicates that the value being written is
-* a default value (or can be re-generated from other values) so
-* need not necessarily be written out. Such values will
-* typically be included in the external representation with
-* (e.g.) a comment character so that they are available to
-* human readers but will be ignored when re-read. They may also
-* be completely omitted in some circumstances.
-*
-* If "set" is non-zero, the value will always be explicitly
-* included in the external representation so that it can be
-* re-read.
-* helpful
-* This flag provides a hint about whether a value whose "set"
-* flag is zero (above) should actually appear at all in the
-* external representaton.
-*
-* If the external representation allows values to be "commented
-* out" then, by default, values will be included in this form
-* only if their "helpful" flag is non-zero. Otherwise, they
-* will be omitted entirely. When possible, omitting the more
-* obscure values associated with a class is recommended in
-* order to improve readability.
-*
-* This default behaviour may be further modified if the
-* Channel's Full attribute is set - either to permit all values
-* to be shown, or to suppress non-essential information
-* entirely.
-* value
-* The value to be written.
-* comment
-* Pointer to a constant null-terminated string containing a
-* textual comment to be associated with the value.
-*
-* Note that this comment may not actually be used, depending on
-* the nature of the Channel supplied and the setting of its
-* Comment attribute.
-*-
-*/
-
-/* Local Constants: */
-#define BUFF_LEN 100 /* Size of local formatting buffer */
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Declare the thread specific global data */
- char *line; /* Pointer to dynamic output string */
- char buff[ BUFF_LEN + 1 ]; /* Local formatting buffer */
- int i; /* Loop counter for indentation characters */
- int nc; /* Number of output characters */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Get a pointer to the structure holding thread-specific global data. */
- astGET_GLOBALS(this);
-
-/* Use the "set" and "helpful" flags, along with the Channel's
- attributes to decide whether this value should actually be
- written. */
- if ( Use( this, set, helpful, status ) ) {
-
-/* Start building a dynamic string with an initial space, or a comment
- character if "set" is zero. Then add further spaces to suit the
- current indentation level. */
- line = astAppendString( NULL, &nc, set ? " " : "#" );
- for ( i = 0; i < current_indent; i++ ) {
- line = astAppendString( line, &nc, " " );
- }
-
-/* Append the name string followed by " = ". */
- line = astAppendString( line, &nc, name );
- line = astAppendString( line, &nc, " = " );
-
-/* Format the value as a string and append this. Make sure "-0" isn't
- produced. Use a magic string to represent bad values. */
- if( value != AST__BAD ) {
- (void) sprintf( buff, "%.*g", AST__DBL_DIG, value );
- if ( !strcmp( buff, "-0" ) ) {
- buff[ 0 ] = '0';
- buff[ 1 ] = '\0';
- }
- } else {
- strcpy( buff, BAD_STRING );
- }
- line = astAppendString( line, &nc, buff );
-
-/* If required, also append the comment. */
- if ( astGetComment( this ) && *comment ) {
- line = astAppendString( line, &nc, " \t# " );
- line = astAppendString( line, &nc, comment );
- }
-
-/* Write out the resulting line of text. */
- OutputTextItem( this, line, status );
-
-/* Free the dynamic string. */
- line = astFree( line );
- }
-
-/* Undefine macros local to this function. */
-#undef BUFF_LEN
-}
-
-static void WriteEnd( AstChannel *this, const char *class, int *status ) {
-/*
-*+
-* Name:
-* astWriteEnd
-
-* Purpose:
-* Write an "End" data item to a data sink.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "channel.h"
-* void astWriteEnd( AstChannel *this, const char *class )
-
-* Class Membership:
-* Channel method.
-
-* Description:
-* This function writes an "End" data item to the data sink
-* associated with a Channel. This item delimits the end of an
-* Object definition.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-* class
-* Pointer to a constant null-terminated string containing the
-* class name of the Object whose definition is being terminated
-* by the "End" item.
-*-
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Declare the thread specific global data */
- char *line; /* Pointer to dynamic output string */
- int i; /* Loop counter for indentation characters */
- int nc; /* Number of output characters */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Get a pointer to the structure holding thread-specific global data. */
- astGET_GLOBALS(this);
-
-/* Decrement the indentation level so that the "End" item matches the
- corresponding "Begin" item. */
- current_indent -= astGetIndent( this );
-
-/* Start building a dynamic string with an initial space. Then add
- further spaces to suit the current indentation level. */
- line = astAppendString( NULL, &nc, " " );
- for ( i = 0; i < current_indent; i++ ) {
- line = astAppendString( line, &nc, " " );
- }
-
-/* Append the "End" keyword followed by the class name. */
- line = astAppendString( line, &nc, "End " );
- line = astAppendString( line, &nc, class );
-
-/* Write out the resulting line of text. */
- OutputTextItem( this, line, status );
-
-/* Free the dynamic string. */
- line = astFree( line );
-}
-
-static void WriteInt( AstChannel *this, const char *name, int set, int helpful,
- int value, const char *comment, int *status ) {
-/*
-*+
-* Name:
-* astWriteInt
-
-* Purpose:
-* Write an integer value to a data sink.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "channel.h"
-* void astWriteInt( AstChannel *this, const char *name,
-* int set, int helpful,
-* int value, const char *comment )
-
-* Class Membership:
-* Channel method.
-
-* Description:
-* This function writes a named integer value, representing the
-* value of a class instance variable, to the data sink associated
-* with a Channel. It is intended for use by class "Dump" functions
-* when writing out class information which will subsequently be
-* re-read.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-* name
-* Pointer to a constant null-terminated string containing the
-* name to be used to identify the value in the external
-* representation. This will form the key for identifying it
-* again when it is re-read. The name supplied should be unique
-* within its class.
-*
-* Mixed case may be used and will be preserved in the external
-* representation (where possible) for cosmetic effect. However,
-* case is not significant when re-reading values.
-*
-* It is recommended that a maximum of 6 alphanumeric characters
-* (starting with an alphabetic character) be used. This permits
-* maximum flexibility in adapting to standard external data
-* representations (e.g. FITS).
-* set
-* If this is zero, it indicates that the value being written is
-* a default value (or can be re-generated from other values) so
-* need not necessarily be written out. Such values will
-* typically be included in the external representation with
-* (e.g.) a comment character so that they are available to
-* human readers but will be ignored when re-read. They may also
-* be completely omitted in some circumstances.
-*
-* If "set" is non-zero, the value will always be explicitly
-* included in the external representation so that it can be
-* re-read.
-* helpful
-* This flag provides a hint about whether a value whose "set"
-* flag is zero (above) should actually appear at all in the
-* external representaton.
-*
-* If the external representation allows values to be "commented
-* out" then, by default, values will be included in this form
-* only if their "helpful" flag is non-zero. Otherwise, they
-* will be omitted entirely. When possible, omitting the more
-* obscure values associated with a class is recommended in
-* order to improve readability.
-*
-* This default behaviour may be further modified if the
-* Channel's Full attribute is set - either to permit all values
-* to be shown, or to suppress non-essential information
-* entirely.
-* value
-* The value to be written.
-* comment
-* Pointer to a constant null-terminated string containing a
-* textual comment to be associated with the value.
-*
-* Note that this comment may not actually be used, depending on
-* the nature of the Channel supplied and the setting of its
-* Comment attribute.
-*-
-*/
-
-/* Local Constants: */
-#define BUFF_LEN 50 /* Size of local formatting buffer */
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Declare the thread specific global data */
- char *line; /* Pointer to dynamic output string */
- char buff[ BUFF_LEN + 1 ]; /* Local formatting buffer */
- int i; /* Loop counter for indentation characters */
- int nc; /* Number of output characters */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Get a pointer to the structure holding thread-specific global data. */
- astGET_GLOBALS(this);
-
-/* Use the "set" and "helpful" flags, along with the Channel's
- attributes to decide whether this value should actually be
- written. */
- if ( Use( this, set, helpful, status ) ) {
-
-/* Start building a dynamic string with an initial space, or a comment
- character if "set" is zero. Then add further spaces to suit the
- current indentation level. */
- line = astAppendString( NULL, &nc, set ? " " : "#" );
- for ( i = 0; i < current_indent; i++ ) {
- line = astAppendString( line, &nc, " " );
- }
-
-/* Append the name string followed by " = ". */
- line = astAppendString( line, &nc, name );
- line = astAppendString( line, &nc, " = " );
-
-/* Format the value as a decimal string and append this. */
- (void) sprintf( buff, "%d", value );
- line = astAppendString( line, &nc, buff );
-
-/* If required, also append the comment. */
- if ( astGetComment( this ) && *comment ) {
- line = astAppendString( line, &nc, " \t# " );
- line = astAppendString( line, &nc, comment );
- }
-
-/* Write out the resulting line of text. */
- OutputTextItem( this, line, status );
-
-/* Free the dynamic string. */
- line = astFree( line );
- }
-
-/* Undefine macros local to this function. */
-#undef BUFF_LEN
-}
-
-int astWriteInvocations_( int *status ){
-/*
-*+
-* Name:
-* astWriteInvocations
-
-* Purpose:
-* Returns the number of invocations of the astWrite method.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "channel.h"
-* int astWriteInvocations
-
-* Class Membership:
-* Channel method.
-
-* Description:
-* This function returns the number of invocations of astWrite which
-* have been made so far, excluding those made from within the
-* astWriteObject method. An example of its use is to allow a Dump
-* function to determine if a sub-object has already been dumped
-* during the current invocation of astWrite. See the Dump method for
-* the AstUnit class as an example.
-*-
-*/
- astDECLARE_GLOBALS
- astGET_GLOBALS(NULL);
- return nwrite_invoc;
-}
-
-static void WriteIsA( AstChannel *this, const char *class,
- const char *comment, int *status ) {
-/*
-*+
-* Name:
-* astWriteIsA
-
-* Purpose:
-* Write an "IsA" data item to a data sink.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "channel.h"
-* void astWriteIsA( AstChannel *this, const char *class,
-* const char *comment )
-
-* Class Membership:
-* Channel method.
-
-* Description:
-* This function writes an "IsA" data item to the data sink
-* associated with a Channel. This item delimits the end of the
-* data associated with the instance variables of a class, as part
-* of an overall Object definition.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-* class
-* Pointer to a constant null-terminated string containing the
-* name of the class whose data are terminated by the "IsA"
-* item.
-* comment
-* Pointer to a constant null-terminated string containing a
-* textual comment to be associated with the "IsA"
-* item. Normally, this will describe the purpose of the class
-* whose data are being terminated.
-
-* Notes:
-* - The comment supplied may not actually be used, depending on
-* the nature of the Channel supplied.
-*-
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Declare the thread specific global data */
- char *line; /* Pointer to dynamic output string */
- int i; /* Loop counter for indentation characters */
- int indent_inc; /* Indentation increment */
- int nc; /* Number of output characters */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Get a pointer to the structure holding thread-specific global data. */
- astGET_GLOBALS(this);
-
-/* Output an "IsA" item only if there has been at least one item
- written since the last "Begin" or "IsA" item, or if the Full
- attribute for the Channel is greater than zero (requesting maximum
- information). */
- if ( items_written || astGetFull( this ) > 0 ) {
-
-/* Start building a dynamic string with an initial space. Then add
- further spaces to suit the current indentation level, but reduced
- by one to allow the "IsA" item to match the "Begin" and "End" items
- which enclose it. */
- indent_inc = astGetIndent( this );
- line = astAppendString( NULL, &nc, " " );
- for ( i = 0; i < ( current_indent - indent_inc ); i++ ) {
- line = astAppendString( line, &nc, " " );
- }
-
-/* Append the "IsA" keyword followed by the class name. */
- line = astAppendString( line, &nc, "IsA " );
- line = astAppendString( line, &nc, class );
-
-/* If required, also append the comment. */
- if ( astGetComment( this ) && *comment ) {
- line = astAppendString( line, &nc, " \t# " );
- line = astAppendString( line, &nc, comment );
- }
-
-/* Write out the resulting line of text. */
- OutputTextItem( this, line, status );
-
-/* Free the dynamic string. */
- line = astFree( line );
-
-/* Clear the count of items written for this class. */
- items_written = 0;
- }
-}
-
-static void WriteObject( AstChannel *this, const char *name,
- int set, int helpful,
- AstObject *value, const char *comment, int *status ) {
-/*
-*+
-* Name:
-* astWriteObject
-
-* Purpose:
-* Write an Object as a value to a data sink.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "channel.h"
-* void astWriteObject( AstChannel *this, const char *name,
-* int set, int helpful,
-* AstObject *value, const char *comment )
-
-* Class Membership:
-* Channel method.
-
-* Description:
-* This function writes an Object as a named value, representing
-* the value of a class instance variable, to the data sink
-* associated with a Channel. It is intended for use by class
-* "Dump" functions when writing out class information which will
-* subsequently be re-read.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-* name
-* Pointer to a constant null-terminated string containing the
-* name to be used to identify the value in the external
-* representation. This will form the key for identifying it
-* again when it is re-read. The name supplied should be unique
-* within its class.
-*
-* Mixed case may be used and will be preserved in the external
-* representation (where possible) for cosmetic effect. However,
-* case is not significant when re-reading values.
-*
-* It is recommended that a maximum of 6 alphanumeric characters
-* (starting with an alphabetic character) be used. This permits
-* maximum flexibility in adapting to standard external data
-* representations (e.g. FITS).
-* set
-* If this is zero, it indicates that the value being written is
-* a default value (or can be re-generated from other values) so
-* need not necessarily be written out. Such values will
-* typically be included in the external representation with
-* (e.g.) a comment character so that they are available to
-* human readers but will be ignored when re-read. They may also
-* be completely omitted in some circumstances.
-*
-* If "set" is non-zero, the value will always be explicitly
-* included in the external representation so that it can be
-* re-read.
-* helpful
-* This flag provides a hint about whether a value whose "set"
-* flag is zero (above) should actually appear at all in the
-* external representaton.
-*
-* If the external representation allows values to be "commented
-* out" then, by default, values will be included in this form
-* only if their "helpful" flag is non-zero. Otherwise, they
-* will be omitted entirely. When possible, omitting the more
-* obscure values associated with a class is recommended in
-* order to improve readability.
-*
-* This default behaviour may be further modified if the
-* Channel's Full attribute is set - either to permit all values
-* to be shown, or to suppress non-essential information
-* entirely.
-* value
-* A Pointer to the Object to be written.
-* comment
-* Pointer to a constant null-terminated string containing a
-* textual comment to be associated with the value.
-*
-* Note that this comment may not actually be used, depending on
-* the nature of the Channel supplied and the setting of its
-* Comment attribute.
-*-
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Declare the thread specific global data */
- char *line; /* Pointer to dynamic output string */
- int i; /* Loop counter for indentation characters */
- int indent_inc; /* Indentation increment */
- int nc; /* Number of output characters */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Get a pointer to the structure holding thread-specific global data. */
- astGET_GLOBALS(this);
-
-/* Use the "set" and "helpful" flags, along with the Channel's
- attributes to decide whether this value should actually be
- written. */
- if ( Use( this, set, helpful, status ) ) {
-
-/* Start building a dynamic string with an initial space, or a comment
- character if "set" is zero. Then add further spaces to suit the
- current indentation level. */
- line = astAppendString( NULL, &nc, set ? " " : "#" );
- for ( i = 0; i < current_indent; i++ ) {
- line = astAppendString( line, &nc, " " );
- }
-
-/* Append the name string followed by " =". The absence of a value on
- the right hand side indicates an Object value, whose definition
- follows. */
- line = astAppendString( line, &nc, name );
- line = astAppendString( line, &nc, " =" );
-
-/* If required, also append the comment. */
- if ( astGetComment( this ) && *comment ) {
- line = astAppendString( line, &nc, " \t# " );
- line = astAppendString( line, &nc, comment );
- }
-
-/* Write out the resulting line of text. */
- OutputTextItem( this, line, status );
-
-/* Free the dynamic string. */
- line = astFree( line );
-
-/* If the value is not a default, write the Object to the Channel as
- well, suitably indented (this is omitted if the value is commented
- out). */
- if ( set ) {
- indent_inc = astGetIndent( this );
- current_indent += indent_inc;
- (void) astWrite( this, value );
- current_indent -= indent_inc;
- }
- }
-}
-
-static void WriteString( AstChannel *this, const char *name,
- int set, int helpful,
- const char *value, const char *comment, int *status ) {
-/*
-*+
-* Name:
-* astWriteString
-
-* Purpose:
-* Write a string value to a data sink.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "channel.h"
-* void astWriteString( AstChannel *this, const char *name,
-* int set, int helpful,
-* const char *value, const char *comment )
-
-* Class Membership:
-* Channel method.
-
-* Description:
-* This function writes a named string value, representing the
-* value of a class instance variable, to the data sink associated
-* with a Channel. It is intended for use by class "Dump" functions
-* when writing out class information which will subsequently be
-* re-read.
-
-* Parameters:
-* this
-* Pointer to the Channel.
-* name
-* Pointer to a constant null-terminated string containing the
-* name to be used to identify the value in the external
-* representation. This will form the key for identifying it
-* again when it is re-read. The name supplied should be unique
-* within its class.
-*
-* Mixed case may be used and will be preserved in the external
-* representation (where possible) for cosmetic effect. However,
-* case is not significant when re-reading values.
-*
-* It is recommended that a maximum of 6 alphanumeric characters
-* (starting with an alphabetic character) be used. This permits
-* maximum flexibility in adapting to standard external data
-* representations (e.g. FITS).
-* set
-* If this is zero, it indicates that the value being written is
-* a default value (or can be re-generated from other values) so
-* need not necessarily be written out. Such values will
-* typically be included in the external representation with
-* (e.g.) a comment character so that they are available to
-* human readers but will be ignored when re-read. They may also
-* be completely omitted in some circumstances.
-*
-* If "set" is non-zero, the value will always be explicitly
-* included in the external representation so that it can be
-* re-read.
-* helpful
-* This flag provides a hint about whether a value whose "set"
-* flag is zero (above) should actually appear at all in the
-* external representaton.
-*
-* If the external representation allows values to be "commented
-* out" then, by default, values will be included in this form
-* only if their "helpful" flag is non-zero. Otherwise, they
-* will be omitted entirely. When possible, omitting the more
-* obscure values associated with a class is recommended in
-* order to improve readability.
-*
-* This default behaviour may be further modified if the
-* Channel's Full attribute is set - either to permit all values
-* to be shown, or to suppress non-essential information
-* entirely.
-* value
-* Pointer to a constant null-terminated string containing the
-* value to be written.
-* comment
-* Pointer to a constant null-terminated string containing a
-* textual comment to be associated with the value.
-*
-* Note that this comment may not actually be used, depending on
-* the nature of the Channel supplied and the setting of its
-* Comment attribute.
-*-
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Declare the thread specific global data */
- char *line; /* Pointer to dynamic output string */
- int i; /* Loop counter for characters */
- int nc; /* Number of output characters */
- int quote; /* Quote character found? */
- int size; /* Size of allocated memory */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Get a pointer to the structure holding thread-specific global data. */
- astGET_GLOBALS(this);
-
-/* Use the "set" and "helpful" flags, along with the Channel's
- attributes to decide whether this value should actually be
- written. */
- if ( Use( this, set, helpful, status ) ) {
-
-/* Start building a dynamic string with an initial space, or a comment
- character if "set" is zero. Then add further spaces to suit the
- current indentation level. */
- line = astAppendString( NULL, &nc, set ? " " : "#" );
- for ( i = 0; i < current_indent; i++ ) {
- line = astAppendString( line, &nc, " " );
- }
-
-/* Append the name string followed by " = " and an opening quote
- character (the string will be quoted to protect leading and
- trailing spaces). */
- line = astAppendString( line, &nc, name );
- line = astAppendString( line, &nc, " = \"" );
-
-/* We now append the value string, but must inspect each character so
- that quotes (appearing inside quotes) can be doubled. Determine the
- current size of memory allocated for the dynamic string. */
- size = (int) astSizeOf( line );
-
-/* Loop to inspect each character and see if it is a quote. */
- for ( i = 0; value[ i ]; i++ ) {
- quote = ( value[ i ] == '"' );
-
-/* If more memory is required, extend the dynamic string (allowing for
- doubling of quotes and the final null) and save its new size. */
- if ( nc + 2 + quote > size ) {
- line = astGrow( line, nc + 2 + quote, sizeof( char ) );
- if ( astOK ) {
- size = (int) astSizeOf( line );
-
-/* Quit if an error occurs. */
- } else {
- break;
- }
- }
-
-/* Append the value character to the dynamic string, duplicating each
- quote character. */
- line[ nc++ ] = value[ i ];
- if ( quote ) line[ nc++ ] = '"';
- }
-
-/* Append the closing quote. */
- line = astAppendString( line, &nc, "\"" );
-
-/* If required, also append the comment. */
- if ( astGetComment( this ) && *comment ) {
- line = astAppendString( line, &nc, " \t# " );
- line = astAppendString( line, &nc, comment );
- }
-
-/* Write out the resulting line of text. */
- OutputTextItem( this, line, status );
-
-/* Free the dynamic string. */
- line = astFree( line );
- }
-}
-
-/* Functions which access class attributes. */
-/* ---------------------------------------- */
-/* Implement member functions to access the attributes associated with
- this class using the macros defined for this purpose in the
- "object.h" file. */
-
-/*
-*att++
-* Name:
-* SourceFile
-
-* Purpose:
-* Input file from which to read data.
-
-* Type:
-* Public attribute.
-
-* Synopsis:
-* String.
-
-* Description:
-* This attribute specifies the name of a file from which the Channel
-* should read data. If specified it is used in preference to any source
-* function specified when the Channel was created.
-*
-* Assigning a new value to this attribute will cause any previously
-* opened SourceFile to be closed. The first subsequent call to
-c astRead
-f AST_READ
-* will attempt to open the new file (an error will be reported if the
-* file cannot be opened), and read data from it. All subsequent call to
-c astRead
-f AST_READ
-* will read data from the new file, until the SourceFile attribute is
-* cleared or changed.
-*
-* Clearing the attribute causes any open SourceFile to be closed. All
-* subsequent data reads will use the source function specified when the
-* Channel was created, or will read from standard input if no source
-* function was specified.
-*
-* If no value has been assigned to SourceFile, a null string will be
-* returned if an attempt is made to get the attribute value.
-
-* Notes:
-* - Any open SourceFile is closed when the Channel is deleted.
-* - If the Channel is copied or dumped
-c (using astCopy or astShow)
-f (using AST_COPY or AST_SHOW)
-* the SourceFile attribute is left in a cleared state in the output
-* Channel (i.e. the value of the SourceFile attribute is not copied).
-
-* Applicability:
-* FitsChan
-* In the case of a FitsChan, the specified SourceFile supplements
-* the source function specified when the FitsChan was created,
-* rather than replacing the source function. The source file
-* should be a text file (not a FITS file) containing one header per
-* line. When a value is assigned to SourceFile, the file is opened
-* and read immediately, and all headers read from the file are
-* appended to the end of any header already in the FitsChan. The file
-* is then closed. Clearing the SourceFile attribute has no further
-* effect, other than nullifying the string (i.e. the file name)
-* associated with the attribute.
-
-*att--
-*/
-
-/* Clear the SourceFile value by closing any open file, freeing the
- allocated memory and assigning a NULL pointer. */
-astMAKE_CLEAR(Channel,SourceFile,fn_in,((this->fd_in=(this->fd_in?(fclose(this->fd_in),NULL):NULL)),astFree(this->fn_in)))
-
-/* If the SourceFile value is not set, supply a default in the form of a
- pointer to the constant string "". */
-astMAKE_GET(Channel,SourceFile,const char *,NULL,( this->fn_in ? this->fn_in : "" ))
-
-/* Set a SourceFile value by closing any open file, freeing any previously
- allocated memory, allocating new memory, storing the string and saving
- the pointer to the copy. */
-astMAKE_SET(Channel,SourceFile,const char *,fn_in,((this->fd_in=(this->fd_in?(fclose(this->fd_in),NULL):NULL)),astStore( this->fn_in, value, strlen( value ) + (size_t) 1 )))
-
-/* The SourceFile value is set if the pointer to it is not NULL. */
-astMAKE_TEST(Channel,SourceFile,( this->fn_in != NULL ))
-
-/*
-*att++
-* Name:
-* SinkFile
-
-* Purpose:
-* Output file to which to data should be written.
-
-* Type:
-* Public attribute.
-
-* Synopsis:
-* String.
-
-* Description:
-* This attribute specifies the name of a file to which the Channel
-* should write data. If specified it is used in preference to any sink
-* function specified when the Channel was created.
-*
-* Assigning a new value to this attribute will cause any previously
-* opened SinkFile to be closed. The first subsequent call to
-c astWrite
-f AST_WRITE
-* will attempt to open the new file (an error will be reported if the
-* file cannot be opened), and write data to it. All subsequent call to
-c astWrite
-f AST_WRITE
-* will write data to the new file, until the SinkFile attribute is
-* cleared or changed.
-*
-* Clearing the attribute causes any open SinkFile to be closed. All
-* subsequent data writes will use the sink function specified when the
-* Channel was created, or will write to standard output if no sink
-* function was specified.
-*
-* If no value has been assigned to SinkFile, a null string will be
-* returned if an attempt is made to get the attribute value.
-
-* Notes:
-* - A new SinkFile will over-write any existing file with the same
-* name unless the existing file is write protected, in which case an
-* error will be reported.
-* - Any open SinkFile is closed when the Channel is deleted.
-* - If the Channel is copied or dumped
-c (using astCopy or astShow)
-f (using AST_COPY or AST_SHOW)
-* the SinkFile attribute is left in a cleared state in the output
-* Channel (i.e. the value of the SinkFile attribute is not copied).
-
-* Applicability:
-* FitsChan
-* When the FitsChan is destroyed, any headers in the FitsChan will be
-* written out to the sink file, if one is specified (if not, the
-* sink function used when the FitsChan was created is used). The
-* sink file is a text file (not a FITS file) containing one header
-* per line.
-
-*att--
-*/
-
-/* Clear the SinkFile value by closing any open file, freeing the allocated
- memory and assigning a NULL pointer. */
-astMAKE_CLEAR(Channel,SinkFile,fn_out,((this->fd_out=(this->fd_out?(fclose(this->fd_out),NULL):NULL)),astFree(this->fn_out)))
-
-/* If the SinkFile value is not set, supply a default in the form of a
- pointer to the constant string "". */
-astMAKE_GET(Channel,SinkFile,const char *,NULL,( this->fn_out ? this->fn_out : "" ))
-
-/* Set a SinkFile value by closing any open file, freeing any previously
- allocated memory, allocating new memory, storing the string and saving
- the pointer to the copy. */
-astMAKE_SET(Channel,SinkFile,const char *,fn_out,((this->fd_out=(this->fd_out?(fclose(this->fd_out),NULL):NULL)),astStore( this->fn_out, value, strlen( value ) + (size_t) 1 )))
-
-/* The SinkFile value is set if the pointer to it is not NULL. */
-astMAKE_TEST(Channel,SinkFile,( this->fn_out != NULL ))
-
-
-/*
-*att++
-* Name:
-* Comment
-
-* Purpose:
-* Include textual comments in output?
-
-* Type:
-* Public attribute.
-
-* Synopsis:
-* Integer (boolean).
-
-* Description:
-* This is a boolean attribute which controls whether textual
-* comments are to be included in the output generated by a
-* Channel. If included, they will describe what each item of
-* output represents.
-*
-* If Comment is non-zero, then comments will be included. If
-* it is zero, comments will be omitted.
-
-* Applicability:
-* Channel
-* The default value is non-zero for a normal Channel.
-* FitsChan
-* The default value is non-zero for a FitsChan.
-* XmlChan
-* The default value is zero for an XmlChan.
-
-*att--
-*/
-
-/* This is a boolean value (0 or 1) with a value of -INT_MAX when
- undefined but yielding a default of one. */
-astMAKE_CLEAR(Channel,Comment,comment,-INT_MAX)
-astMAKE_GET(Channel,Comment,int,0,( this->comment != -INT_MAX ? this->comment : 1 ))
-astMAKE_SET(Channel,Comment,int,comment,( value != 0 ))
-astMAKE_TEST(Channel,Comment,( this->comment != -INT_MAX ))
-
-/*
-*att++
-* Name:
-* Full
-
-* Purpose:
-* Set level of output detail.
-
-* Type:
-* Public attribute.
-
-* Synopsis:
-* Integer.
-
-* Description:
-* This attribute is a three-state flag and takes values of -1, 0
-* or +1. It controls the amount of information included in the
-* output generated by a Channel.
-*
-* If Full is zero, then a modest amount of
-* non-essential but useful information will be included in the
-* output. If Full is negative, all non-essential information will
-* be suppressed to minimise the amount of output, while if it is
-* positive, the output will include the maximum amount of detailed
-* information about the Object being written.
-
-* Applicability:
-* Channel
-* The default value is zero for a normal Channel.
-* FitsChan
-* The default value is zero for a FitsChan.
-* XmlChan
-* The default value is -1 for an XmlChan.
-* StcsChan
-* The default value is zero for an StcsChan. Set a positive value
-* to cause default values to be included in STC-S descriptions.
-
-* Notes:
-* - All positive values supplied for this attribute are converted
-* to +1 and all negative values are converted to -1.
-*att--
-*/
-
-/* This ia a 3-state value (-1, 0 or +1) with a value of -INT_MAX when
- undefined but yielding a default of zero. */
-astMAKE_CLEAR(Channel,Full,full,-INT_MAX)
-astMAKE_GET(Channel,Full,int,0,( this->full != -INT_MAX ? this->full : 0 ))
-astMAKE_SET(Channel,Full,int,full,( value > 0 ? 1 : ( value < 0 ? -1 : 0 ) ))
-astMAKE_TEST(Channel,Full,( this->full != -INT_MAX ))
-
-/*
-*att++
-* Name:
-* Indent
-
-* Purpose:
-* Specifies the indentation to use in text produced by a Channel.
-
-* Type:
-* Public attribute.
-
-* Synopsis:
-* Integer (boolean).
-
-* Description:
-* This attribute controls the indentation within the output text produced by
-f the AST_WRITE function.
-c the astWrite function.
-* It gives the increase in the indentation for each level in the object
-* heirarchy. If it is set to zero, no indentation will be used. [3]
-
-* Applicability:
-* Channel
-* The default value is zero for a basic Channel.
-* FitsChan
-* The FitsChan class ignores this attribute.
-* StcsChan
-* The default value for an StcsChan is zero, which causes the entire
-* STC-S description is written out by a single invocation of the sink
-* function. The text supplied to the sink function will not contain
-* any linefeed characters, and each pair of adjacent words will be
-* separated by a single space. The text may thus be arbitrarily large
-* and the StcsLength attribute is ignored.
-*
-* If Indent is non-zero, then the text is written out via multiple
-* calls to the sink function, each call corresponding to a single
-* "line" of text (although no line feed characters will be inserted
-* by AST). The complete STC-S description is broken into lines so that:
-*
-* - the line length specified by attribute StcsLength is not exceeded
-* - each sub-phrase (time, space, etc.) starts on a new line
-* - each argument in a compound spatial region starts on a new line
-*
-* If this causes a sub-phrase to extend to two or more lines, then the
-* second and subsequent lines will be indented by three spaces compared
-* to the first line. In addition, lines within a compound spatial region
-* will have extra indentation to highlight the nesting produced by the
-* parentheses. Each new level of nesting will be indented by a further
-* three spaces.
-f
-f Note, the default value of zero is unlikely to be appropriate when
-f an StcsChan is used within Fortran code. In this case, Indent
-f should usually be set non-zero, and the StcsLength attribute set to
-f the size of the CHARACTER variable used to
-f receive the text returned by AST_GETLINE within the sink function.
-f This avoids the possibility of long lines being truncated invisibly
-f within AST_GETLINE.
-* XmlChan
-* The default value for an XmlChan is zero, which results in no
-* linefeeds or indentation strings being added to output text.
-* If any non-zero value is assigned to Indent, then extra linefeed and
-* space characters will be inserted as necessary to ensure that each
-* XML tag starts on a new line, and each tag will be indented by
-* a further 3 spaces to show its depth in the containment hierarchy.
-*att--
-*/
-
-/* This is an integer value with a value of -INT_MAX when undefined,
- yielding a default of 3. Sub-classes may over-ride theis default. */
-astMAKE_CLEAR(Channel,Indent,indent,-INT_MAX)
-astMAKE_GET(Channel,Indent,int,3,( this->indent != -INT_MAX ? this->indent : 3 ))
-astMAKE_SET(Channel,Indent,int,indent,value)
-astMAKE_TEST(Channel,Indent,( this->indent != -INT_MAX ))
-
-/*
-*att++
-* Name:
-* ReportLevel
-
-* Purpose:
-* Determines which read/write conditions are reported.
-
-* Type:
-* Public attribute.
-
-* Synopsis:
-* Integer.
-
-* Description:
-* This attribute determines which, if any, of the conditions that occur
-* whilst reading or writing an Object should be reported. These
-* conditions will generate either a fatal error or a warning, as
-* determined by attribute Strict. ReportLevel can take any of the
-* following values:
-*
-* 0 - Do not report any conditions.
-*
-* 1 - Report only conditions where significant information content has been
-* changed. For instance, an unsupported time-scale has been replaced by a
-* supported near-equivalent time-scale. Another example is if a basic
-* Channel unexpected encounters data items that may have been introduced
-* by later versions of AST.
-*
-* 2 - Report the above, and in addition report significant default
-* values. For instance, if no time-scale was specified when reading an
-* Object from an external data source, report the default time-scale
-* that is being used.
-*
-* 3 - Report the above, and in addition report any other potentially
-* interesting conditions that have no significant effect on the
-* conversion. For instance, report if a time-scale of "TT"
-* (terrestrial time) is used in place of "ET" (ephemeris time). This
-* change has no signficiant effect because ET is the predecessor of,
-* and is continuous with, TT. Synonyms such as "IAT" and "TAI" are
-* another example.
-*
-* The default value is 1. Note, there are many other conditions that
-* can occur whilst reading or writing an Object that completely
-* prevent the conversion taking place. Such conditions will always
-* generate errors, irrespective of the ReportLevel and Strict attributes.
-
-* Applicability:
-* Channel
-* All Channels have this attribute.
-* FitsChan
-* All the conditions selected by the FitsChan Warnings attribute are
-* reported at level 1.
-*att--
-*/
-
-/* This is an integer value with a value of -INT_MAX when undefined,
- yielding a default of one. */
-astMAKE_CLEAR(Channel,ReportLevel,report_level,-INT_MAX)
-astMAKE_GET(Channel,ReportLevel,int,1,( this->report_level != -INT_MAX ? this->report_level : 1 ))
-astMAKE_SET(Channel,ReportLevel,int,report_level,value)
-astMAKE_TEST(Channel,ReportLevel,( this->report_level != -INT_MAX ))
-
-/*
-*att++
-* Name:
-* Skip
-
-* Purpose:
-* Skip irrelevant data?
-
-* Type:
-* Public attribute.
-
-* Synopsis:
-* Integer (boolean).
-
-* Description:
-* This is a boolean attribute which indicates whether the Object
-* data being read through a Channel are inter-mixed with other,
-* irrelevant, external data.
-*
-* If Skip is zero (the default), then the source of input data is
-* expected to contain descriptions of AST Objects and comments and
-* nothing else (if anything else is read, an error will
-* result). If Skip is non-zero, then any non-Object data
-* encountered between Objects will be ignored and simply skipped
-* over in order to reach the next Object.
-
-* Applicability:
-* Channel
-* All Channels have this attribute.
-* FitsChan
-* The FitsChan class sets the default value of this attribute
-* to 1, so that all irrelevant FITS headers will normally be
-* ignored.
-*att--
-*/
-
-/* This ia a boolean value (0 or 1) with a value of -INT_MAX when
- undefined but yielding a default of zero. */
-astMAKE_CLEAR(Channel,Skip,skip,-INT_MAX)
-astMAKE_GET(Channel,Skip,int,0,( this->skip != -INT_MAX ? this->skip : 0 ))
-astMAKE_SET(Channel,Skip,int,skip,( value != 0 ))
-astMAKE_TEST(Channel,Skip,( this->skip != -INT_MAX ))
-
-/*
-*att++
-* Name:
-* Strict
-
-* Purpose:
-* Report an error if any unexpeted data items are found?
-
-* Type:
-* Public attribute.
-
-* Synopsis:
-* Integer (boolean).
-
-* Description:
-* This is a boolean attribute which indicates whether a warning
-* rather than an error should be issed for insignificant conversion
-* problems. If it is set non-zero, then fatal errors are issued
-* instead of warnings, resulting in the
-c AST error status being set.
-f inherited STATUS variable being set to an error value.
-* If Strict is zero (the default), then execution continues after minor
-* conversion problems, and a warning message is added to the Channel
-* structure. Such messages can be retrieved using the
-c astWarnings
-f AST_WARNINGS
-* function.
-
-* Notes:
-* - This attribute was introduced in AST version 5.0. Prior to this
-* version of AST unexpected data items read by a basic Channel always
-* caused an error to be reported. So applications linked against
-* versions of AST prior to version 5.0 may not be able to read Object
-* descriptions created by later versions of AST, if the Object's class
-* description has changed.
-
-* Applicability:
-* Channel
-* All Channels have this attribute.
-*att--
-*/
-
-/* This ia a boolean value (0 or 1) with a value of -INT_MAX when
- undefined but yielding a default of zero. */
-astMAKE_CLEAR(Channel,Strict,strict,-INT_MAX)
-astMAKE_GET(Channel,Strict,int,0,( this->strict != -INT_MAX ? this->strict : 0 ))
-astMAKE_SET(Channel,Strict,int,strict,( value != 0 ))
-astMAKE_TEST(Channel,Strict,( this->strict != -INT_MAX ))
-
-/* Destructor. */
-/* ----------- */
-static void Delete( AstObject *obj, int *status ) {
-/*
-* Name:
-* Delete
-
-* Purpose:
-* Destructor for Channel objects.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* void Delete( AstObject *obj, int *status )
-
-* Description:
-* This function implements the destructor for Channel objects.
-
-* Parameters:
-* obj
-* Pointer to the object to be deleted.
-* status
-* Pointer to the inherited status variable.
-
-* Notes:
-* This function attempts to execute even if the global error status is
-* set.
-*/
-
-/* Local Variables: */
- AstChannel *this; /* Pointer to Channel */
-
-/* Obtain a pointer to the Channel structure. */
- this = (AstChannel *) obj;
-
-/* Free memory used to store warnings. */
- astAddWarning( this, 0, NULL, NULL, status );
-
-/* Close any open input or output files. */
- if( this->fd_in ) fclose( this->fd_in );
- if( this->fd_out ) fclose( this->fd_out );
-
-/* Free file name memory. */
- this->fn_in = astFree( this->fn_in );
- this->fn_out = astFree( this->fn_out );
-}
-
-/* Copy constructor. */
-/* ----------------- */
-static void Copy( const AstObject *objin, AstObject *objout, int *status ) {
-/*
-* Name:
-* Copy
-
-* Purpose:
-* Copy constructor for Channel objects.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* void Copy( const AstObject *objin, AstObject *objout, int *status )
-
-* Description:
-* This function implements the copy constructor for Channel objects.
-
-* Parameters:
-* objin
-* Pointer to the object to be copied.
-* objout
-* Pointer to the object being constructed.
-* status
-* Pointer to the inherited status variable.
-
-* Notes:
-* - This constructor makes a deep copy.
-*/
-
-/* Local Variables: */
- AstChannel *out; /* Pointer to output Channel */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain pointers to the input and output Channels. */
- out = (AstChannel *) objout;
-
-/* Just clear any references to the input memory from the output Channel. */
- out->warnings = NULL;
- out->nwarn = 0;
- out->fd_in = NULL;
- out->fn_in = NULL;
- out->fd_out = NULL;
- out->fn_out = NULL;
-}
-
-/* Dump function. */
-/* -------------- */
-static void Dump( AstObject *this_object, AstChannel *channel, int *status ) {
-/*
-* Name:
-* Dump
-
-* Purpose:
-* Dump function for Channel 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 Channel class to an output Channel.
-
-* Parameters:
-* this
-* Pointer to the Object 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: */
- AstChannel *this; /* Pointer to the Channel structure */
- const char *comment; /* Pointer to comment string */
- int ival; /* Integer value */
- int set; /* Attribute value set? */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the Channel structure. */
- this = (AstChannel *) this_object;
-
-/* Write out values representing the instance variables for the
- Channel 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. */
-
-/* Indent */
-/* ------------ */
- set = TestIndent( this, status );
- ival = set ? GetIndent( this, status ) : astGetIndent( this );
- astWriteInt( channel, "Indnt", set, 0, ival, "Indentation increment" );
-
-/* ReportLevel. */
-/* ------------ */
- set = TestReportLevel( this, status );
- ival = set ? GetReportLevel( this, status ) : astGetReportLevel( this );
- astWriteInt( channel, "RpLev", set, 0, ival, "Error reporting level" );
-
-/* Skip. */
-/* ----- */
- set = TestSkip( this, status );
- ival = set ? GetSkip( this, status ) : astGetSkip( this );
- astWriteInt( channel, "Skip", set, 0, ival,
- ival ? "Ignore data between Objects" :
- "No data allowed between Objects" );
-
-/* Strict. */
-/* ------- */
- set = TestStrict( this, status );
- ival = set ? GetStrict( this, status ) : astGetStrict( this );
- astWriteInt( channel, "Strict", set, 0, ival,
- ival ? "Report errors insead of warnings" :
- "Report warnings instead of errors" );
-
-/* Full. */
-/* ----- */
- set = TestFull( this, status );
- ival = set ? GetFull( this, status ) : astGetFull( this );
- if ( ival < 0 ) {
- comment = "Suppress non-essential output";
- }else if ( ival == 0 ) {
- comment = "Output standard information";
- } else {
- comment = "Output maximum information";
- }
- astWriteInt( channel, "Full", set, 0, ival, comment );
-
-/* Comment. */
-/* -------- */
- set = TestComment( this, status );
- ival = set ? GetComment( this, status ) : astGetComment( this );
- astWriteInt( channel, "Comm", set, 0, ival,
- ival ? "Display comments" :
- "Omit comments" );
-}
-
-/* Standard class functions. */
-/* ========================= */
-/* Implement the astIsAChannel and astCheckChannel functions using the
- macros defined for this purpose in the "object.h" header file. */
-astMAKE_ISA(Channel,Object)
-astMAKE_CHECK(Channel)
-
-AstChannel *astChannel_( const char *(* source)( void ),
- void (* sink)( const char * ),
- const char *options, int *status, ...) {
-/*
-*+
-* Name:
-* astChannel
-
-* Purpose:
-* Create a Channel.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "channel.h"
-* AstChannel *astChannel( const char *(* source)( void ),
-* void (* sink)( const char * ),
-* const char *options, ..., int *status )
-
-* Class Membership:
-* Channel constructor.
-
-* Description:
-* This function creates a new Channel and optionally initialises
-* its attributes.
-*
-* A Channel implements low-level input/output for the AST library.
-* Writing an Object to a Channel (using astWrite) will generate a
-* textual representation of that Object, and reading from a
-* Channel (using astRead) will create a new Object from its
-* textual representation.
-*
-* Normally, when you use a Channel, you should provide "source"
-* and "sink" functions which connect it to an external data store
-* by reading and writing the resulting text. By default, however,
-* a Channel will read from standard input and write to standard
-* output.
-
-* Parameters:
-* source
-* Pointer to a "source" function that takes no arguments and
-* returns a pointer to a null-terminated string.
-*
-* This function will be used by the Channel to obtain lines of
-* input text. On each invocation, it should return a pointer to
-* the next input line read from some external data store, and a
-* NULL pointer when there are no more lines to read.
-*
-* If "source" is NULL, the Channel will read from standard
-* input instead.
-* sink
-* Pointer to a "sink" function that takes a pointer to a
-* null-terminated string as an argument and returns void.
-*
-* This function will be used by the Channel to deliver lines of
-* output text. On each invocation, it should deliver the
-* contents of the string supplied to some external data store.
-*
-* If "sink" is NULL, the Channel will write to standard output
-* instead.
-* options
-* Pointer to a null-terminated string containing an optional
-* comma-separated list of attribute assignments to be used for
-* initialising the new Channel. The syntax used is identical to
-* that for the astSet function 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 additional 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 function (and for the C "printf"
-* function).
-
-* Returned Value:
-* astChannel()
-* A pointer to the new Channel.
-
-* Notes:
-* - A NULL pointer value will be returned if this function is
-* invoked with the global error status set, or if it should fail
-* for any reason.
-*-
-
-* Implementation Notes:
-* - This function implements the basic Channel constructor which
-* is available via the protected interface to the Channel class.
-* A public interface is provided by the astChannelId_ function.
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Pointer to thread-specific global data */
- AstChannel *new; /* Pointer to new Channel */
- va_list args; /* Variable argument list */
-
-/* Get a pointer to the thread specific global data structure. */
- astGET_GLOBALS(NULL);
-
-/* Check the global status. */
- if ( !astOK ) return NULL;
-
-/* Initialise the Channel, allocating memory and initialising the
- virtual function table as well if necessary. Supply pointers to
- (local) wrapper functions that can invoke the source and sink
- functions with appropriate arguments for the C language. */
- new = astInitChannel( NULL, sizeof( AstChannel ), !class_init, &class_vtab,
- "Channel", source, SourceWrap, sink, SinkWrap );
-
-/* 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
- Channel's 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 Channel. */
- return new;
-}
-
-AstChannel *astChannelId_( const char *(* source)( void ),
- void (* sink)( const char * ),
- const char *options, ... ) {
-/*
-*++
-* Name:
-c astChannel
-f AST_CHANNEL
-
-* Purpose:
-* Create a Channel.
-
-* Type:
-* Public function.
-
-* Synopsis:
-c #include "channel.h"
-c AstChannel *astChannel( const char *(* source)( void ),
-c void (* sink)( const char * ),
-c const char *options, ... )
-f RESULT = AST_CHANNEL( SOURCE, SINK, OPTIONS, STATUS )
-
-* Class Membership:
-* Channel constructor.
-
-* Description:
-* This function creates a new Channel and optionally initialises
-* its attributes.
-*
-* A Channel implements low-level input/output for the AST library.
-c Writing an Object to a Channel (using astWrite) will generate a
-f Writing an Object to a Channel (using AST_WRITE) will generate a
-* textual representation of that Object, and reading from a
-c Channel (using astRead) will create a new Object from its
-f Channel (using AST_READ) will create a new Object from its
-* textual representation.
-*
-* Normally, when you use a Channel, you should provide "source"
-c and "sink" functions which connect it to an external data store
-f and "sink" routines which connect it to an external data store
-* by reading and writing the resulting text. By default, however,
-* a Channel will read from standard input and write to standard
-* output. Alternatively, a Channel can be told to read or write from
-* specific text files using the SinkFile and SourceFile attributes,
-* in which case no sink or source function need be supplied.
-
-* Parameters:
-c source
-f SOURCE = SUBROUTINE (Given)
-c Pointer to a source function that takes no arguments and
-c returns a pointer to a null-terminated string. If no value
-c has been set for the SourceFile attribute, this function
-c will be used by the Channel to obtain lines of input text. On
-c each invocation, it should return a pointer to the next input
-c line read from some external data store, and a NULL pointer
-c when there are no more lines to read.
-c
-c If "source" is NULL and no value has been set for the SourceFile
-c attribute, the Channel will read from standard input instead.
-f A source routine, which is a subroutine which takes a single
-f integer error status argument. If no value has been set
-f for the SourceFile attribute, this routine will be used by
-f the Channel to obtain lines of input text. On each
-f invocation, it should read the next input line from some
-f external data store, and then return the resulting text to
-f the AST library by calling AST_PUTLINE. It should supply a
-f negative line length when there are no more lines to read.
-f If an error occurs, it should set its own error status
-f argument to an error value before returning.
-f
-f If the null routine AST_NULL is suppied as the SOURCE value,
-f and no value has been set for the SourceFile attribute,
-f the Channel will read from standard input instead.
-c sink
-f SINK = SUBROUTINE (Given)
-c Pointer to a sink function that takes a pointer to a
-c null-terminated string as an argument and returns void.
-c If no value has been set for the SinkFile attribute, this
-c function will be used by the Channel to deliver lines of
-c output text. On each invocation, it should deliver the
-c contents of the string supplied to some external data store.
-c
-c If "sink" is NULL, and no value has been set for the SinkFile
-c attribute, the Channel will write to standard output instead.
-f A sink routine, which is a subroutine which takes a single
-f integer error status argument. If no value has been set
-f for the SinkFile attribute, this routine will be used by
-f the Channel to deliver lines of output text. On each
-f invocation, it should obtain the next output line from the
-f AST library by calling AST_GETLINE, and then deliver the
-f resulting text to some external data store. If an error
-f occurs, it should set its own error status argument to an
-f error value before returning.
-f
-f If the null routine AST_NULL is suppied as the SINK value,
-f and no value has been set for the SinkFile attribute,
-f the Channel will write to standard output instead.
-c options
-f OPTIONS = CHARACTER * ( * ) (Given)
-c Pointer to a null-terminated string containing an optional
-c comma-separated list of attribute assignments to be used for
-c initialising the new Channel. The syntax used is identical to
-c that for the astSet function and may include "printf" format
-c specifiers identified by "%" symbols in the normal way.
-f A character string containing an optional comma-separated
-f list of attribute assignments to be used for initialising the
-f new Channel. The syntax used is identical to that for the
-f AST_SET routine.
-c ...
-c If the "options" string contains "%" format specifiers, then
-c an optional list of additional arguments may follow it in
-c order to supply values to be substituted for these
-c specifiers. The rules for supplying these are identical to
-c those for the astSet function (and for the C "printf"
-c function).
-f STATUS = INTEGER (Given and Returned)
-f The global status.
-
-* Returned Value:
-c astChannel()
-f AST_CHANNEL = INTEGER
-* A pointer to the new Channel.
-
-* Notes:
-c - Application code can pass arbitrary data (such as file
-c descriptors, etc) to source and sink functions using the
-c astPutChannelData function. The source or sink function should use
-c the astChannelData macro to retrieve this data.
-f - The names of the routines supplied for the SOURCE and SINK
-f arguments should appear in EXTERNAL statements in the Fortran
-f routine which invokes AST_CHANNEL. However, this is not generally
-f necessary for the null routine AST_NULL (so long as the AST_PAR
-f include file has been used).
-* - A null Object pointer (AST__NULL) will be returned if this
-c function is invoked with the AST error status set, or if it
-f function is invoked with STATUS set to an error value, or if it
-* should fail for any reason.
-f - Note that the null routine AST_NULL (one underscore) is
-f different to AST__NULL (two underscores), which is the null Object
-f pointer.
-*--
-
-* Implementation Notes:
-* - This function implements the external (public) interface to
-* the astChannel constructor function. It returns an ID value
-* (instead of a true C pointer) to external users, and must be
-* provided because astChannel_ 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 astChanel_ 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.
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Pointer to thread-specific global data */
- AstChannel *new; /* Pointer to new Channel */
- 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 status. */
- if ( !astOK ) return NULL;
-
-/* Initialise the Channel, allocating memory and initialising the
- virtual function table as well if necessary. Supply pointers to
- (local) wrapper functions that can invoke the source and sink
- functions with appropriate arguments for the C language. */
- new = astInitChannel( NULL, sizeof( AstChannel ), !class_init, &class_vtab,
- "Channel", source, SourceWrap, sink, SinkWrap );
-
-/* 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
- Channel's 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 Channel. */
- return astMakeId( new );
-}
-
-AstChannel *astChannelForId_( const char *(* source)( void ),
- char *(* source_wrap)( const char *(*)( void ), int * ),
- void (* sink)( const char * ),
- void (* sink_wrap)( void (*)( const char * ),
- const char *, int * ),
- const char *options, ... ) {
-/*
-*+
-* Name:
-* astChannelFor
-
-* Purpose:
-* Initialise a Channel from a foreign language interface.
-
-* Type:
-* Public function.
-
-* Synopsis:
-* #include "channel.h"
-* AstChannel *astChannelFor( const char *(* source)( void ),
-* char *(* source_wrap)( const char *(*)
-* ( void ), int * ),
-* void (* sink)( const char * ),
-* void (* sink_wrap)( void (*)( const char * ),
-* const char *, int * ),
-* const char *options, ... )
-
-* Class Membership:
-* Channel constructor.
-
-* Description:
-* This function creates a new Channel from a foreign language
-* interface and optionally initialises its attributes.
-*
-* A Channel implements low-level input/output for the AST library.
-* Writing an Object to a Channel (using astWrite) will generate a
-* textual representation of that Object, and reading from a
-* Channel (using astRead) will create a new Object from its
-* textual representation.
-*
-* Normally, when you use a Channel, you should provide "source"
-* and "sink" functions which connect it to an external data store
-* by reading and writing the resulting text. This function also
-* requires you to provide "wrapper" functions which will invoke
-* the source and sink functions. By default, however, a Channel
-* will read from standard input and write to standard output.
-
-* Parameters:
-* source
-* Pointer to a "source" function which will be used to obtain
-* lines of input text. Generally, this will be obtained by
-* casting a pointer to a source function which is compatible
-* with the "source_wrap" wrapper function (below). The pointer
-* should later be cast back to its original type by the
-* "source_wrap" function before the function is invoked.
-*
-* If "source" is NULL, the Channel will read from standard
-* input instead.
-* source_wrap
-* Pointer to a function which can be used to invoke the
-* "source" function supplied (above). This wrapper function is
-* necessary in order to hide variations in the nature of the
-* source function, such as may arise when it is supplied by a
-* foreign (non-C) language interface.
-*
-* The single parameter of the "source_wrap" function is a
-* pointer to the "source" function, and it should cast this
-* function pointer (as necessary) and invoke the function with
-* appropriate arguments to obtain the next line of input
-* text. The "source_wrap" function should then return a pointer
-* to a dynamically allocated, null terminated string containing
-* the text that was read. The string will be freed (using
-* astFree) when no longer required and the "source_wrap"
-* function need not concern itself with this. A NULL pointer
-* should be returned if there is no more input to read.
-*
-* If "source_wrap" is NULL, the Channel will read from standard
-* input instead.
-* sink
-* Pointer to a "sink" function which will be used to deliver
-* lines of output text. Generally, this will be obtained by
-* casting a pointer to a sink function which is compatible with
-* the "sink_wrap" wrapper function (below). The pointer should
-* later be cast back to its original type by the "sink_wrap"
-* function before the function is invoked.
-*
-* If "sink" is NULL, the Channel will write to standard output
-* instead.
-* sink_wrap
-* Pointer to a function which can be used to invoke the "sink"
-* function supplied (above). This wrapper function is necessary
-* in order to hide variations in the nature of the sink
-* function, such as may arise when it is supplied by a foreign
-* (non-C) language interface.
-*
-* The first parameter of the "sink_wrap" function is a pointer
-* to the "sink" function, and the second parameter is a pointer
-* to a const, null-terminated character string containing the
-* text to be written. The "sink_wrap" function should cast the
-* "sink" function pointer (as necessary) and invoke the
-* function with appropriate arguments to deliver the line of
-* output text. The "sink_wrap" function then returns void.
-*
-* If "sink_wrap" is NULL, the Channel will write to standard
-* output instead.
-* options
-* Pointer to a null-terminated string containing an optional
-* comma-separated list of attribute assignments to be used for
-* initialising the new Channel. The syntax used is identical to
-* that for the astSet function and may include "printf" format
-* specifiers identified by "%" symbols in the normal way.
-* ...
-* If the "options" string contains "%" format specifiers, then
-* an optional list of additional 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 function (and for the C "printf"
-* function).
-
-* Returned Value:
-* astChannelFor()
-* A pointer to the new Channel.
-
-* Notes:
-* - A null Object pointer (AST__NULL) will be returned if this
-* function is invoked with the global error status set, or if it
-* should fail for any reason.
-* - This function is only available through the public interface
-* to the Channel class (not the protected interface) and is
-* intended solely for use in implementing foreign language
-* interfaces to this class.
-*-
-
-* Implememtation Notes:
-* - This function behaves exactly like astChannelId_, in that it
-* returns ID values and not true C pointers, but it has two
-* additional arguments. These are pointers to the "wrapper
-* functions" which are needed to accommodate foreign language
-* interfaces.
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Declare the thread specific global data */
- AstChannel *new; /* Pointer to new Channel */
- va_list args; /* Variable argument list */
- int *status; /* Pointer to inherited status value */
-
-/* Get a pointer to the inherited status value. */
- status = astGetStatusPtr;
-
-/* Check the global status. */
- if ( !astOK ) return NULL;
-
-/* Get a pointer to the thread specific global data structure. */
- astGET_GLOBALS(NULL);
-
-/* Initialise the Channel, allocating memory and initialising the
- virtual function table as well if necessary. */
- new = astInitChannel( NULL, sizeof( AstChannel ), !class_init, &class_vtab,
- "Channel", source, source_wrap, sink, sink_wrap );
-
-/* 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
- Channel's 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 Channel. */
- return astMakeId( new );
-}
-
-AstChannel *astLoadChannel_( void *mem, size_t size,
- AstChannelVtab *vtab, const char *name,
- AstChannel *channel, int *status ) {
-/*
-*+
-* Name:
-* astLoadChannel
-
-* Purpose:
-* Load a Channel.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "channel.h"
-* AstChannel *astLoadChannel( void *mem, size_t size,
-* AstChannelVtab *vtab, const char *name,
-* AstChannel *channel )
-
-* Class Membership:
-* Channel loader.
-
-* Description:
-* This function is provided to load a new Channel 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
-* Channel 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 Channel at the start of the memory
-* passed via the "vtab" parameter.
-
-
-* Parameters:
-* mem
-* A pointer to the memory into which the Channel is to be
-* loaded. This must be of sufficient size to accommodate the
-* Channel data (sizeof(Channel)) 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 Channel (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 Channel 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(AstChannel) is used instead.
-* vtab
-* Pointer to the start of the virtual function table to be
-* associated with the new Channel. If this is NULL, a pointer
-* to the (static) virtual function table for the Channel 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 "Channel" is used instead.
-
-* Returned Value:
-* A pointer to the new Channel.
-
-* 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 */
- AstChannel *new; /* Pointer to the new Channel */
-
-/* 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 Channel. In this case the
- Channel belongs to this class, so supply appropriate values to be
- passed to the parent class loader (and its parent, etc.). */
- if ( !vtab ) {
- size = sizeof( AstChannel );
- vtab = &class_vtab;
- name = "Channel";
-
-/* If required, initialise the virtual function table for this class. */
- if ( !class_init ) {
- astInitChannelVtab( 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 Channel. */
- new = astLoadObject( mem, size, (AstObjectVtab *) 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, "Channel" );
-
-/* Set the pointers to the source and sink functions, and their
- wrapper functions, to NULL (we cannot restore these since they
- refer to process-specific addresses). */
- new->source = NULL;
- new->source_wrap = NULL;
- new->sink = NULL;
- new->sink_wrap = NULL;
-
-/* We do not have any data to pass to the source and sink functions. */
- new->data = NULL;
-
-/* No warnings yet. */
- new->warnings = NULL;
- new->nwarn = 0;
-
-/* Indicate no input or output files have been associated with the
- Channel. */
- new->fd_in = NULL;
- new->fn_in = NULL;
- new->fd_out = NULL;
- new->fn_out = NULL;
-
-/* 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. */
-
-/* Indent. */
-/* ------- */
- new->indent = astReadInt( channel, "indnt", -INT_MAX );
- if ( TestIndent( new, status ) ) SetIndent( new, new->indent, status );
-
-/* ReportLevel. */
-/* ------------ */
- new->report_level = astReadInt( channel, "rplev", -INT_MAX );
- if ( TestReportLevel( new, status ) ) SetReportLevel( new,
- new->report_level,
- status );
-
-/* Skip. */
-/* ----- */
- new->skip = astReadInt( channel, "skip", -INT_MAX );
- if ( TestSkip( new, status ) ) SetSkip( new, new->skip, status );
-
-/* Strict. */
-/* ------- */
- new->strict = astReadInt( channel, "strict", -INT_MAX );
- if ( TestStrict( new, status ) ) SetStrict( new, new->strict, status );
-
-/* Full. */
-/* ----- */
- new->full = astReadInt( channel, "full", -INT_MAX );
- if ( TestFull( new, status ) ) SetFull( new, new->full, status );
-
-/* Comment. */
-/* -------- */
- new->comment = astReadInt( channel, "comm", -INT_MAX );
- if ( TestComment( new, status ) ) SetComment( new, new->comment, status );
-
-/* If an error occurred, clean up by deleting the new Channel. */
- if ( !astOK ) new = astDelete( new );
- }
-
-/* Return the new Channel 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. */
-void astGetNextData_( AstChannel *this, int begin, char **name, char **val, int *status ) {
- *name = NULL;
- *val = NULL;
- if ( !astOK ) return;
- (**astMEMBER(this,Channel,GetNextData))( this, begin, name, val, status );
-}
-char *astGetNextText_( AstChannel *this, int *status ) {
- if ( !astOK ) return NULL;
- return (**astMEMBER(this,Channel,GetNextText))( this, status );
-}
-void astPutNextText_( AstChannel *this, const char *line, int *status ) {
- if ( !astOK ) return;
- (**astMEMBER(this,Channel,PutNextText))( this, line, status );
-}
-AstObject *astRead_( AstChannel *this, int *status ) {
- if ( !astOK ) return NULL;
- astAddWarning( this, 0, NULL, NULL, status );
- return (**astMEMBER(this,Channel,Read))( this, status );
-}
-void astReadClassData_( AstChannel *this, const char *class, int *status ) {
- if ( !astOK ) return;
- (**astMEMBER(this,Channel,ReadClassData))( this, class, status );
-}
-double astReadDouble_( AstChannel *this, const char *name, double def, int *status ) {
- if ( !astOK ) return 0.0;
- return (**astMEMBER(this,Channel,ReadDouble))( this, name, def, status );
-}
-int astReadInt_( AstChannel *this, const char *name, int def, int *status ) {
- if ( !astOK ) return 0;
- return (**astMEMBER(this,Channel,ReadInt))( this, name, def, status );
-}
-AstObject *astReadObject_( AstChannel *this, const char *name,
- AstObject *def, int *status ) {
- if ( !astOK ) return NULL;
- return (**astMEMBER(this,Channel,ReadObject))( this, name, def, status );
-}
-char *astReadString_( AstChannel *this, const char *name, const char *def, int *status ) {
- if ( !astOK ) return NULL;
- return (**astMEMBER(this,Channel,ReadString))( this, name, def, status );
-}
-void astWriteBegin_( AstChannel *this, const char *class,
- const char *comment, int *status ) {
- if ( !astOK ) return;
- (**astMEMBER(this,Channel,WriteBegin))( this, class, comment, status );
-}
-void astWriteDouble_( AstChannel *this, const char *name, int set, int helpful,
- double value, const char *comment, int *status ) {
- if ( !astOK ) return;
- (**astMEMBER(this,Channel,WriteDouble))( this, name, set, helpful, value,
- comment, status );
-}
-void astWriteEnd_( AstChannel *this, const char *class, int *status ) {
- if ( !astOK ) return;
- (**astMEMBER(this,Channel,WriteEnd))( this, class, status );
-}
-void astWriteInt_( AstChannel *this, const char *name, int set, int helpful,
- int value, const char *comment, int *status ) {
- if ( !astOK ) return;
- (**astMEMBER(this,Channel,WriteInt))( this, name, set, helpful, value,
- comment, status );
-}
-void astWriteIsA_( AstChannel *this, const char *class, const char *comment, int *status ) {
- if ( !astOK ) return;
- (**astMEMBER(this,Channel,WriteIsA))( this, class, comment, status );
-}
-void astWriteString_( AstChannel *this, const char *name, int set, int helpful,
- const char *value, const char *comment, int *status ) {
- if ( !astOK ) return;
- (**astMEMBER(this,Channel,WriteString))( this, name, set, helpful, value,
- comment, status );
-}
-void astPutChannelData_( AstChannel *this, void *data, int *status ) {
- if ( !astOK ) return;
- (**astMEMBER(this,Channel,PutChannelData))( this, data, status );
-}
-
-AstKeyMap *astWarnings_( AstChannel *this, int *status ){
- if( !astOK ) return NULL;
- return (**astMEMBER(this,Channel,Warnings))( this, status );
-}
-
-/* Because of the variable argument list, we need to work a bit harder on
- astAddWarning. Functions that provide implementations of the
- astAddWarning method recieve the fully expanded message and so do not
- need a variable argument list. */
-
-void astAddWarning_( void *this_void, int level, const char *fmt,
- const char *method, int *status, ... ) {
- AstChannel *this;
- char buff[ 201 ];
- va_list args;
- int nc;
-
- this = astCheckChannel( this_void );
-
- if( fmt ) {
- if( astOK ) {
- va_start( args, status );
- nc = vsprintf( buff, fmt, args );
- va_end( args );
- if( nc > 200 ) {
- astError( AST__INTER, "astAddWarning(%s): Message buffer size "
- "exceeded (internal AST programming error).",
- status, astGetClass( this ) );
- } else {
- (**astMEMBER(this,Channel,AddWarning))( this, level, buff, method, status );
- }
- }
- } else {
- (**astMEMBER(this,Channel,AddWarning))( this, level, NULL, method, status );
- }
-}
-
-/* Count the number of times astWrite is invoked (excluding invocations
- made from within the astWriteObject method - see below). The count is
- done here so that invocations of astWrite within a sub-class will be
- included. */
-int astWrite_( AstChannel *this, AstObject *object, int *status ) {
- astDECLARE_GLOBALS
- if ( !astOK ) return 0;
- astGET_GLOBALS(this);
- nwrite_invoc++;
- astAddWarning( this, 0, NULL, NULL, status );
- return (**astMEMBER(this,Channel,Write))( this, object, status );
-}
-
-/* We do not want to count invocations of astWrite made from within the
- astWriteObject method. So decrement the number of invocations first
- (this assumes that each invocation of astWriteObject will only invoke
- astWrite once). */
-void astWriteObject_( AstChannel *this, const char *name, int set,
- int helpful, AstObject *value, const char *comment, int *status ) {
- astDECLARE_GLOBALS
- if ( !astOK ) return;
- astGET_GLOBALS(this);
- nwrite_invoc--;
- (**astMEMBER(this,Channel,WriteObject))( this, name, set, helpful, value,
- comment, status );
-}
-
-
-
-
-