summaryrefslogtreecommitdiffstats
path: root/ast/keymap.c
diff options
context:
space:
mode:
authorWilliam Joye <wjoye@cfa.harvard.edu>2017-12-08 18:57:06 (GMT)
committerWilliam Joye <wjoye@cfa.harvard.edu>2017-12-08 18:57:06 (GMT)
commit90a861b642f765d5657ab827aedabe3920ff9333 (patch)
tree88b93d468ca1feed91ef2958f46f3f74f1418aac /ast/keymap.c
parentfba23129f50db253ed3fbbaa23d6e342bf86068e (diff)
downloadblt-90a861b642f765d5657ab827aedabe3920ff9333.zip
blt-90a861b642f765d5657ab827aedabe3920ff9333.tar.gz
blt-90a861b642f765d5657ab827aedabe3920ff9333.tar.bz2
upgrade AST
Diffstat (limited to 'ast/keymap.c')
-rw-r--r--ast/keymap.c10786
1 files changed, 0 insertions, 10786 deletions
diff --git a/ast/keymap.c b/ast/keymap.c
deleted file mode 100644
index 1578fe3..0000000
--- a/ast/keymap.c
+++ /dev/null
@@ -1,10786 +0,0 @@
-/*
-*class++
-* Name:
-* KeyMap
-
-* Purpose:
-* Store a set of key/value pairs.
-
-* Constructor Function:
-c astKeyMap
-f AST_KEYMAP
-
-* Description:
-* The KeyMap class is used to store a set of values with associated keys
-* which identify the values. The keys are strings. These may be case
-* sensitive or insensitive as selected by the KeyCase attribute, and
-* trailing spaces are ignored. The value associated with a key can be
-* integer (signed 4 and 2 byte, or unsigned 1 byte), floating point
-* (single or double precision),
-c void pointer,
-* character string or AST Object pointer. Each
-* value can be a scalar or a one-dimensional vector. A KeyMap is
-* conceptually similar to a Mapping in that a KeyMap transforms an
-* input into an output - the input is the key, and the output is the
-* value associated with the key. However, this is only a conceptual
-* similarity, and it should be noted that the KeyMap class inherits from
-* the Object class rather than the Mapping class. The methods of the
-* Mapping class cannot be used with a KeyMap.
-
-* Inheritance:
-* The KeyMap class inherits from the Object class.
-
-* Attributes:
-* In addition to those attributes common to all Objects, every
-* KeyMap also has the following attributes:
-*
-* - KeyCase: Sets the case in which keys are stored
-* - KeyError: Report an error if the requested key does not exist?
-* - SizeGuess: The expected size of the KeyMap.
-* - SortBy: Determines how keys are sorted in a KeyMap.
-* - MapLocked: Prevent new entries being added to the KeyMap?
-
-* Functions:
-c In addition to those functions applicable to all Objects, the
-c following functions may also be applied to all KeyMaps:
-f In addition to those routines applicable to all Objects, the
-f following routines may also be applied to all KeyMaps:
-*
-c - astMapDefined: Does a KeyMap contain a defined value for a key?
-c - astMapGet0<X>: Get a named scalar entry from a KeyMap
-c - astMapGet1<X>: Get a named vector entry from a KeyMap
-c - astMapGetElem<X>: Get an element of a named vector entry from a KeyMap
-c - astMapHasKey: Does the KeyMap contain a named entry?
-c - astMapKey: Return the key name at a given index in the KeyMap
-c - astMapLenC: Get the length of a named character entry in a KeyMap
-c - astMapLength: Get the length of a named entry in a KeyMap
-c - astMapCopy: Copy entries from one KeyMap into another
-c - astMapPut0<X>: Add a new scalar entry to a KeyMap
-c - astMapPut1<X>: Add a new vector entry to a KeyMap
-c - astMapPutElem<X>: Puts a value into a vector entry in a KeyMap
-c - astMapPutU: Add a new entry to a KeyMap with an undefined value
-c - astMapRemove: Removed a named entry from a KeyMap
-c - astMapRename: Rename an existing entry in a KeyMap
-c - astMapSize: Get the number of entries in a KeyMap
-c - astMapType: Return the data type of a named entry in a map
-f - AST_MAPDEFINED: Does a KeyMap contain a defined value for a key?
-f - AST_MAPGET0<X>: Get a named scalar entry from a KeyMap
-f - AST_MAPGET1<X>: Get a named vector entry from a KeyMap
-f - AST_MAPGETELEM<X>: Get an element of a named vector entry from a KeyMap
-f - AST_MAPHASKEY: Does the KeyMap contain a named entry?
-f - AST_MAPKEY: Return the key name at a given index in the KeyMap
-f - AST_MAPLENC: Get the length of a named character entry in a KeyMap
-f - AST_MAPLENGTH: Get the length of a named entry in a KeyMap
-f - AST_MAPCOPY: Copy entries from one KeyMap into another
-f - AST_MAPPUT0<X>: Add a new scalar entry to a KeyMap
-f - AST_MAPPUT1<X>: Add a new vector entry to a KeyMap
-f - AST_MAPPUTELEM<X>: Puts a value into a vector entry in a KeyMap
-f - AST_MAPPUTU: Add a new entry to a KeyMap with an undefined value
-f - AST_MAPREMOVE: Removed a named entry from a KeyMap
-f - AST_MAPRENAME: Rename an existing entry in a KeyMap
-f - AST_MAPSIZE: Get the number of entries in a KeyMap
-f - AST_MAPTYPE: Return the data type of a named entry in a map
-
-* Copyright:
-* Copyright (C) 1997-2006 Council for the Central Laboratory of the
-* Research Councils
-* Copyright (C) 2008-2010 Science & Technology Facilities Council.
-* All Rights Reserved.
-
-* Licence:
-* This program is free software: you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation, either
-* version 3 of the License, or (at your option) any later
-* version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General
-* License along with this program. If not, see
-* <http://www.gnu.org/licenses/>.
-
-* Authors:
-* DSB: B.S. Berry (Starlink)
-
-* History:
-* 12-NOV-2004 (DSB):
-* Original version.
-* 5-JAN-2005 (DSB):
-* Added astMapLenC method.
-* 17-JAN-2005 (DSB):
-* Remove "void *" arithmetic.
-* 25-JAN-2005 (DSB):
-* Added more DEBUG blocks
-* 30-SEP-2005 (DSB):
-* Allow an integer to be read from a formatted floating point value.
-* 6-DEC-2005 (DSB):
-* Remove astMapGet0C stuff from description of astMapGet1C.
-* 14-FEB-2006 (DSB):
-* Override astGetObjSize.
-* 1-MAR-2006 (DSB):
-* Replace astSetPermMap within DEBUG blocks by astBeginPM/astEndPM.
-* 5-JUN-2006 (DSB):
-* Added support for single precision entries.
-* 30-NOV-2007 (DSB):
-* Added SizeGuess attribute.
-* 4-DEC-2007 (DSB):
-* Allow size of hash table to grow dynamically as more entries are
-* added to the KeyMap.
-* 5-DEC-2007 (DSB):
-* Ensure mapsize is always a power of 2.
-* 6-DEC-2007 (DSB):
-* - Define the minium table size rather than the default SizeGuess
-* value, and derive the default SizeGuess value from the minimum
-* table size.
-* - Use "&" rather than "%" to get the hash table index from the
-* full width hash value (& may be faster than %).
-* 7-MAR-2008 (DSB):
-* Added support for pointer ("P") entries.
-* 31-MAR-2009 (DSB):
-* Remove rounding errors from formatted double values.
-* 27-APR-2009 (DSB):
-* Added astMapGetElem<X>.
-* 1-SEP-2009 (DSB):
-* Added KeyError attribute.
-* 12-FEB-2010 (DSB):
-* When converting an entry value between double and string, treat
-* "<bad>" as the formatted version of AST__BAD.
-* 3-MAR-2010 (DSB):
-* Added astMapPutElem<X>.
-* 27-APR-2010 (DSB):
-* Added MapLocked attribute.
-* 4-MAY-2010 (DSB):
-* - Propagate MapLocked and KeyError attributes to any encapsulated
-* KeyMaps.
-* - Added astMapCopy method.
-* - Added astMapPutU method and AST__UNDEFTYPE data type.
-* 11-AUG-2010 (DSB):
-* Added SortBy attribute.
-* 12-AUG-2010 (DSB):
-* Speed up access to large KeyMaps.
-* 13-AUG-2010 (DSB):
-* - No need to sort all entries when doubling the table size since
-* changing the table size does not change the linked list of sorted
-* entries.
-* - Initialise the sortby attribute to the cleared value, rather
-* than the default value.
-* 2-OCT-2010 (DSB):
-* Added support for short int valued entries.
-* 24-NOV-2010 (DSB):
-* Fix memory leak in astMapPutElemC and astMapPutElemA.
-* 26-NOV-2010 (DSB):
-* Added support for unsigned byte valued entries.
-* 3-DEC-2010 (DSB):
-* Added KeyCase attribute.
-* 14-JAN-2011 (DSB):
-* Fix bug that prevented zero length strings being stored in a
-* keymap.
-* 17-SEP-2012 (DSB):
-* Fix bug that prevented UNDEF entries from being read back in
-* from a dump of a KeyMap.
-* 18-MAR-2013 (DSB):
-* Added astMapDefined.
-* 18-JUL-2013 (DSB):
-* Added SortBy options "KeyAgeUp" and "KeyAgeDown".
-* 9-SEP-2016 (DSB):
-* Guard against memory corruption that could occur after making
-* 50 (AST__KEYMAP_CONVERTVALUE_MAX_STRINGS) calls to put a string
-* into a KeyMap using astMapPutElemC.
-*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 KeyMap
-
-/* Minimum size for the hash table. */
-#define MIN_TABLE_SIZE 16
-
-/* The maximum number of entries per element of the hash table. If this
- value is exceeded the hash table will be doubled in size. */
-#define MAX_ENTRIES_PER_TABLE_ENTRY 10
-
-/* String used to represent the formatetd version of AST__BAD. */
-#define BAD_STRING "<bad>"
-
-/* Integer values to represent the different values of the SortBy attribute. */
-#define SORTBY_NONE 0
-#define SORTBY_AGEUP 1
-#define SORTBY_AGEDOWN 2
-#define SORTBY_KEYUP 3
-#define SORTBY_KEYDOWN 4
-#define SORTBY_KEYAGEUP 5
-#define SORTBY_KEYAGEDOWN 6
-
-
-/* Include files. */
-/* ============== */
-/* Interface definitions. */
-/* ---------------------- */
-
-#include "globals.h" /* Thread-safe global data access */
-#include "error.h" /* Error reporting facilities */
-#include "memory.h" /* Memory management facilities */
-#include "object.h" /* Base Object class */
-#include "pointset.h" /* For AST__BAD */
-#include "channel.h" /* I/O channels */
-#include "keymap.h" /* Interface definition for this class */
-#include "globals.h" /* Thread-safe global data access */
-
-/* Error code definitions. */
-/* ----------------------- */
-#include "ast_err.h" /* AST error codes */
-
-/* C header files. */
-/* --------------- */
-#include <limits.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-/* Type Definitions */
-/* ================ */
-
-/* This structure is a AstMapEntry holding a scalar int */
-typedef struct Entry0I {
- struct AstMapEntry entry; /* The parent Entry information */
- int value; /* The integer value */
-} Entry0I;
-
-/* This structure is a AstMapEntry holding a scalar double */
-typedef struct Entry0D {
- struct AstMapEntry entry; /* The parent Entry information */
- double value; /* The floating point value */
-} Entry0D;
-
-/* This structure is a AstMapEntry holding a scalar short int */
-typedef struct Entry0S {
- struct AstMapEntry entry; /* The parent Entry information */
- short int value; /* The short int value */
-} Entry0S;
-
-/* This structure is a AstMapEntry holding a scalar unsigned byte
- (unsigned char) */
-typedef struct Entry0B {
- struct AstMapEntry entry; /* The parent Entry information */
- unsigned char value; /* The byte value */
-} Entry0B;
-
-/* This structure is a AstMapEntry holding a scalar float */
-typedef struct Entry0F {
- struct AstMapEntry entry; /* The parent Entry information */
- float value; /* The floating point value */
-} Entry0F;
-
-/* This structure is a AstMapEntry holding a scalar string */
-typedef struct Entry0C {
- struct AstMapEntry entry; /* The parent Entry information */
- const char *value; /* The string pointer */
-} Entry0C;
-
-/* This structure is a AstMapEntry holding a scalar AST Object */
-typedef struct Entry0A {
- struct AstMapEntry entry; /* The parent Entry information */
- AstObject *value; /* The Object pointer */
- struct AstMapEntry *next; /* Pointer to next AST Object entry */
- struct AstMapEntry *prev; /* Pointer to previous AST Object entry */
-} Entry0A;
-
-/* This structure is a AstMapEntry holding a scalar void pointer */
-typedef struct Entry0P {
- struct AstMapEntry entry; /* The parent Entry information */
- void *value; /* The pointer */
-} Entry0P;
-
-/* This structure is a AstMapEntry holding a 1D array of ints */
-typedef struct Entry1I {
- struct AstMapEntry entry; /* The parent Entry information */
- int *value; /* The integer values */
-} Entry1I;
-
-/* This structure is a AstMapEntry holding a 1D array of doubles */
-typedef struct Entry1D {
- struct AstMapEntry entry; /* The parent Entry information */
- double *value; /* The floating point values */
-} Entry1D;
-
-/* This structure is a AstMapEntry holding a 1D array of short ints */
-typedef struct Entry1S {
- struct AstMapEntry entry; /* The parent Entry information */
- short int *value; /* The short int values */
-} Entry1S;
-
-/* This structure is a AstMapEntry holding a 1D array of unsigned bytes */
-typedef struct Entry1B {
- struct AstMapEntry entry; /* The parent Entry information */
- unsigned char *value; /* The byte values */
-} Entry1B;
-
-/* This structure is a AstMapEntry holding a 1D array of floats */
-typedef struct Entry1F {
- struct AstMapEntry entry; /* The parent Entry information */
- float *value; /* The floating point values */
-} Entry1F;
-
-/* This structure is a AstMapEntry holding a 1D array of strings */
-typedef struct Entry1C {
- struct AstMapEntry entry; /* The parent Entry information */
- const char **value; /* The string pointers */
-} Entry1C;
-
-/* This structure is a AstMapEntry holding a 1D array of AST Objects */
-typedef struct Entry1A {
- struct AstMapEntry entry; /* The parent Entry information */
- AstObject **value; /* The Object pointers */
- struct AstMapEntry *next; /* Pointer to next AST Object entry */
- struct AstMapEntry *prev; /* Pointer to previous AST Object entry */
-} Entry1A;
-
-/* This structure is a AstMapEntry holding a 1D array of void pointers. */
-typedef struct Entry1P {
- struct AstMapEntry entry; /* The parent Entry information */
- void **value; /* The pointers */
-} Entry1P;
-
-
-/* Module Variables. */
-/* ================= */
-
-/* Address of this static variable is used as a unique identifier for
- member of this class. */
-static int class_check;
-
-/* Pointers to parent class methods which are extended by this class. */
-static int (* parent_getobjsize)( AstObject *, int * );
-static const char *(* parent_getattrib)( AstObject *, const char *, int * );
-static int (* parent_testattrib)( AstObject *, const char *, int * );
-static void (* parent_clearattrib)( AstObject *, const char *, int * );
-static void (* parent_setattrib)( AstObject *, const char *, int * );
-
-#if defined(THREAD_SAFE)
-static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * );
-#endif
-
-/* 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->GetAttrib_Buff[ 0 ] = 0; \
- globals->ConvertValue_Init = 0; \
- globals->ConvertValue_Istr = 0; \
- globals->ConvertValue_Buff[ 0 ] = 0; \
- globals->MapKey_Init = 0; \
- globals->MapKey_Istr = 0;
-
-/* Create the function that initialises global data for this module. */
-astMAKE_INITGLOBALS(KeyMap)
-
-/* Define macros for accessing each item of thread specific global data. */
-#define class_init astGLOBAL(KeyMap,Class_Init)
-#define class_vtab astGLOBAL(KeyMap,Class_Vtab)
-#define getattrib_buff astGLOBAL(KeyMap,GetAttrib_Buff)
-#define convertvalue_strings astGLOBAL(KeyMap,ConvertValue_Strings)
-#define convertvalue_istr astGLOBAL(KeyMap,ConvertValue_Istr)
-#define convertvalue_init astGLOBAL(KeyMap,ConvertValue_Init)
-#define convertvalue_buff astGLOBAL(KeyMap,ConvertValue_Buff)
-#define mapkey_strings astGLOBAL(KeyMap,MapKey_Strings)
-#define mapkey_istr astGLOBAL(KeyMap,MapKey_Istr)
-#define mapkey_init astGLOBAL(KeyMap,MapKey_Init)
-
-
-
-/* If thread safety is not needed, declare and initialise globals at static
- variables. */
-#else
-
-/* Buffer returned by GetAttrib. */ \
-static char getattrib_buff[ AST__KEYMAP_GETATTRIB_BUFF_LEN + 1 ];
-
-/* Strings returned by ConvertValue */ \
-static char *convertvalue_strings[ AST__KEYMAP_CONVERTVALUE_MAX_STRINGS ];
-
-/* Offset of next string in "ConvertValue_Strings" */ \
-static int convertvalue_istr;
-
-/* "ConvertValue_Strings" array initialised? */ \
-static int convertvalue_init;
-
-/* ConvertValue string buffer */ \
-static char convertvalue_buff[ AST__KEYMAP_CONVERTVALUE_BUFF_LEN + 1 ];
-
-/* Strings returned by MapKey */ \
-static char *mapkey_strings[ AST__KEYMAP_MAPKEY_MAX_STRINGS ];
-
-/* Offset of next string in "MapKey_Strings" */ \
-static int mapkey_istr;
-
-/* "MapKey_Strings" array initialised? */ \
-static int mapkey_init;
-
-
-/* Define the class virtual function table and its initialisation flag
- as static variables. */
-static AstKeyMapVtab class_vtab; /* Virtual function table */
-static int class_init = 0; /* Virtual function table initialised? */
-
-#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. */
-AstKeyMap *astKeyMapId_( const char *, ... );
-
-/* Prototypes for Private Member Functions. */
-/* ======================================== */
-static AstMapEntry *AddTableEntry( AstKeyMap *, int, AstMapEntry *, int, int * );
-static AstMapEntry *CopyMapEntry( AstMapEntry *, int * );
-static AstMapEntry *FreeMapEntry( AstMapEntry *, int * );
-static AstMapEntry *RemoveTableEntry( AstKeyMap *, int, const char *, int * );
-static AstMapEntry *SearchTableEntry( AstKeyMap *, int, const char *, int * );
-static const char *ConvertKey( AstKeyMap *, const char *, char *, int, const char *, int * );
-static const char *GetKey( AstKeyMap *, int index, int * );
-static const char *MapIterate( AstKeyMap *, int, int * );
-static const char *MapKey( AstKeyMap *, int index, int * );
-static const char *SortByString( int, const char *, int * );
-static int CompareEntries( const void *, const void * );
-static int ConvertValue( void *, int, void *, int, int * );
-static int GetObjSize( AstObject *, int * );
-static int HashFun( const char *, int, unsigned long *, int * );
-static int KeyCmp( const char *, const char * );
-static int MapDefined( AstKeyMap *, const char *, int * );
-static int MapGet0A( AstKeyMap *, const char *, AstObject **, int * );
-static int MapGet0C( AstKeyMap *, const char *, const char **, int * );
-static int MapGet0D( AstKeyMap *, const char *, double *, int * );
-static int MapGet0S( AstKeyMap *, const char *, short int *, int * );
-static int MapGet0B( AstKeyMap *, const char *, unsigned char *, int * );
-static int MapGet0F( AstKeyMap *, const char *, float *, int * );
-static int MapGet0I( AstKeyMap *, const char *, int *, int * );
-static int MapGet0P( AstKeyMap *, const char *, void **, int * );
-static int MapGet1A( AstKeyMap *, const char *, int, int *, AstObject **, int * );
-static int MapGet1C( AstKeyMap *, const char *, int, int, int *, char *, int * );
-static int MapGet1D( AstKeyMap *, const char *, int, int *, double *, int * );
-static int MapGet1B( AstKeyMap *, const char *, int, int *, unsigned char *, int * );
-static int MapGet1S( AstKeyMap *, const char *, int, int *, short int *, int * );
-static int MapGet1F( AstKeyMap *, const char *, int, int *, float *, int * );
-static int MapGet1I( AstKeyMap *, const char *, int, int *, int *, int * );
-static int MapGet1P( AstKeyMap *, const char *, int, int *, void **, int * );
-static int MapGetElemA( AstKeyMap *, const char *, int, AstObject **, int * );
-static int MapGetElemC( AstKeyMap *, const char *, int, int, char *, int * );
-static int MapGetElemD( AstKeyMap *, const char *, int, double *, int * );
-static int MapGetElemB( AstKeyMap *, const char *, int, unsigned char *, int * );
-static int MapGetElemS( AstKeyMap *, const char *, int, short int *, int * );
-static int MapGetElemF( AstKeyMap *, const char *, int, float *, int * );
-static int MapGetElemI( AstKeyMap *, const char *, int, int *, int * );
-static int MapGetElemP( AstKeyMap *, const char *, int, void **, int * );
-static int MapHasKey( AstKeyMap *, const char *, int * );
-static int MapLenC( AstKeyMap *, const char *, int * );
-static int MapLength( AstKeyMap *, const char *, int * );
-static int MapSize( AstKeyMap *, int * );
-static int MapType( AstKeyMap *, const char *, int * );
-static int SortByInt( const char *, const char *, int * );
-static size_t SizeOfEntry( AstMapEntry *, int * );
-static void AddToObjectList( AstKeyMap *, AstMapEntry *, int * );
-static void AddToSortedList( AstKeyMap *, AstMapEntry *, int * );
-static void CheckCircle( AstKeyMap *, AstObject *, const char *, int * );
-static void Copy( const AstObject *, AstObject *, int * );
-static void CopyTableEntry( AstKeyMap *, AstKeyMap *, int, int * );
-static void Delete( AstObject *, int * );
-static void DoubleTableSize( AstKeyMap *, int * );
-static void Dump( AstObject *, AstChannel *, int * );
-static void DumpEntry( AstMapEntry *, AstChannel *, int, int * );
-static void FreeTableEntry( AstKeyMap *, int itab, int * );
-static void InitMapEntry( AstMapEntry *, int, int, int * );
-static void MapCopy( AstKeyMap *, AstKeyMap *, int * );
-static void MapPut0A( AstKeyMap *, const char *, AstObject *, const char *, int * );
-static void MapPut0C( AstKeyMap *, const char *, const char *, const char *, int * );
-static void MapPut0D( AstKeyMap *, const char *, double, const char *, int * );
-static void MapPut0B( AstKeyMap *, const char *, unsigned char, const char *, int * );
-static void MapPut0S( AstKeyMap *, const char *, short int, const char *, int * );
-static void MapPut0F( AstKeyMap *, const char *, float, const char *, int * );
-static void MapPut0I( AstKeyMap *, const char *, int, const char *, int * );
-static void MapPut0P( AstKeyMap *, const char *, void *, const char *, int * );
-static void MapPut1A( AstKeyMap *, const char *, int, AstObject *const [], const char *, int * );
-static void MapPut1C( AstKeyMap *, const char *, int, const char *const [], const char *, int * );
-static void MapPut1D( AstKeyMap *, const char *, int, const double *, const char *, int * );
-static void MapPut1B( AstKeyMap *, const char *, int, const unsigned char *, const char *, int * );
-static void MapPut1S( AstKeyMap *, const char *, int, const short int *, const char *, int * );
-static void MapPut1F( AstKeyMap *, const char *, int, const float *, const char *, int * );
-static void MapPut1I( AstKeyMap *, const char *, int, const int *, const char *, int * );
-static void MapPut1P( AstKeyMap *, const char *, int, void *const [], const char *, int * );
-static void MapPutElemA( AstKeyMap *, const char *, int, AstObject *, int * );
-static void MapPutElemC( AstKeyMap *, const char *, int, const char *, int * );
-static void MapPutElemD( AstKeyMap *, const char *, int, double, int * );
-static void MapPutElemB( AstKeyMap *, const char *, int, unsigned char, int * );
-static void MapPutElemS( AstKeyMap *, const char *, int, short int, int * );
-static void MapPutElemF( AstKeyMap *, const char *, int, float, int * );
-static void MapPutElemI( AstKeyMap *, const char *, int, int, int * );
-static void MapPutElemP( AstKeyMap *, const char *, int, void *, int * );
-static void MapPutU( AstKeyMap *, const char *, const char *, int * );
-static void MapRemove( AstKeyMap *, const char *, int * );
-static void MapRename( AstKeyMap *, const char *, const char *, int * );
-static void NewTable( AstKeyMap *, int, int * );
-static void RemoveFromSortedList( AstKeyMap *, AstMapEntry *, int * );
-static void RemoveFromObjectList( AstKeyMap *, AstMapEntry *, int * );
-static void SortEntries( AstKeyMap *, int * );
-
-static const char *GetAttrib( AstObject *, const char *, int * );
-static int TestAttrib( AstObject *, const char *, int * );
-static void ClearAttrib( AstObject *, const char *, int * );
-static void SetAttrib( AstObject *, const char *, int * );
-
-static int GetSizeGuess( AstKeyMap *, int * );
-static int TestSizeGuess( AstKeyMap *, int * );
-static void ClearSizeGuess( AstKeyMap *, int * );
-static void SetSizeGuess( AstKeyMap *, int, int * );
-
-static int GetSortBy( AstKeyMap *, int * );
-static int TestSortBy( AstKeyMap *, int * );
-static void ClearSortBy( AstKeyMap *, int * );
-static void SetSortBy( AstKeyMap *, int, int * );
-
-static int GetKeyError( AstKeyMap *, int * );
-static int TestKeyError( AstKeyMap *, int * );
-static void ClearKeyError( AstKeyMap *, int * );
-static void SetKeyError( AstKeyMap *, int, int * );
-
-static int GetKeyCase( AstKeyMap *, int * );
-static int TestKeyCase( AstKeyMap *, int * );
-static void ClearKeyCase( AstKeyMap *, int * );
-static void SetKeyCase( AstKeyMap *, int, int * );
-
-static int GetMapLocked( AstKeyMap *, int * );
-static int TestMapLocked( AstKeyMap *, int * );
-static void ClearMapLocked( AstKeyMap *, int * );
-static void SetMapLocked( AstKeyMap *, int, int * );
-
-#if defined(THREAD_SAFE)
-static int ManageLock( AstObject *, int, int, AstObject **, int * );
-#endif
-
-/* Member functions. */
-/* ================= */
-static AstMapEntry *AddTableEntry( AstKeyMap *this, int itab,
- AstMapEntry *entry, int keymember,
- int *status ){
-/*
-* Name:
-* AddTableEntry
-
-* Purpose:
-* Add an new entry to a linked-list of KeyMap entries.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* AstMapEntry *AddTableEntry( AstKeyMap *this, int itab,
-* AstMapEntry *entry, int keymember,
-* int *status ){
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function adds the supplied MapEntry to the head of the linked
-* list of MapEntries stored at the specified entry of the hash table.
-* If this results in the linked list having too many entries, then a
-* new larger hash table is allocated and the entries in the existing
-* table are moved into the new table.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-* itab
-* Index of the hash table element to be searched.
-* entry
-* Pointer to the MapEntry to be added.
-* keymember
-* A unique integer identifier for the key that increases
-* monotonically with age of the key. If this is negative,
-* the next available identifier will be used automatically.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A NULL pointer.
-
-*/
-
-/* Check the global error status. */
- if ( !astOK ) return NULL;
-
-/* Put a pointer to the MapEntry which is currently at the head of the
- linked list in the "next" component of the supplied MapEntry. */
- entry->next = this->table[ itab ];
-
-/* Store the supplied MapEntry pointer in the requested element of the
- hash table. */
- this->table[ itab ] = entry;
-
-/* Increment the length of linked list. */
- this->nentry[ itab ]++;
-
-/* Each new entry added to the KeyMap has a unique member index that is
- never re-used. */
- entry->member = (this->member_count)++;
-
-/* Each key added to the KeyMap also has a separate unique member index,
- but this index is re-used each time the same key is added into the
- KeyMap. So changing the value associated with a key does not cause the
- keymember value to change. */
- if( keymember >= 0 ) {
- entry->keymember = keymember;
- } else {
- entry->keymember = (this->member_count)++;
- }
-
-/* Insert the supplied MapEntry into a list sorted by key. */
- AddToSortedList( this, entry, status );
-
-/* If the entry is of type AST__OBJECTTYPE, add it to the head of the
- list of AST__OBJECTTYPE entries in the KeyMap. */
- AddToObjectList( this, entry, status );
-
-/* If the population of this table entry is now too large, double the size
- of the table, moving the table entries to appropriate places in the
- new larger table. */
- if( this->nentry[ itab ] > MAX_ENTRIES_PER_TABLE_ENTRY ) {
- DoubleTableSize( this, status );
- }
-
-/* Return a NULL pointer. */
- return NULL;
-}
-
-static void AddToObjectList( AstKeyMap *this, AstMapEntry *entry, int *status ){
-/*
-* Name:
-* AddToObjectList
-
-* Purpose:
-* Add AST__OBJECTTYPE entries into a linked-list of such entries.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* void AddToObjectList( AstKeyMap *this, AstMapEntry *entry, int *status )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* If the supplied MapEntry holds one or more pointers to AST Objects,
-* then the entry is added to a linked list of such entries.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-* entry
-* Pointer to the MapEntry to be added.
-* status
-* Pointer to the inherited status variable.
-
-*/
-
-/* Local Variables: */
- Entry0A *scalar; /* Pointer to a scalar AST__OBJECTTYPE entry */
- Entry1A *vector; /* Pointer to a vector AST__OBJECTTYPE entry */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Do nothing if the entry does not hold AST Object pointers. */
- if( entry->type == AST__OBJECTTYPE ) {
-
-/* If the list is not currently empty, add the new entry into the list. */
- if( this->firstA ) {
-
-/* Store a pointer to the new entry as the previous link in the current
- first entry in the list. */
- if( this->firstA->nel == 0 ) {
- scalar = (Entry0A *) this->firstA;
- scalar->prev = entry;
- } else {
- vector = (Entry1A *) this->firstA;
- vector->prev = entry;
- }
-
-/* Store a pointer to the current first entry as the next link in the new
- entry, and nullify the previus link. */
- if( entry->nel == 0 ) {
- scalar = (Entry0A *) entry;
- scalar->next = this->firstA;
- scalar->prev = NULL;
- } else {
- vector = (Entry1A *) entry;
- vector->next = this->firstA;
- vector->prev = NULL;
- }
-
-/* If the list is currently empty, nullify both links in the entry. */
- } else {
- if( entry->nel == 0 ) {
- scalar = (Entry0A *) entry;
- scalar->next = NULL;
- scalar->prev = NULL;
- } else {
- vector = (Entry1A *) entry;
- vector->next = NULL;
- vector->prev = NULL;
- }
-
- }
-
-/* Store the new entry as the first entry. */
- this->firstA = entry;
- }
-}
-
-static void AddToSortedList( AstKeyMap *this, AstMapEntry *entry, int *status ){
-/*
-* Name:
-* AddToSortedList
-
-* Purpose:
-* Add an entry into the linked-list of sorted KeyMap entries.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* void AddToSortedList( AstKeyMap *this, AstMapEntry *entry, int *status )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function adds the supplied MapEntry into the linked list of
-* sorted MapEntries at a position that maintains the sorted order.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-* entry
-* Pointer to the MapEntry to be added.
-* status
-* Pointer to the inherited status variable.
-
-*/
-
-/* Local Variables: */
- AstMapEntry *hi; /* MapEntry at high end of current range */
- AstMapEntry *lo; /* MapEntry at low end of current range */
- AstMapEntry *mid; /* MapEntry at middle of current range */
- int cmp; /* Result of comparing two entries */
- int istep; /* Step counter */
- int nstep; /* Number of entries in current range */
- int sortby; /* How to sort the keys */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Get the SortBy value. */
- sortby = astGetSortBy( this );
-
-/* Do nothing if no sorting is required. */
- if( sortby != SORTBY_NONE ) {
-
-/* Get pointers to the entries at the start and end of the sorted list. */
- lo = this->first;
- hi = lo ? lo->sprev : NULL;
-
-/* Store sortby value in the mapentry structures. */
- if( lo ) lo->sortby = sortby;
- if( hi ) hi->sortby = sortby;
- entry->sortby = sortby;
-
-/* If the sorted list is empty, just store the supplied entry at the
- head, and set the links to point back to itself. */
- if( !lo ) {
- this->first = entry;
- entry->sprev = entry;
- entry->snext = entry;
-
-/* If the new entry comes before the first entry or is equal to the first
- entry, record it as the new first entry, and insert it into the linked
- list before the original first entry. */
- } else if( CompareEntries( &entry, &lo ) <= 0 ) {
- this->first = entry;
- entry->snext = lo;
- entry->sprev = hi;
- lo->sprev = entry;
- hi->snext = entry;
-
-/* If the new entry comes after the last entry or is equal to the last
- entry, insert it into the linked list after the last entry. */
- } else if( CompareEntries( &entry, &hi ) >= 0 ) {
- entry->snext = lo;
- entry->sprev = hi;
- lo->sprev = entry;
- hi->snext = entry;
-
-/* If the list only contains two values, insert the new entry into the linked
- list between the existing two entries. */
- } else if( lo->snext == hi ) {
- entry->snext = hi;
- entry->sprev = lo;
- lo->snext = entry;
- hi->sprev = entry;
-
-/* Otherwise we do a binary chop within the existing sorted list to find the
- correct position for the new entry. */
- } else {
-
-/* Get a pointer to the entry mid way between the hi and lo entries. The
- mid entry will be on the upper side of half way if there are an even
- number of entries. */
- nstep = this->nsorted/2;
- mid = lo;
- for( istep = 0; istep < nstep; istep++ ) mid = mid->snext;
-
-/* Loop until we have a pointer to the first entry which is equal to or
- higher than the new entry. */
- while( lo->snext != hi ) {
-
-/* The next step will be half the length of the previous step. Do not
- allow the step size to fall to zero. */
- nstep = ( nstep > 1 ) ? nstep/2 : 1;
-
-/* Compare the new entry with the current mid-way entry. */
- mid->sortby = sortby;
- cmp = CompareEntries( &entry, &mid );
-
-/* If the new entry comes before the mid entry, use the mid entry as the
- next hi entry, and go down the list by the new step size to find the
- new mid-way entry. */
- if( cmp < 0 ) {
- hi = mid;
- for( istep = 0; istep < nstep; istep++ ) mid = mid->sprev;
-
-/* If the new entry comes after the mid entry, use the mid entry as the
- next lo entry, and go up the list by the new step size to find the
- new mid-way entry. */
- } else if( cmp > 0 ) {
- lo = mid;
- for( istep = 0; istep < nstep; istep++ ) mid = mid->snext;
-
-/* If the new entry is equal to the mid entry, use the mid entry as hi
- and set lo to the previous entry. This causes the loop to quit. */
- } else {
- hi = mid;
- lo = mid->sprev;
- }
- }
-
-/* Insert the new entry into the list between lo and hi. */
- entry->sprev = lo;
- entry->snext = hi;
- lo->snext = entry;
- hi->sprev = entry;
- }
-
-/* Increment the number of entries in the sorted list. */
- (this->nsorted)++;
- }
-}
-
-static void CheckCircle( AstKeyMap *this, AstObject *obj, const char *method, int *status ) {
-/*
-* Name:
-* CheckCircle
-
-* Purpose:
-* Check for circular dependencies between KeyMaps.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* void CheckCircle( AstKeyMap *this, AstObject *obj, const char *method, int *status )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function checks that the given AstObject is not a KeyMap which
-* contains "this". If it is, an error is reported.
-
-* Parameters:
-* this
-* The KeyMap pointer.
-* obj
-* Pointer to the AstObject to be inserted into the KeyMap, or NULL.
-* method
-* Name of method to include in error messages.
-* status
-* Pointer to the inherited status variable.
-
-*/
-
-/* Local Variables: */
- AstKeyMap *keymap; /* The KeyMap being added to "this" */
- AstObject **vec; /* Pointer to list of AstObject pointers */
- const char *key; /* The i'th key within second KeyMap */
- int i; /* Index of entry within second KeyMap */
- int j; /* Index within the vector of values */
- int len; /* No. of AST pointers stored in the entry */
- int nkey; /* No. of entries in the second KeyMap */
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Return if the AstObject is not a KeyMap. */
- if( obj && astIsAKeyMap( obj ) ) {
- keymap = (AstKeyMap *) obj;
-
-/* First check if the supplied Objects are the same. You cannot store a
- KeyMap as an entry within itself. */
- if( keymap == this ) {
- astError( AST__KYCIR, "%s(%s): Cannot add a %s into another "
- "%s because they are same %s.", status, method,
- astGetClass( this ), astGetClass( this ),
- astGetClass( this ), astGetClass( this ) );
-
-/* Otherwise, loop through all the entries in the KeyMap looking for AstObject
- entries. */
- } else {
- nkey = astMapSize( keymap );
- for( i = 0; i < nkey && astOK; i++ ) {
- key = astMapKey( keymap, i );
- if( astMapType( keymap, key ) == AST__OBJECTTYPE ) {
-
-/* Find the number of AstObject pointers stored in this entry, and
- allocate memory to store a copy of the every pointer. */
- len = astMapLength( keymap, key );
- vec = astMalloc( sizeof( AstObject *) * len );
- if( vec ) {
-
-/* Extract pointers to the AstObjects at this entry, and loop round them. */
- astMapGet1A( keymap, key, len, &len, vec );
- for( j = 0; j < len; j++ ) {
-
-/* If this entry is a KeyMap, we need to check if is the same as "this"
- or contains "this". */
- if( astIsAKeyMap( vec[ j ] ) ) {
-
-/* If it is the same as "this", report an error. */
- if( vec[ j ] == (AstObject *) this ) {
- astError( AST__KYCIR, "%s(%s): Cannot add a KeyMap "
- "into another KeyMap because the first "
- "KeyMap contains the second KeyMap.", status,
- method, astGetClass( this ) );
- break;
-
-/* Otherwise, see if it contains "this". */
- } else {
- CheckCircle( this, vec[ j ], method, status );
- }
- }
-
-/* Free resources. */
- vec[ j ] = astAnnul( vec[ j ] );
- }
- vec = astFree( vec );
- }
- }
- }
- }
- }
-}
-
-static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) {
-/*
-* Name:
-* ClearAttrib
-
-* Purpose:
-* Clear an attribute value for a KeyMap.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* void ClearAttrib( AstObject *this, const char *attrib, int *status )
-
-* Class Membership:
-* KeyMap member function (over-rides the astClearAttrib protected
-* method inherited from the Mapping class).
-
-* Description:
-* This function clears the value of a specified attribute for a
-* KeyMap, so that the default value will subsequently be used.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-* 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: */
- AstKeyMap *this; /* Pointer to the KeyMap structure */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the KeyMap structure. */
- this = (AstKeyMap *) this_object;
-
-/* Check the attribute name and clear the appropriate attribute. */
-
-/* SizeGuess. */
-/* ---------- */
- if ( !strcmp( attrib, "sizeguess" ) ) {
- astClearSizeGuess( this );
-
-/* KeyError. */
-/* --------- */
- } else if ( !strcmp( attrib, "keyerror" ) ) {
- astClearKeyError( this );
-
-/* KeyCase. */
-/* --------- */
- } else if ( !strcmp( attrib, "keycase" ) ) {
- astClearKeyCase( this );
-
-/* MapLocked. */
-/* --------- */
- } else if ( !strcmp( attrib, "maplocked" ) ) {
- astClearMapLocked( this );
-
-/* SortBy. */
-/* ------- */
- } else if ( !strcmp( attrib, "sortby" ) ) {
- astClearSortBy( 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 ClearKeyCase( AstKeyMap *this, int *status ) {
-/*
-*+
-* Name:
-* astClearKeyCase
-
-* Purpose:
-* Clear the value of the KeyCase attribute for a KeyMap.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "keymap.h"
-* void astSetKeyCase( AstKeyMap *this )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This function Clears the KeyCase attribute of a KeyMap. It reports
-* an error if the KeyMap contains any entries.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-
-*-
-*/
-
-/* Local Variables: */
- int defval; /* Default KeyCase value */
- int itab; /* Index into hash table */
- int oldval; /* Old KeyCase value */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Save the old value. */
- oldval = astGetKeyCase( this );
-
-/* Clear it. */
- this->keycase = -1;
-
-/* Get the default value. */
- defval = astGetKeyCase( this );
-
-/* If the old value and the default value are not the same, we must check
- that the KeyMap is empty. If not, restore the old value and report an
- error. */
- if( defval != oldval ) {
- for( itab = 0; itab < this->mapsize; itab++ ) {
- if( this->nentry[ itab ] > 0 ) {
- this->keycase = oldval;
- astError( AST__NOWRT, "astClearAttrib(KeyMap): Illegal attempt to "
- "clear the KeyCase attribute of a non-empty KeyMap.",
- status);
- break;
- }
- }
- }
-}
-
-static void ClearKeyError( AstKeyMap *this, int *status ) {
-/*
-*+
-* Name:
-* astClearKeyError
-
-* Purpose:
-* Clear the value of the KeyError attribute for a KeyMap.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "keymap.h"
-* void astClearKeyError( AstKeyMap *this )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This function clears the value of the KeyError attribute for a
-* KeyMap. It clears the attribute recursively in any KeyMaps
-* contained within the supplied KeyMap.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-
-*-
-*/
-
-/* Local Variables: */
- AstMapEntry *next; /* Pointer to next Entry to copy */
- AstObject **obj_list; /* List of pointers to AST Object entries */
- int i; /* Index into hash table */
- int iel; /* Index of current vector element */
- int nel; /* Number of elements in vector */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Clear the KeyError value in the supplied KeyMap. */
- this->keyerror = -INT_MAX;
-
-/* Loop round each entry in the hash table. */
- for( i = 0; i < this->mapsize; i++ ) {
-
-/* Get a pointer to the next KeyMap entry. */
- next = this->table[ i ];
-
-/* Loop round all entries in this element of the hash table. */
- while( next && astOK ) {
-
-/* If this entry has an Object data type, see if holds any KeyMaps. */
- if( next->type == AST__OBJECTTYPE ) {
-
-/* Get the number of objects to check, and a pointer to the first. */
- nel = next->nel;
- if( nel == 0 ) {
- obj_list = &( ((Entry0A *)next)->value );
- nel = 1;
- } else {
- obj_list = ((Entry1A *)next)->value;
- }
-
-/* Loop round checking all Objects. */
- for( iel = 0; iel < nel; iel++ ) {
-
-/* If this Object is a KeyMap, clear its KeyError attribute. */
- if( astIsAKeyMap( obj_list[ iel ] ) ) {
- astClearKeyError( (AstKeyMap *) obj_list[ iel ] );
- }
- }
- }
-
-/* Get a pointer to the next entry. */
- next = next->next;
- }
- }
-}
-
-static void ClearMapLocked( AstKeyMap *this, int *status ) {
-/*
-*+
-* Name:
-* astClearMapLocked
-
-* Purpose:
-* Clear the value of the MapLocked attribute for a KeyMap.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "keymap.h"
-* void astClearMapLocked( AstKeyMap *this )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This function clears the value of the MapLocked attribute for a
-* KeyMap. It clears the attribute recursively in any KeyMaps
-* contained within the supplied KeyMap.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-
-*-
-*/
-
-/* Local Variables: */
- AstMapEntry *next; /* Pointer to next Entry to copy */
- AstObject **obj_list; /* List of pointers to AST Object entries */
- int i; /* Index into hash table */
- int iel; /* Index of current vector element */
- int nel; /* Number of elements in vector */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Clear the MapLocked value in the supplied KeyMap. */
- this->maplocked = -INT_MAX;
-
-/* Loop round each entry in the hash table. */
- for( i = 0; i < this->mapsize; i++ ) {
-
-/* Get a pointer to the next KeyMap entry. */
- next = this->table[ i ];
-
-/* Loop round all entries in this element of the hash table. */
- while( next && astOK ) {
-
-/* If this entry has an Object data type, see if holds any KeyMaps. */
- if( next->type == AST__OBJECTTYPE ) {
-
-/* Get the number of objects to check, and a pointer to the first. */
- nel = next->nel;
- if( nel == 0 ) {
- obj_list = &( ((Entry0A *)next)->value );
- nel = 1;
- } else {
- obj_list = ((Entry1A *)next)->value;
- }
-
-/* Loop round checking all Objects. */
- for( iel = 0; iel < nel; iel++ ) {
-
-/* If this Object is a KeyMap, clear its MapLocked attribute. */
- if( astIsAKeyMap( obj_list[ iel ] ) ) {
- astClearMapLocked( (AstKeyMap *) obj_list[ iel ] );
- }
- }
- }
-
-/* Get a pointer to the next entry. */
- next = next->next;
- }
- }
-}
-
-static void ClearSizeGuess( AstKeyMap *this, int *status ) {
-/*
-*+
-* Name:
-* astClearSizeGuess
-
-* Purpose:
-* Clear the value of the SizeGuess attribute for a KeyMap.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "keymap.h"
-* void astClearSizeGuess( AstKeyMap *this )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This function clears the value of the SizeGuess attribute for a
-* KeyMap. It reports an error if the KeyMap contains any entries.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-
-*-
-*/
-
-/* Local Variables: */
- int empty; /* Is the KeyMap empty? */
- int itab; /* Index into hash table */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* See if the KeyMap is empty. */
- empty = 1;
- for( itab = 0; itab < this->mapsize; itab++ ) {
- if( this->nentry[ itab ] > 0 ) {
- empty = 0;
- break;
- }
- }
-
-/* If not report an error. */
- if( !empty ) {
- astError( AST__NOWRT, "astClearAttrib(KeyMap): Illegal attempt to "
- "clear the SizeGuess attribute of a non-empty KeyMap." , status);
-
-/* Otherwise, store the "cleared" value and change the size of the hash
- table. */
- } else {
- this->sizeguess = INT_MAX;
- NewTable( this, MIN_TABLE_SIZE, status );
- }
-}
-
-static void ClearSortBy( AstKeyMap *this, int *status ) {
-/*
-*+
-* Name:
-* astClearSortBy
-
-* Purpose:
-* Clear the value of the SortBy attribute for a KeyMap.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "keymap.h"
-* void astClearSortBy( AstKeyMap *this )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This function clears the value of the SortBy attribute for a
-* KeyMap.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-
-*-
-*/
-
-/* Local Variables: */
- int oldval; /* The old sortby value */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Get the original SortBy value. */
- oldval = astGetSortBy( this );
-
-/* Clear the SortBy value in the supplied KeyMap. */
- this->sortby = -INT_MAX;
-
-/* If the value has changed, re-sort the keys. */
- if( oldval != astGetSortBy( this ) ) SortEntries( this, status );
-}
-
-static int CompareEntries( const void *first_void, const void *second_void ) {
-/*
-* Name:
-* CompareEntries
-
-* Purpose:
-* Determine the sorting order of two mapEntries.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* int CompareEntries( const void *first, const void *second )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function returns a value indicating if the first MapEntry
-* is less than, equal to, or greater than the second MapEntry using
-* the indicated sorting method. It is designed for use with the
-* "qsort" function, and therefore must used "void *" pointers.
-
-* Parameters:
-* first
-* Pointer to the address of the first MapEntry.
-* second
-* Pointer to the address of the second MapEntry.
-
-* Returned Value:
-* -1 if "first" is less than "second". This implies that "first"
-* should come before "second" in the sorted list.
-*
-* 0 if "first" is equal to "second".
-*
-* +1 if "first" is greater than "second". This implies that "first"
-* should come after "second" in the sorted list.
-
-*/
-
-/* Local Variables: */
- AstMapEntry *first; /* Pointer to first MapEntry structure */
- AstMapEntry *second; /* Pointer to second MapEntry structure */
- int result; /* Returned value */
- int sortby; /* Sorting method */
-
-/* Initialise returned value */
- result = 0;
-
-/* Get pointers to the MapEntry structures, and get the sorting method. */
- first = *( (AstMapEntry **) first_void );
- second = *( (AstMapEntry **) second_void );
- sortby = first->sortby;
-
-/* First handle sorting by increasing age of the value */
- if( sortby == SORTBY_AGEUP ) {
- if( first->member < second->member ) {
- result = 1;
- } else if( first->member > second->member ) {
- result = -1;
- } else {
- result = 0;
- }
-
-/* Next handle sorting by decreasing age of the value */
- } else if( sortby == SORTBY_AGEDOWN ) {
- if( first->member < second->member ) {
- result = -1;
- } else if( first->member > second->member ) {
- result = 1;
- } else {
- result = 0;
- }
-
-/* Next handle sorting by increasing age of the key */
- } else if( sortby == SORTBY_KEYAGEUP ) {
- if( first->keymember < second->keymember ) {
- result = 1;
- } else if( first->keymember > second->keymember ) {
- result = -1;
- } else {
- result = 0;
- }
-
-/* Next handle sorting by decreasing age of the key */
- } else if( sortby == SORTBY_KEYAGEDOWN ) {
- if( first->keymember < second->keymember ) {
- result = -1;
- } else if( first->keymember > second->keymember ) {
- result = 1;
- } else {
- result = 0;
- }
-
-/* Next handle sorting by increasing alphabetical position. */
- } else if( sortby == SORTBY_KEYUP ) {
- result = KeyCmp( first->key, second->key );
-
-/* Next handle sorting by decreasing alphabetical position. */
- } else if( sortby == SORTBY_KEYDOWN ) {
- result = KeyCmp( second->key, first->key );
-
- }
-
-/* Return the result. */
- return result;
-
-}
-
-static const char *ConvertKey( AstKeyMap *this, const char *skey, char *keybuf,
- int blen, const char *method, int *status ){
-/*
-* Name:
-* ConvertValue
-
-* Purpose:
-* Convert the supplied key to upper case if required.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* const char *ConvertKey( AstKeyMap *this, const char *skey, char *keybuf,
-* int blen, const char *method, int *status )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function converts the supplied key string to uppercase if the
-* KeyCase attribute it currently set to zero in the supplied KeyMap.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-* skey
-* Pointer to the supplied key string.
-* keybuf
-* Pointer to a buffer in which to place the converted string. This
-* will only be used if the supplied key string needs to be
-* converted.
-* blen
-* The length of the "keybuf" buffer. This should include room for
-* a terminating null character.
-* method
-* Pointer to a string holding the name of the method to include in
-* any error message.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* If the KeyMap's KeyCase attribute is currently set to a non-zero
-* value, the returned value will be a copy of "skey". Otherwise it
-* will be copy of "keybuf" (the buffer holding the upper case version
-* of the supplied string).
-
-* Notes:
-* - The valeu of "skey" will be returned if this function is invoked
-* with the global error status set, or if it should fail for any reason.
-*/
-
-/* Local Variables: */
- const char *result;
- int len;
-
-/* Initialise. */
- result = skey;
-
-/* Check the global error status and the supplied pointers. */
- if( !astOK ) return result;
-
-/* If the KeyCase attribute is non-zero, return "skey". Otherwise, convert
- the "skey" string to upper case and return "keybuf". Report an error if
- the key is too long. */
- if( !astGetKeyCase( this ) && astOK ) {
- len = astChrLen( skey );
- if( len >= blen ) {
- astError( AST__BIGKEY, "%s(%s): Supplied key '%s' is too long "
- "(keys must be no more than %d characters long).",
- status, method, astGetClass( this ), skey, blen - 1 );
- } else {
- astChrCase( skey, keybuf, 1, blen );
- result = keybuf;
- }
- }
-
-/* Return the result. */
- return result;
-}
-
-static int ConvertValue( void *raw, int raw_type, void *out, int out_type, int *status ) {
-/*
-* Name:
-* ConvertValue
-
-* Purpose:
-* Convert a value from one KeyMap data type to another.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* int ConvertValue( void *raw, int raw_type, void *out, int out_type, int *status )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function converts a supplied value from one KeyMap data type to
-* another, if possible.
-
-* Parameters:
-* raw
-* Pointer to input value.
-* raw_type
-* The data type of the input value.
-* out
-* Pointer to the location at which to store the output value. This
-* may be NULL, in which case the conversion is still performed if
-* possible, but the result of the conversion is thrown away. If the
-* output value is a pointer to a string, it should not be modified
-* by the caller in any way. Neither should it be freed by the caller.
-* out_type
-* The data type of the output value.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Non-zero if the conversion was performed succesfully, otherwise zero.
-* In the case of the output type being AST__STRINGTYPE, the returned
-* non-zero value will be the length of the formatted string (including
-* the terminating null character). This value will be returned correctly
-* even if "out" is NULL.
-
-* Notes:
-* - 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: */
- AstObject *aval; /* AstObject pointer value */
- astDECLARE_GLOBALS /* Declare the thread specific global data */
- const char *cval; /* Pointer to string value */
- const char *cvalue; /* Pointer to output string value */
- double dval; /* Double precision value */
- float fval; /* Single precision value */
- int i; /* Loop count */
- int ival; /* Integer value */
- int n1; /* Number of characters at reduced precision */
- int n2; /* Number of characters at full precision */
- int nc; /* Number of characters read from string */
- int nval; /* Number of values read from string */
- int result; /* Returned flag */
- short int sval; /* Short int value */
- unsigned char bval; /* Byte value */
-
-/* Initialise. */
- result = 0;
-
-/* Check the global error status and the supplied pointers. */
- if( !astOK || !raw ) return result;
-
-/* Get a pointer to the structure holding thread-specific global data. */
- astGET_GLOBALS(NULL);
-
-/* If the "convertvalue_strings" array has not been initialised, fill it with
- NULL pointers. */
- if( !convertvalue_init ) {
- convertvalue_init = 1;
- for( i = 0; i < AST__KEYMAP_CONVERTVALUE_MAX_STRINGS; i++ ) convertvalue_strings[ i ] = NULL;
- }
-
-/* Assume conversion is possible */
- result = 1;
- cvalue = NULL;
-
-/* Do nothing if both data types are AST__UNDEFTYPE. */
- if( raw_type == AST__UNDEFTYPE && out_type == AST__UNDEFTYPE ) {
-
-/* Indicate failure if one of the two types is AST__UNDEFTYPE and the
- other is not. */
- } else if( raw_type == AST__UNDEFTYPE || out_type == AST__UNDEFTYPE ) {
- result = 0;
-
-/* Otherwise, consider conversion from "int". */
- } else if( raw_type == AST__INTTYPE ) {
- ival = *( (int *) raw );
-
-/* Consider conversion to "int". */
- if( out_type == AST__INTTYPE ) {
- if( out ) *( (int *) out ) = ival;
-
-/* Consider conversion to "short int". */
- } else if( out_type == AST__SINTTYPE ) {
- if( out ) *( (short int *) out ) = (short int) ival;
-
-/* Consider conversion to "byte". */
- } else if( out_type == AST__BYTETYPE ) {
- if( out ) *( (unsigned char *) out ) = (unsigned char) ival;
-
-/* Consider conversion to "float". */
- } else if( out_type == AST__FLOATTYPE ) {
- if( out ) *( (float *) out ) = (float) ival;
-
-/* Consider conversion to "double". */
- } else if( out_type == AST__DOUBLETYPE ) {
- if( out ) *( (double *) out ) = (double) ival;
-
-/* Consider conversion to "const char *". */
- } else if( out_type == AST__STRINGTYPE ) {
- (void) sprintf( convertvalue_buff, "%d", ival );
- cvalue = convertvalue_buff;
-
-/* Consider conversion to "AstObject *". */
- } else if( out_type == AST__OBJECTTYPE ) {
- result = 0;
-
-/* Consider conversion to "void *". */
- } else if( out_type == AST__POINTERTYPE ) {
- result = 0;
-
-/* Report an error if the data type is unknown. */
- } else {
- result = 0;
- astError( AST__INTER, "ConvertValue(KeyMap): Illegal map entry data "
- "type %d encountered (internal AST programming error).", status,
- out_type );
- }
-
-/* Otherwise, consider conversion from "short int". */
- } else if( raw_type == AST__SINTTYPE ) {
- sval = *( (short int *) raw );
-
-/* Consider conversion to "int". */
- if( out_type == AST__INTTYPE ) {
- if( out ) *( (int *) out ) = sval;
-
-/* Consider conversion to "short int". */
- } else if( out_type == AST__SINTTYPE ) {
- if( out ) *( (short int *) out ) = sval;
-
-/* Consider conversion to "byte". */
- } else if( out_type == AST__BYTETYPE ) {
- if( out ) *( (unsigned char *) out ) = sval;
-
-/* Consider conversion to "float". */
- } else if( out_type == AST__FLOATTYPE ) {
- if( out ) *( (float *) out ) = (float) sval;
-
-/* Consider conversion to "double". */
- } else if( out_type == AST__DOUBLETYPE ) {
- if( out ) *( (double *) out ) = (double) sval;
-
-/* Consider conversion to "const char *". */
- } else if( out_type == AST__STRINGTYPE ) {
- (void) sprintf( convertvalue_buff, "%d", (int) sval );
- cvalue = convertvalue_buff;
-
-/* Consider conversion to "AstObject *". */
- } else if( out_type == AST__OBJECTTYPE ) {
- result = 0;
-
-/* Consider conversion to "void *". */
- } else if( out_type == AST__POINTERTYPE ) {
- result = 0;
-
-/* Report an error if the data type is unknown. */
- } else {
- result = 0;
- astError( AST__INTER, "ConvertValue(KeyMap): Illegal map entry data "
- "type %d encountered (internal AST programming error).", status,
- out_type );
- }
-
-/* Otherwise, consider conversion from "byte". */
- } else if( raw_type == AST__BYTETYPE ) {
- bval = *( (unsigned char *) raw );
-
-/* Consider conversion to "int". */
- if( out_type == AST__INTTYPE ) {
- if( out ) *( (int *) out ) = bval;
-
-/* Consider conversion to "short int". */
- } else if( out_type == AST__SINTTYPE ) {
- if( out ) *( (short int *) out ) = bval;
-
-/* Consider conversion to "byte". */
- } else if( out_type == AST__BYTETYPE ) {
- if( out ) *( (unsigned char *) out ) = bval;
-
-/* Consider conversion to "float". */
- } else if( out_type == AST__FLOATTYPE ) {
- if( out ) *( (float *) out ) = (float) bval;
-
-/* Consider conversion to "double". */
- } else if( out_type == AST__DOUBLETYPE ) {
- if( out ) *( (double *) out ) = (double) bval;
-
-/* Consider conversion to "const char *". */
- } else if( out_type == AST__STRINGTYPE ) {
- (void) sprintf( convertvalue_buff, "%d", (int) bval );
- cvalue = convertvalue_buff;
-
-/* Consider conversion to "AstObject *". */
- } else if( out_type == AST__OBJECTTYPE ) {
- result = 0;
-
-/* Consider conversion to "void *". */
- } else if( out_type == AST__POINTERTYPE ) {
- result = 0;
-
-/* Report an error if the data type is unknown. */
- } else {
- result = 0;
- astError( AST__INTER, "ConvertValue(KeyMap): Illegal map entry data "
- "type %d encountered (internal AST programming error).", status,
- out_type );
- }
-
-/* Consider conversion from "double". */
- } else if( raw_type == AST__DOUBLETYPE ) {
- dval = *( (double *) raw );
-
-/* Consider conversion to "int". */
- if( out_type == AST__INTTYPE ) {
- if( out ) *( (int *) out ) = (int)( dval + 0.5 );
-
-/* Consider conversion to "short int". */
- } else if( out_type == AST__SINTTYPE ) {
- if( out ) *( (short int *) out ) = (int)( dval + 0.5 );
-
-/* Consider conversion to "byte". */
- } else if( out_type == AST__BYTETYPE ) {
- if( out ) *( (unsigned char *) out ) = (int)( dval + 0.5 );
-
-/* Consider conversion to "double". */
- } else if( out_type == AST__DOUBLETYPE ) {
- if( out ) *( (double *) out ) = dval;
-
-/* Consider conversion to "float". */
- } else if( out_type == AST__FLOATTYPE ) {
- if( out ) *( (float *) out ) = (float) dval;
-
-/* Consider conversion to "const char *". If reducing the number of
- decimal places by two produces a saving of 10 or more characters,
- assume the least significant two characters are rounding error. */
- } else if( out_type == AST__STRINGTYPE ) {
- if( dval != AST__BAD ) {
- n1 = sprintf( convertvalue_buff, "%.*g", DBL_DIG - 2, dval );
- n2 = sprintf( convertvalue_buff, "%.*g", DBL_DIG, dval );
- if( n2 - n1 > 9 ) {
- (void) sprintf( convertvalue_buff, "%.*g", DBL_DIG - 2, dval );
- }
- cvalue = convertvalue_buff;
- } else {
- cvalue = BAD_STRING;
- }
-
-/* Consider conversion to "AstObject *". */
- } else if( out_type == AST__OBJECTTYPE ) {
- result = 0;
-
-/* Consider conversion to "void *". */
- } else if( out_type == AST__POINTERTYPE ) {
- result = 0;
-
-/* Report an error if the data type is unknown. */
- } else {
- result = 0;
- astError( AST__INTER, "ConvertValue(KeyMap): Illegal map entry data "
- "type %d encountered (internal AST programming error).", status,
- out_type );
- }
-
-/* Consider conversion from "float". */
- } else if( raw_type == AST__FLOATTYPE ) {
- fval = *( (float *) raw );
-
-/* Consider conversion to "int". */
- if( out_type == AST__INTTYPE ) {
- if( out ) *( (int *) out ) = (int)( fval + 0.5 );
-
-/* Consider conversion to "short int". */
- } else if( out_type == AST__SINTTYPE ) {
- if( out ) *( (short int *) out ) = (int)( fval + 0.5 );
-
-/* Consider conversion to "byte". */
- } else if( out_type == AST__BYTETYPE ) {
- if( out ) *( (unsigned char *) out ) = (int)( fval + 0.5 );
-
-/* Consider conversion to "double". */
- } else if( out_type == AST__DOUBLETYPE ) {
- if( out ) *( (double *) out ) = (double) fval;
-
-/* Consider conversion to "float". */
- } else if( out_type == AST__FLOATTYPE ) {
- if( out ) *( (float *) out ) = fval;
-
-/* Consider conversion to "const char *". */
- } else if( out_type == AST__STRINGTYPE ) {
- (void) sprintf( convertvalue_buff, "%.*g", FLT_DIG, fval );
- cvalue = convertvalue_buff;
-
-/* Consider conversion to "AstObject *". */
- } else if( out_type == AST__OBJECTTYPE ) {
- result = 0;
-
-/* Consider conversion to "void *". */
- } else if( out_type == AST__POINTERTYPE ) {
- result = 0;
-
-/* Report an error if the data type is unknown. */
- } else {
- result = 0;
- astError( AST__INTER, "ConvertValue(KeyMap): Illegal map entry data "
- "type %d encountered (internal AST programming error).", status,
- out_type );
- }
-
-/* Consider conversion from "const char *". */
- } else if( raw_type == AST__STRINGTYPE ) {
- cval = *( (const char **) raw );
-
-/* Consider conversion to "int". */
- if( out_type == AST__INTTYPE ) {
- nc = 0;
- nval = astSscanf( cval, " %d %n", &ival, &nc );
- if( ( nval == 1 ) && ( nc >= (int) strlen( cval ) ) ) {
- if( out ) *( (int *) out ) = ival;
- } else {
- nc = 0;
- nval = astSscanf( cval, " %lf %n", &dval, &nc );
- if( ( nval == 1 ) && ( nc >= (int) strlen( cval ) ) ) {
- if( out ) *( (int *) out ) = (int) ( dval + 0.5 );
- } else {
- result = 0;
- }
- }
-
-/* Consider conversion to "short int". */
- } else if( out_type == AST__SINTTYPE ) {
- nc = 0;
- nval = astSscanf( cval, " %d %n", &ival, &nc );
- if( ( nval == 1 ) && ( nc >= (int) strlen( cval ) ) ) {
- if( out ) *( (short int *) out ) = ival;
- } else {
- nc = 0;
- nval = astSscanf( cval, " %lf %n", &dval, &nc );
- if( ( nval == 1 ) && ( nc >= (int) strlen( cval ) ) ) {
- if( out ) *( (short int *) out ) = (int) ( dval + 0.5 );
- } else {
- result = 0;
- }
- }
-
-/* Consider conversion to "byte". */
- } else if( out_type == AST__BYTETYPE ) {
- nc = 0;
- nval = astSscanf( cval, " %d %n", &ival, &nc );
- if( ( nval == 1 ) && ( nc >= (int) strlen( cval ) ) ) {
- if( out ) *( (unsigned char *) out ) = ival;
- } else {
- nc = 0;
- nval = astSscanf( cval, " %lf %n", &dval, &nc );
- if( ( nval == 1 ) && ( nc >= (int) strlen( cval ) ) ) {
- if( out ) *( (unsigned char *) out ) = (int) ( dval + 0.5 );
- } else {
- result = 0;
- }
- }
-
-/* Consider conversion to "double". */
- } else if( out_type == AST__DOUBLETYPE ) {
- nc = 0;
- nval = astSscanf( cval, " " BAD_STRING " %n", &nc );
- if( ( astSscanf( cval, " " BAD_STRING " %n", &nc ) == 0 ) &&
- ( nc >= (int) strlen( cval ) ) ) {
- if( out ) *( (double *) out ) = AST__BAD;
-
- } else if( ( astSscanf( cval, " %lf %n", &dval, &nc ) == 1 ) &&
- ( nc >= (int) strlen( cval ) ) ) {
- if( out ) *( (double *) out ) = dval;
-
- } else {
- result = 0;
- }
-
-/* Consider conversion to "float". */
- } else if( out_type == AST__FLOATTYPE ) {
- nc = 0;
- nval = astSscanf( cval, " %f %n", &fval, &nc );
- if( ( nval == 1 ) && ( nc >= (int) strlen( cval ) ) ) {
- if( out ) *( (float *) out ) = fval;
- } else {
- result = 0;
- }
-
-/* Consider conversion to "const char *". */
- } else if( out_type == AST__STRINGTYPE ) {
- cvalue = cval;
-
-/* Consider conversion to "AstObject *". */
- } else if( out_type == AST__OBJECTTYPE ) {
- result = 0;
-
-/* Consider conversion to "void *". */
- } else if( out_type == AST__POINTERTYPE ) {
- result = 0;
-
-/* Report an error if the data type is unknown. */
- } else {
- result = 0;
- astError( AST__INTER, "ConvertValue(KeyMap): Illegal map entry data "
- "type %d encountered (internal AST programming error).", status,
- out_type );
- }
-
-/* Consider conversion from "AstObject *". */
- } else if( raw_type == AST__OBJECTTYPE ) {
-
-/* Consider conversion to "int". */
- if( out_type == AST__INTTYPE ) {
- result = 0;
-
-/* Consider conversion to "short int". */
- } else if( out_type == AST__SINTTYPE ) {
- result = 0;
-
-/* Consider conversion to "byte". */
- } else if( out_type == AST__BYTETYPE ) {
- result = 0;
-
-/* Consider conversion to "double". */
- } else if( out_type == AST__DOUBLETYPE ) {
- result = 0;
-
-/* Consider conversion to "float". */
- } else if( out_type == AST__FLOATTYPE ) {
- result = 0;
-
-/* Consider conversion to "const char *". */
- } else if( out_type == AST__STRINGTYPE ) {
- result = 0;
-
-/* Consider conversion to "AstObject *". */
- } else if( out_type == AST__OBJECTTYPE ) {
- aval = *( (AstObject **) raw );
- if( out ) *( (AstObject **) out ) = aval ? astClone( aval ) : NULL;
-
-/* Consider conversion to "void *". */
- } else if( out_type == AST__POINTERTYPE ) {
- result = 0;
-
-/* Report an error if the data type is unknown. */
- } else {
- result = 0;
- astError( AST__INTER, "ConvertValue(KeyMap): Illegal map entry data "
- "type %d encountered (internal AST programming error).", status,
- out_type );
- }
-
-/* Consider conversion from "void *". */
- } else if( raw_type == AST__POINTERTYPE ) {
-
-/* Consider conversion to "int". */
- if( out_type == AST__INTTYPE ) {
- result = 0;
-
-/* Consider conversion to "short int". */
- } else if( out_type == AST__SINTTYPE ) {
- result = 0;
-
-/* Consider conversion to "byte". */
- } else if( out_type == AST__BYTETYPE ) {
- result = 0;
-
-/* Consider conversion to "double". */
- } else if( out_type == AST__DOUBLETYPE ) {
- result = 0;
-
-/* Consider conversion to "float". */
- } else if( out_type == AST__FLOATTYPE ) {
- result = 0;
-
-/* Consider conversion to "const char *". */
- } else if( out_type == AST__STRINGTYPE ) {
- result = 0;
-
-/* Consider conversion to "AstObject *". */
- } else if( out_type == AST__OBJECTTYPE ) {
- result = 0;
-
-/* Consider conversion to "void *". */
- } else if( out_type == AST__POINTERTYPE ) {
- if( out ) *( (void **) out ) = *( (void **) raw );
-
-/* Report an error if the data type is unknown. */
- } else {
- result = 0;
- astError( AST__INTER, "ConvertValue(KeyMap): Illegal map entry data "
- "type %d encountered (internal AST programming error).", status,
- out_type );
- }
-
-/* Report an error if the data type is unknown. */
- } else {
- result = 0;
- astError( AST__INTER, "ConvertValue(KeyMap): Illegal map entry data "
- "type %d encountered (internal AST programming error).", status,
- raw_type );
- }
-
-/* If the output is a string, store a copy of the resulting string in
- dynamically allocated memory, putting a pointer to the copy into the next
- element of the "convertvalue_strings" array. (This process also de-allocates
- any previously allocated memory pointed at by this "convertvalue_strings"
- element, so the earlier string is effectively replaced by the new
- one.) */
- if( out_type == AST__STRINGTYPE && astOK && result && cvalue ) {
- result = strlen( cvalue ) + 1;
-
- astBeginPM;
- convertvalue_strings[ convertvalue_istr ] = astStore( convertvalue_strings[ convertvalue_istr ], cvalue,
- (size_t) result );
- astEndPM;
-
-/* If OK, return a pointer to the copy and increment "convertvalue_istr" to use the
- next element of "convertvalue_strings" on the next invocation. Recycle "convertvalue_istr" to
- zero when all elements have been used. */
- if ( astOK ) {
- if( out ) *( (const char **) out ) = convertvalue_strings[ convertvalue_istr++ ];
- if( convertvalue_istr == ( AST__KEYMAP_CONVERTVALUE_MAX_STRINGS - 1 ) ) convertvalue_istr = 0;
- }
- }
-
-/* If an error has occurred, return zero. */
- if( !astOK ) result = 0;
-
-/* Return the result. */
- return result;
-}
-
-
-static AstMapEntry *CopyMapEntry( AstMapEntry *in, int *status ){
-/*
-* Name:
-* CopyMapEntry
-
-* Purpose:
-* Produces a copy of the supplied KeyMap entry.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* AstMapEntry *CopyMapEntry( AstMapEntry *in, int *status )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function creates a deep copy of the supplied KeyMap entry.
-
-* Parameters:
-* in
-* Pointer to the MapEntry to be copied. NULL may be supplied in
-* which case NULL will be returned.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Pointer to the new copy. The link to the next MapEntry in the
-* linked list is set NULL in the returned copy.
-
-* 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: */
- AstMapEntry *result; /* Returned pointer */
- AstObject **alist; /* Pointer to list of AST object pointers */
- AstObject *obj; /* Pointer to AstObject value */
- const char **slist; /* Pointer to list of text pointers */
- const char *text; /* Pointer to text string */
- int i; /* Loop count */
- int nel; /* No. of values in entry vector (0 => scalar) */
- int type; /* Entry data type */
- size_t size; /* Size of Entry structure */
-
-/* Initialise. */
- result = NULL;
-
-/* Check the global error status and the supplied pointer. */
- if ( !astOK || !in ) return result;
-
-/* Get the size, data type and length of the MapEntry. */
- size = SizeOfEntry( in, status );
- nel = in->nel;
- type = in->type;
-
-/* Do a byte-for-byte copy of the supplied MapEntry. */
- result = astStore( NULL, in, size );
-
-/* Copy or nullify pointers in the AstMapEntry structure. */
- result->next = NULL;
- result->snext = NULL;
- result->sprev = NULL;
- text = in->key;
- result->key = text ? astStore( NULL, text, strlen( text ) + 1 ) : NULL;
- text = in->comment;
- result->comment = text ? astStore( NULL, text, strlen( text ) + 1 ) : NULL;
-
-/* Nothing further to do for undefined values. */
- if( type == AST__UNDEFTYPE ) {
-
-/* Next deal with string entries. */
- } else if( type == AST__STRINGTYPE ) {
-
-/* Scalar valued entries... */
- if( nel == 0 ) {
-
-/* Take a copy of the single string in the input entry. */
- text = ( (Entry0C *) in )->value;
- ( (Entry0C *) result )->value = text ? astStore( NULL, text,
- strlen( text ) + 1 ) : NULL;
-/* Vector valued entries... */
- } else {
-
-/* Allocate an array to store the string pointers. */
- slist = astMalloc( sizeof(char *)*(size_t)nel );
- ( (Entry1C *) result )->value = slist;
-
-/* Copy the strings. */
- if( slist ) {
- for( i = 0; i < nel; i++ ) {
- text = ( (Entry1C *) in )->value[ i ];
- slist[ i ] = text ? astStore( NULL, text, strlen( text ) + 1 ) : NULL;
- }
- }
- }
-
-/* Similarly deal with AST Object entries. */
- } else if( type == AST__OBJECTTYPE ) {
- if( nel == 0 ) {
- obj = ( (Entry0A *) in )->value;
- ( (Entry0A *) result )->value = obj ? astCopy( obj ) : NULL;
- ( (Entry0A *) result )->next = NULL;
- ( (Entry0A *) result )->prev = NULL;
- } else {
- alist = astMalloc( sizeof(AstObject *)*(size_t)nel );
- ( (Entry1A *) result )->value = alist;
- if( alist ) {
- for( i = 0; i < nel; i++ ) {
- obj = ( (Entry1A *) in )->value[ i ];
- alist[ i ] = obj ? astCopy( obj ) : NULL;
- }
- ( (Entry1A *) result )->next = NULL;
- ( (Entry1A *) result )->prev = NULL;
- }
- }
-
-/* Now deal with integer entries. Scalar entries do not need any further
- action. If this is a vector entry copy the values array. */
- } else if( type == AST__INTTYPE ) {
- if( nel > 0 ) {
- ( (Entry1I *) result )->value = astStore( NULL,
- ( (Entry1I *) in )->value,
- sizeof( int )*(size_t)nel );
- }
-
-/* Now deal with short int entries. Scalar entries do not need any further
- action. If this is a vector entry copy the values array. */
- } else if( type == AST__SINTTYPE ) {
- if( nel > 0 ) {
- ( (Entry1S *) result )->value = astStore( NULL,
- ( (Entry1S *) in )->value,
- sizeof( short int )*(size_t)nel );
- }
-
-/* Now deal with byte entries. Scalar entries do not need any further
- action. If this is a vector entry copy the values array. */
- } else if( type == AST__BYTETYPE ) {
- if( nel > 0 ) {
- ( (Entry1B *) result )->value = astStore( NULL,
- ( (Entry1B *) in )->value,
- sizeof( unsigned char )*(size_t)nel );
- }
-
-/* Similarly deal with floating point entries. */
- } else if( type == AST__DOUBLETYPE ) {
- if( nel > 0 ) {
- ( (Entry1D *) result )->value = astStore( NULL,
- ( (Entry1D *) in )->value,
- sizeof( double )*(size_t)nel );
- }
-
- } else if( type == AST__FLOATTYPE ) {
- if( nel > 0 ) {
- ( (Entry1F *) result )->value = astStore( NULL,
- ( (Entry1F *) in )->value,
- sizeof( float )*(size_t)nel );
- }
-
-/* Similarly deal with void pointer entries. */
- } else if( type == AST__POINTERTYPE ) {
- if( nel > 0 ) {
- ( (Entry1P *) result )->value = astStore( NULL,
- ( (Entry1P *) in )->value,
- sizeof( void * )*(size_t)nel );
- }
-
-/* Report an error if the data type is unknown. */
- } else {
- astError( AST__INTER, "CopyMapEntry(KeyMap): Illegal map entry data "
- "type %d encountered (internal AST programming error).", status,
- type );
- }
-
-/* If an error has occurred, attempt to delete the returned MapEntry. */
- if( !astOK ) result = FreeMapEntry( result, status );
-
-/* Return the result. */
- return result;
-}
-
-static void CopyTableEntry( AstKeyMap *in, AstKeyMap *out, int itab, int *status ){
-/*
-* Name:
-* CopyTableEntry
-
-* Purpose:
-* Produces a deep copy of a hash table element.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* void CopyTableEntry( AstKeyMap *in, AstKeyMap *out, int itab, int *status )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function creates a deep copy of the linked-list of KeyMap entries
-* stored in the specified element of the input KeyMaps hash table.
-
-* Parameters:
-* in
-* Pointer to the input KeyMap.
-* out
-* Pointer to the output KeyMap.
-* itab
-* Index of the hash table element to be copied.
-* status
-* Pointer to the inherited status variable.
-
-*/
-
-/* Local Variables: */
- AstMapEntry **link; /* Address to store foward link */
- AstMapEntry *next; /* Pointer to next Entry to copy */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* The "link" variable holds the address of the location at which the
- pointer to the next copied MapEntry should be stored. Initialise this to
- be the address of the required element of the output hash table. */
- link = &( out->table[ itab ] );
-
-/* The "next" variable holds the address of the next MapEntry to be
- copied. Initialise this to the MapEntry at the head of the linked list
- associated with the specified index of the input KeyMaps hash table. */
- next = in->table[ itab ];
-
-/* If the hash table element is empty, store a null pointer and pass on. */
- if( !next ) {
- out->table[ itab ] = NULL;
-
-/* Otherwise copy the liked list. */
- } else {
-
-/* Loop round until we have copied all entries. */
- while( next && astOK ) {
-
-/* Copy the next entry, storing the resulting pointer at the position
- indicated by "link". */
- *link = CopyMapEntry( next, status );
-
-/* If the entry is of type AST__OBJECTTYPE, add it to the head of the
- list of AST__OBJECTTYPE entries in the output KeyMap. */
- AddToObjectList( out, *link, status );
-
-/* Update "link" and "next" */
- next = next->next;
- link = &( (*link)->next );
- }
- }
-
-/* Set the number of entries in the output to be the same as the input. */
- out->nentry[ itab ] = in->nentry[ itab ];
-
-/* If an error has occurred, attempt to delete the returned MapEntry. */
- if( !astOK ) FreeTableEntry( out, itab, status );
-}
-
-static void DoubleTableSize( AstKeyMap *this, int *status ) {
-/*
-* Name:
-* DoubleTableSize
-
-* Purpose:
-* Double the size of the hash table in a KeyMap
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* void DoubleTableSize( AstKeyMap *this, int *status )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function creates a new hash table which has twice as many
-* elements as the current hash table, and moves all the entries out
-* of the old table into the new table (at their new positions).
-
-* Parameters:
-* this
-* The KeyMap pointer.
-* status
-* Pointer to the inherited status variable.
-
-*/
-
-/* Local Variables: */
- AstMapEntry **newtable;
- AstMapEntry *next;
- AstMapEntry *new_next;
- int *newnentry;
- int bitmask;
- int i;
- int newi;
- int newmapsize;
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Determine the new hash table size. Since mapsize starts out as a power
- of 2 (ensured by the NewTable function), the new mapsize will also be
- a power of 2. Also, create a bit mask that can be used to zero the
- upper bits in a full width hash value. */
- newmapsize = 2*this->mapsize;
- bitmask = newmapsize - 1;
-
-/* Create the new arrays, leaving the old arrays intact for the moment. */
- newtable = astMalloc( newmapsize*sizeof( AstMapEntry * ) );
- newnentry = astMalloc( newmapsize*sizeof( int ) );
- if( astOK ) {
-
-/* Initialise the new table. */
- for( i = 0; i < newmapsize; i++ ) {
- newtable[ i ] = NULL;
- newnentry[ i ] = 0;
- }
-
-/* Loop round each of the existing table entries. */
- for( i = 0; i < this->mapsize; i++ ) {
-
-/* The "next" variable holds the address of the next MapEntry to be
- moved. Initialise this to the MapEntry at the head of the linked list
- associated with the specified index of the input KeyMaps hash table. */
- next = this->table[ i ];
-
-/* Loop round until we have moved all entries. */
- while( next && astOK ) {
-
-/* Find the index within the new table at which to store this entry. */
- newi = ( next->hash & bitmask );
-
-/* Save the pointer to the next entry following the current one in the
- linked list. */
- new_next = next->next;
-
-/* Put a pointer to the MapEntry which is currently at the head of the
- linked list in the "next" component of the current MapEntry. */
- next->next = newtable[ newi ];
-
-/* Store the supplied MapEntry pointer in the requested element of the
- hash table. */
- newtable[ newi ] = next;
-
-/* Increment the length of linked list. */
- newnentry[ newi ]++;
-
-/* Use the pointer to the next map entry to be moved. */
- next = new_next;
- }
- }
- }
-
-/* If OK, delete the existing table and use the new table */
- if( astOK ) {
- this->mapsize = newmapsize;
-
- (void) astFree( this->table );
- this->table = newtable;
-
- (void) astFree( this->nentry );
- this->nentry = newnentry;
-
-/* If not OK, delete the new table. */
- } else {
- newtable = astFree( newtable );
- newnentry = astFree( newnentry );
- }
-}
-
-static void DumpEntry( AstMapEntry *entry, AstChannel *channel, int nentry, int *status ) {
-/*
-* Name:
-* DumpEntry
-
-* Purpose:
-* Dump a single AstMapEntry to a Channel.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* void DumpEntry( AstMapEntry *entry, AstChannel *channel, int nentry )
-
-* Description:
-* This function dumps the supplied MapEntry to the supplied Channel.
-
-* Parameters:
-* entry
-* Pointer to the MapEntry whose data are being written.
-* channel
-* Pointer to the Channel to which the data are being written.
-* nentry
-* The integer index value to use when describing the MapEntry in
-* the dump.
-*/
-
-/* Local Variables: */
- char buff[20]; /* Buffer for item names */
- const char *com; /* Pointer to comment string */
- int index; /* Index into vector valued entry */
- int nel; /* Number of elements in value */
- int type; /* Entry data type */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Dump the entry key. */
- (void) sprintf( buff, "Key%d", nentry );
- astWriteString( channel, buff, 1, 1, entry->key, "Item name" );
-
-/* Dump the comment if not blank. */
- if( entry->comment && *(entry->comment) ) {
- (void) sprintf( buff, "Com%d", nentry );
- astWriteString( channel, buff, 1, 1, entry->comment, "Item comment" );
- }
-
-/* Get the data type and the length of the Entry. */
- type = entry->type;
- nel = entry->nel;
-
-/* Dump the entry data type. */
- if( type == AST__STRINGTYPE ) {
- com = "Item data type (string)";
-
- } else if( type == AST__OBJECTTYPE ) {
- com = "Item data type (AST Object)";
-
- } else if( type == AST__INTTYPE ) {
- com = "Item data type (int)";
-
- } else if( type == AST__SINTTYPE ) {
- com = "Item data type (short int)";
-
- } else if( type == AST__BYTETYPE ) {
- com = "Item data type (unsigned byte)";
-
- } else if( type == AST__DOUBLETYPE ) {
- com = "Item data type (double)";
-
- } else if( type == AST__FLOATTYPE ) {
- com = "Item data type (float)";
-
- } else if( type == AST__POINTERTYPE ) {
- com = "Item data type (pointer)";
-
- } else if( type == AST__UNDEFTYPE ) {
- com = "Item data type (undefined)";
-
- } else {
- com = "";
- astError( AST__INTER, "DumpEntry(KeyMap): Illegal map entry data "
- "type %d encountered (internal AST programming error).", status,
- type );
- }
- (void) sprintf( buff, "Typ%d", nentry );
- astWriteInt( channel, buff, 1, 1, entry->type, com );
-
-/* Dump the vector length */
- if( entry->nel > 0 ) {
- (void) sprintf( buff, "Nel%d", nentry );
- astWriteInt( channel, buff, 1, 1, entry->nel, "Vector length" );
- }
-
-/* First deal with integer entries. */
- if( type == AST__INTTYPE ) {
- if( entry->nel == 0 ) {
- (void) sprintf( buff, "Val%d", nentry );
- astWriteInt( channel, buff, 1, 1, ((Entry0I *)entry)->value, "Item value" );
- } else {
- com = "Item values";
- for( index = 0; index < nel; index++ ){
- (void) sprintf( buff, "V%d_%d", nentry, index + 1 );
- astWriteInt( channel, buff, 1, 1, ((Entry1I *)entry)->value[ index ], com );
- com = "";
- }
- }
-
-/* Similarly, deal with short int entries. */
- } else if( type == AST__SINTTYPE ) {
- if( entry->nel == 0 ) {
- (void) sprintf( buff, "Val%d", nentry );
- astWriteInt( channel, buff, 1, 1, (int) ((Entry0S *)entry)->value, "Item value" );
- } else {
- com = "Item values";
- for( index = 0; index < nel; index++ ){
- (void) sprintf( buff, "V%d_%d", nentry, index + 1 );
- astWriteInt( channel, buff, 1, 1, (int) ((Entry1S *)entry)->value[ index ], com );
- com = "";
- }
- }
-
-/* Similarly, deal with byte entries. */
- } else if( type == AST__BYTETYPE ) {
- if( entry->nel == 0 ) {
- (void) sprintf( buff, "Val%d", nentry );
- astWriteInt( channel, buff, 1, 1, (int) ((Entry0B *)entry)->value, "Item value" );
- } else {
- com = "Item values";
- for( index = 0; index < nel; index++ ){
- (void) sprintf( buff, "V%d_%d", nentry, index + 1 );
- astWriteInt( channel, buff, 1, 1, (int) ((Entry1B *)entry)->value[ index ], com );
- com = "";
- }
- }
-
-/* Similarly deal with floating point entries. */
- } else if( type == AST__DOUBLETYPE ) {
- if( entry->nel == 0 ) {
- if( ((Entry0D *)entry)->value != AST__BAD ) {
- (void) sprintf( buff, "Val%d", nentry );
- astWriteDouble( channel, buff, 1, 1, ((Entry0D *)entry)->value, "Item value" );
- }
- } else {
- com = "Item values";
- for( index = 0; index < nel; index++ ){
- if( ((Entry1D *)entry)->value[ index ] != AST__BAD ) {
- (void) sprintf( buff, "V%d_%d", nentry, index + 1 );
- astWriteDouble( channel, buff, 1, 1, ((Entry1D *)entry)->value[ index ], com );
- com = "";
- }
- }
- }
-
-/* Similarly deal with single precision floating point entries. */
- } else if( type == AST__FLOATTYPE ) {
- if( entry->nel == 0 ) {
- (void) sprintf( buff, "Val%d", nentry );
- astWriteDouble( channel, buff, 1, 1, (double) ((Entry0F *)entry)->value, "Item value" );
- } else {
- com = "Item values";
- for( index = 0; index < nel; index++ ){
- (void) sprintf( buff, "V%d_%d", nentry, index + 1 );
- astWriteDouble( channel, buff, 1, 1, (double) ((Entry1F *)entry)->value[ index ], com );
- com = "";
- }
- }
-
-/* Do the same for string values. */
- } else if( type == AST__STRINGTYPE ) {
- if( entry->nel == 0 ) {
- (void) sprintf( buff, "Val%d", nentry );
- astWriteString( channel, buff, 1, 1, ((Entry0C *)entry)->value, "Item value" );
- } else {
- com = "Item values";
- for( index = 0; index < nel; index++ ){
- (void) sprintf( buff, "V%d_%d", nentry, index + 1 );
- astWriteString( channel, buff, 1, 1, ((Entry1C *)entry)->value[ index ], com );
- com = "";
- }
- }
-
-/* Do the same for Object values. */
- } else if( type == AST__OBJECTTYPE ) {
- if( entry->nel == 0 ) {
- if( ((Entry0A *)entry)->value ) {
- (void) sprintf( buff, "Val%d", nentry );
- astWriteObject( channel, buff, 1, 1, ((Entry0A *)entry)->value, "Item value" );
- }
- } else {
- com = "Item values";
- for( index = 0; index < nel; index++ ){
- if( ((Entry1A *)entry)->value[ index ] ) {
- (void) sprintf( buff, "V%d_%d", nentry, index + 1 );
- astWriteObject( channel, buff, 1, 1, ((Entry1A *)entry)->value[ index ], com );
- com = "";
- }
- }
- }
-
-/* Void pointer values cannot be dumped. */
- } else if( type == AST__POINTERTYPE ) {
- astError( AST__INTER, "DumpEntry(KeyMap): Cannot dump KeyMaps in "
- "which the values are arbitrary C pointers (possible "
- "programming error)." , status);
-
-/* Nothing further to do for undefined values. */
- } else if( type == AST__UNDEFTYPE ) {
-
-/* Report an error if the data type is unknown. */
- } else if( astOK ) {
- astError( AST__INTER, "DumpEntry(KeyMap): Illegal map entry data "
- "type %d encountered (internal AST programming error).", status,
- type );
- }
-}
-
-static AstMapEntry *FreeMapEntry( AstMapEntry *in, int *status ){
-/*
-* Name:
-* FreeMapEntry
-
-* Purpose:
-* Frees the supplied KeyMap entry.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* AstMapEntry *FreeMapEntry( AstMapEntry *in, int *status )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function frees resources used by the supplied MapEntry, then
-* frees the MapEntry structure itself and returns a NULL pointer.
-
-* Parameters:
-* in
-* Pointer to the MapEntry to be freed. NULL may be supplied in
-* which the function returns without action.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A NULL pointer.
-
-* Notes:
-* - It is the callers responsibility to ensure that any other MapEntry
-* which refers to the supplied MapEntry (e.g. through the "next" link
-* in the MapEntry structure) is modified to take account of the
-* freeing of the supplied MapEntry.
-* - This function attempts to execute even if it is invoked with the
-* global error status set.
-*/
-
-/* Local Variables: */
- AstObject **alist; /* Pointer to list of AST object pointers */
- AstObject *obj; /* Pointer to AST object */
- const char **slist; /* Pointer to list of text pointers */
- int i; /* Loop count */
- int nel; /* No. of values in entry vector (0 => scalar) */
- int type; /* Entry data type */
-
-/* Check the supplied pointer. */
- if( !in ) return NULL;
-
-/* Get the data type and length of the MapEntry. */
- nel = in->nel;
- type = in->type;
-
-/* First deal with string entries. */
- if( type == AST__STRINGTYPE ) {
-
-/* For scalar valued entries, free the single string in the input entry. */
- if( nel == 0 ) {
- ( (Entry0C *) in )->value = (const char *) astFree( ( void *) ( (Entry0C *) in )->value );
-
-/* For vector valued entries, free the strings, then free the array storing
- the string pointers. */
- } else {
- slist = ( (Entry1C *) in )->value;
- if( slist ) {
- for( i = 0; i < nel; i++ ) slist[ i ] = astFree( (void *) slist[ i ] );
- ( (Entry1C *) in )->value = astFree( (void *) slist );
- }
- }
-
-/* Similarly deal with AST Object entries. */
- } else if( type == AST__OBJECTTYPE ) {
- if( nel == 0 ) {
- obj = ( (Entry0A *) in )->value;
- if( obj ) ( (Entry0A *) in )->value = astAnnul( obj );
- ( (Entry0A *) in )->next = NULL;
- ( (Entry0A *) in )->prev = NULL;
- } else {
- alist = ( (Entry1A *) in )->value;
- if( alist ) {
- for( i = 0; i < nel; i++ ) {
- if( alist[ i ] ) alist[ i ] = astAnnul( alist[ i ] );
- }
- ( (Entry1A *) in )->value = astFree( alist );
- ( (Entry1A *) in )->next = NULL;
- ( (Entry1A *) in )->prev = NULL;
- }
- }
-
-/* Now deal with integer entries. Scalar entries do not need any further
- action. If this is a vector entry free the values array. */
- } else if( type == AST__INTTYPE ) {
- if( nel > 0 ) ( (Entry1I *) in )->value = astFree( ( (Entry1I *) in )->value );
-
-/* Now deal with short int entries. Scalar entries do not need any further
- action. If this is a vector entry free the values array. */
- } else if( type == AST__SINTTYPE ) {
- if( nel > 0 ) ( (Entry1S *) in )->value = astFree( ( (Entry1S *) in )->value );
-
-/* Now deal with byte entries. Scalar entries do not need any further
- action. If this is a vector entry free the values array. */
- } else if( type == AST__BYTETYPE ) {
- if( nel > 0 ) ( (Entry1B *) in )->value = astFree( ( (Entry1B *) in )->value );
-
-/* Similarly deal with void * pointer entries. */
- } else if( type == AST__POINTERTYPE ) {
- if( nel > 0 ) ( (Entry1P *) in )->value = astFree( ( (Entry1P *) in )->value );
-
-/* Similarly deal with floating point entries. */
- } else if( type == AST__DOUBLETYPE ) {
- if( nel > 0 ) ( (Entry1D *) in )->value = astFree( ( (Entry1D *) in )->value );
-
-/* Similarly deal with single precision floating point entries. */
- } else if( type == AST__FLOATTYPE ) {
- if( nel > 0 ) ( (Entry1F *) in )->value = astFree( ( (Entry1F *) in )->value );
-
-/* Nothing further to do for undefined values. */
- } else if( type == AST__UNDEFTYPE ) {
-
-/* Report an error if the data type is unknown. */
- } else {
- astError( AST__INTER, "FreeMapEntry(KeyMap): Illegal map entry data "
- "type %d encountered (internal AST programming error).", status,
- type );
- }
-
-/* Free or nullify pointers in the AstMapEntry structure. */
- in->next = NULL;
- in->snext = NULL;
- in->sprev = NULL;
- in->key = astFree( (void *) in->key );
- in->comment = astFree( (void *) in->comment );
-
-/* Free the complete AstMapEntry structure. */
- astFree( in );
-
-/* Return a NULL pointer. */
- return NULL;
-}
-
-static void FreeTableEntry( AstKeyMap *this, int itab, int *status ){
-/*
-* Name:
-* FreeTableEntry
-
-* Purpose:
-* Frees the linked list of KeyMap entries stored in a given element of
-* the hash table.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* void FreeTableEntry( AstKeyMap *this, int itab, int *status )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function frees resources used by all the MapEntries in the
-* linked list associated with the specified element of the hash table
-* of the supplied KeyMap.
-
-* Parameters:
-* this
-* Pointer to the KeyMap
-* itab
-* Index of the hash table element to free.
-* status
-* Pointer to the inherited status variable.
-
-* Notes:
-* - This function attempts to execute even if it is invoked with the
-* global error status set.
-*/
-
-/* Local Variables: */
- AstMapEntry *link; /* Pointer the next but one MapEntry to be freed */
- AstMapEntry *next; /* Pointer the next MapEntry to be freed */
-
-/* Check it is safe to proceed. */
- if( this && itab >= 0 && itab < this->mapsize ) {
-
-/* Store a pointer to the MapEntry which is to be freed next. */
- next = this->table[ itab ];
-
-/* Loop round freeing all MapEntries in the linked list. */
- while( next ) {
-
-/* Store a pointer to the MapEntry which will be freed after this one. */
- link = next->next;
-
-/* Free this MapEntry */
- (void) FreeMapEntry( next, status );
-
-/* Set up the next MapEntry to be freed. */
- next = link;
- }
-
-/* Store a NULL pointer in the table element. */
- this->table[ itab ] = NULL;
-
-/* Sets the number of entries in this hash table element to zero. */
- this->nentry[ itab ] = 0;
- }
-}
-
-static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) {
-/*
-* Name:
-* GetAttrib
-
-* Purpose:
-* Get the value of a specified attribute for a KeyMap.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* const char *GetAttrib( AstObject *this, const char *attrib, int *status )
-
-* Class Membership:
-* KeyMap member function (over-rides the protected astGetAttrib
-* method inherited from the Mapping class).
-
-* Description:
-* This function returns a pointer to the value of a specified
-* attribute for a KeyMap, formatted as a character string.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-* 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 KeyMap, 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 KeyMap. 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 */
- AstKeyMap *this; /* Pointer to the KeyMap structure */
- const char *result; /* Pointer value to return */
- int ival; /* Attribute value */
-
-/* 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 KeyMap structure. */
- this = (AstKeyMap *) 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. */
-
-/* SizeGuess. */
-/* ---------- */
- if ( !strcmp( attrib, "sizeguess" ) ) {
- ival = astGetSizeGuess( this );
- if ( astOK ) {
- (void) sprintf( getattrib_buff, "%d", ival );
- result = getattrib_buff;
- }
-
-/* KeyCase. */
-/* --------- */
- } else if ( !strcmp( attrib, "keycase" ) ) {
- ival = astGetKeyCase( this );
- if ( astOK ) {
- (void) sprintf( getattrib_buff, "%d", ival );
- result = getattrib_buff;
- }
-
-/* KeyError. */
-/* --------- */
- } else if ( !strcmp( attrib, "keyerror" ) ) {
- ival = astGetKeyError( this );
- if ( astOK ) {
- (void) sprintf( getattrib_buff, "%d", ival );
- result = getattrib_buff;
- }
-
-/* MapLocked. */
-/* --------- */
- } else if ( !strcmp( attrib, "maplocked" ) ) {
- ival = astGetMapLocked( this );
- if ( astOK ) {
- (void) sprintf( getattrib_buff, "%d", ival );
- result = getattrib_buff;
- }
-
-/* SortBy. */
-/* --------- */
- } else if ( !strcmp( attrib, "sortby" ) ) {
- ival = astGetSortBy( this );
- if ( astOK ) {
- result = SortByString( ival, "astGetAttrib", status );
- }
-
-/* 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 int GetObjSize( AstObject *this_object, int *status ) {
-/*
-* Name:
-* GetObjSize
-
-* Purpose:
-* Return the in-memory size of an Object.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* int GetObjSize( AstObject *this, int *status )
-
-* Class Membership:
-* KeyMap member function (over-rides the astGetObjSize protected
-* method inherited from the parent class).
-
-* Description:
-* This function returns the in-memory size of the supplied KeyMap,
-* in bytes.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The Object size, in bytes.
-
-* Notes:
-* - A value of zero will be returned if this function is invoked
-* with the global status set, or if it should fail for any reason.
-*/
-
-/* Local Variables: */
- AstKeyMap *this; /* Pointer to KeyMap structure */
- AstMapEntry *next; /* Pointer the next MapEntry */
- AstObject **alist; /* Pointer to list of AST object pointers */
- AstObject *obj; /* Pointer to AST object */
- const char **slist; /* Pointer to list of text pointers */
- int i; /* Loop count */
- int itab; /* Table entry index */
- int nel; /* No. of values in entry vector (0 => scalar) */
- int result; /* Result value to return */
- int type; /* Entry data type */
-
-/* Initialise. */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointers to the KeyMap structure. */
- this = (AstKeyMap *) this_object;
-
-/* Invoke the GetObjSize method inherited from the parent class, and then
- add on any components of the class structure defined by thsi class
- which are stored in dynamically allocated memory. */
- result = (*parent_getobjsize)( this_object, status );
-
- for( itab = 0; itab < this->mapsize; itab++ ) {
- next = this->table[ itab ];
- while( next ) {
- nel = next->nel;
- type = next->type;
-
- if( type == AST__STRINGTYPE ) {
-
- if( nel == 0 ) {
- result += astTSizeOf( ( void *) ( (Entry0C *) next )->value );
-
- } else {
- slist = ( (Entry1C *) next )->value;
- if( slist ) {
- for( i = 0; i < nel; i++ ) result += astTSizeOf( (void *) slist[ i ] );
- result += astTSizeOf( (void *) slist );
- }
- }
-
- } else if( type == AST__OBJECTTYPE ) {
- if( nel == 0 ) {
- obj = ( (Entry0A *) next )->value;
- result += astGetObjSize( obj );
- } else {
- alist = ( (Entry1A *) next )->value;
- if( alist ) {
- for( i = 0; i < nel; i++ ) {
- result += astGetObjSize( alist[ i ] );
- }
- result += astTSizeOf( alist );
- }
- }
-
- } else if( type == AST__POINTERTYPE ) {
- if( nel > 0 ) result += astTSizeOf( ( (Entry1P *) next )->value );
-
- } else if( type == AST__INTTYPE ) {
- if( nel > 0 ) result += astTSizeOf( ( (Entry1I *) next )->value );
-
- } else if( type == AST__SINTTYPE ) {
- if( nel > 0 ) result += astTSizeOf( ( (Entry1S *) next )->value );
-
- } else if( type == AST__BYTETYPE ) {
- if( nel > 0 ) result += astTSizeOf( ( (Entry1B *) next )->value );
-
- } else if( type == AST__DOUBLETYPE ) {
- if( nel > 0 ) result += astTSizeOf( ( (Entry1D *) next )->value );
-
- } else if( type == AST__FLOATTYPE ) {
- if( nel > 0 ) result += astTSizeOf( ( (Entry1F *) next )->value );
-
- } else if( type == AST__UNDEFTYPE ) {
-
- } else {
- astError( AST__INTER, "astGetObjSize(KeyMap): Illegal map entry data "
- "type %d encountered (internal AST programming error).", status,
- type );
- }
-
- result += astTSizeOf( (void *) next->key );
- result += astTSizeOf( (void *) next->comment );
- result += astTSizeOf( next );
-
- next = next->next;
- }
- }
-
-/* If an error occurred, clear the result value. */
- if ( !astOK ) result = 0;
-
-/* Return the result, */
- return result;
-}
-
-static const char *GetKey( AstKeyMap *this, int index, int *status ) {
-/*
-* Name:
-* GetKey
-
-* Purpose:
-* Get the key at a given index within the KeyMap.
-
-* Type:
-* Private member function.
-
-* Synopsis:
-* #include "keymap.h"
-* const char *GetKey( AstKeyMap *this, int index, int *status )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This function returns a string holding the key for the entry with
-* the given index within the KeyMap. The index associated with a
-* given key is determined by the current setting of the SortBy attribute.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-* index
-* The index into the KeyMap. The first entry has index zero, and the last
-* has index "size-1", where "size" is the value returned by the
-* astMapSize function. An error is reported if the supplied index is
-* out of bounds.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A pointer to a null-terminated string containing the key.
-
-* Notes:
-* - A NULL pointer will be returned if this function is invoked
-* with the AST error status set, or if it should fail for any
-* reason.
-*/
-
-/* Local Variables: */
- AstMapEntry *entry; /* Pointer to the entry */
- const char *result; /* Pointer value to return */
- int ifirst; /* Index of first entry in this table element */
- int ilast; /* Index of last entry in this table element */
- int istep; /* Entry count */
- int itab; /* Index into hash table */
- int nstep; /* No. of entries to skip */
- int sortby; /* The value of the SortBy attribute */
-
-/* Initialise. */
- result = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Get the SortBy value. */
- sortby = astGetSortBy( this );
-
-/* First deal with unsorted keys. */
- if( sortby == SORTBY_NONE ) {
-
-/* Loop round each entry in the hash table. */
- ilast = -1;
- for( itab = 0; itab < this->mapsize; itab++ ) {
-
-/* Find the index of the first and the last Entry in the linked list associated
- with this element of the hash table. */
- ifirst = ilast + 1;
- ilast += this->nentry[ itab ];
-
-/* Pass on if we have not yet reached the element containing the required
- key. */
- if( ilast >= index ) {
-
-/* Find how many steps we need to proceed down the linked list to reach
- the required index. */
- nstep = index - ifirst;
-
-/* Make this many steps down the linked list.*/
- entry = this->table[ itab ];
- for( istep = 0; entry && istep < nstep; istep++ ) entry = entry->next;
-
-/* Return a pointer to the key string, and break out of the loop. */
- if( entry ) result = entry->key;
- break;
-
- }
- }
-
-/* Now deal with sorted keys. */
- } else {
-
-/* Get a pointer to the first entry in the sorted list. */
- entry = this->first;
-
-/* Move up the sorted list by the required number of entries. */
- for( istep = 0; entry && istep < index; istep++ ) entry = entry->snext;
-
-/* Return a pointer to the key string. */
- if( entry ) result = entry->key;
- }
-
-/* Report an error if the element was not found. */
- if( !result && astOK ) {
- astError( AST__MPIND, "astMapKey(%s): Cannot find element "
- "%d (zero-based) of the %s.", status, astGetClass( this ),
- index, astGetClass( this ) );
- }
-
-/* Return the result.*/
- return result;
-}
-
-static int GetSizeGuess( AstKeyMap *this, int *status ) {
-/*
-*+
-* Name:
-* astGetSizeGuess
-
-* Purpose:
-* Get the value of the SizeGuess attribute for a KeyMap.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "keymap.h"
-* int astGetSizeGuess( AstKeyMap *this )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This function returns the value of the SizeGuess attribute for a
-* KeyMap.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-
-* Returned Value:
-* The value of the SizeGuess attribute.
-
-* Notes:
-* - A value of zero is returned if this function is invoked with the
-* global error status set.
-
-*-
-*/
-
-/* Local Variables: */
- int result; /* Returned value */
-
-/* Initialise */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Return the attribute value using a default if not set. */
- return ( this->sizeguess == INT_MAX ) ?
- MIN_TABLE_SIZE*MAX_ENTRIES_PER_TABLE_ENTRY : this->sizeguess;
-}
-
-static int HashFun( const char *key, int bitmask, unsigned long *hash, int *status ){
-/*
-* Name:
-* HashFun
-
-* Purpose:
-* Returns an integer hash code for a string
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* int HashFun( const char *key, int bitmask, int *hash, int *status )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function returns an integer hash code for the supplied string,
-* This is the value that isused as the index into the hash table for
-* the specified key.
-
-* Parameters:
-* key
-* Pointer to the string. Trailing spaces are ignored.
-* bitmask
-* A bit mask that is used to zero the upper bits of a full width
-* hash value in order to produce the required array index. This
-* should be one less than the length of the hash table.
-* hash
-* Pointer to a location at which to put the full width hash value.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* An integer in the range zero to ( mapsize - 1 ).
-
-* Notes:
-* - A value of zero is returned if this function is invoked with the
-* global error status set.
-*/
-
-/* Local Variables: */
- int c;
-
-/* Check the local error status. */
- if ( !astOK ) return 0;
-
-/* djb2: This hash function was first reported by Dan Bernstein many years
- ago in comp.lang.c Each through the "hile" loop corresponds to
- "hash = hash*33 + c ". Ignore spaces so that trailing spaces used to
- pad F77 character variables will be ignored. */
- *hash = 5381;
- while( (c = *key++) ) {
- if( c != ' ' ) {
- *hash = ((*hash << 5) + *hash) + c;
- }
- }
- return ( *hash & bitmask );
-}
-
-void astInitKeyMapVtab_( AstKeyMapVtab *vtab, const char *name, int *status ) {
-/*
-*+
-* Name:
-* astInitKeyMapVtab
-
-* Purpose:
-* Initialise a virtual function table for a KeyMap.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "keymap.h"
-* void astInitKeyMapVtab( AstKeyMapVtab *vtab, const char *name )
-
-* Class Membership:
-* KeyMap vtab initialiser.
-
-* Description:
-* This function initialises the component of a virtual function
-* table which is used by the KeyMap 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 astIsAKeyMap) 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->MapGet0P = MapGet0P;
- vtab->MapGet0A = MapGet0A;
- vtab->MapGet0C = MapGet0C;
- vtab->MapGet0D = MapGet0D;
- vtab->MapGet0F = MapGet0F;
- vtab->MapGet0I = MapGet0I;
- vtab->MapGet0B = MapGet0B;
- vtab->MapGet0S = MapGet0S;
- vtab->MapGet1P = MapGet1P;
- vtab->MapGet1A = MapGet1A;
- vtab->MapGet1C = MapGet1C;
- vtab->MapGet1D = MapGet1D;
- vtab->MapGet1F = MapGet1F;
- vtab->MapGet1I = MapGet1I;
- vtab->MapGet1B = MapGet1B;
- vtab->MapGet1S = MapGet1S;
- vtab->MapGetElemP = MapGetElemP;
- vtab->MapGetElemA = MapGetElemA;
- vtab->MapGetElemC = MapGetElemC;
- vtab->MapGetElemD = MapGetElemD;
- vtab->MapGetElemF = MapGetElemF;
- vtab->MapGetElemI = MapGetElemI;
- vtab->MapGetElemS = MapGetElemS;
- vtab->MapGetElemB = MapGetElemB;
- vtab->MapPutElemP = MapPutElemP;
- vtab->MapPutElemA = MapPutElemA;
- vtab->MapPutElemC = MapPutElemC;
- vtab->MapPutElemD = MapPutElemD;
- vtab->MapPutElemF = MapPutElemF;
- vtab->MapPutElemI = MapPutElemI;
- vtab->MapPutElemS = MapPutElemS;
- vtab->MapPutElemB = MapPutElemB;
- vtab->MapPut0A = MapPut0A;
- vtab->MapPut0P = MapPut0P;
- vtab->MapPut0C = MapPut0C;
- vtab->MapPut0D = MapPut0D;
- vtab->MapPut0F = MapPut0F;
- vtab->MapPut0I = MapPut0I;
- vtab->MapPut0S = MapPut0S;
- vtab->MapPut0B = MapPut0B;
- vtab->MapPut1P = MapPut1P;
- vtab->MapPut1A = MapPut1A;
- vtab->MapPut1C = MapPut1C;
- vtab->MapPut1D = MapPut1D;
- vtab->MapPut1F = MapPut1F;
- vtab->MapPut1I = MapPut1I;
- vtab->MapPut1S = MapPut1S;
- vtab->MapPut1B = MapPut1B;
- vtab->MapPutU = MapPutU;
- vtab->MapRemove = MapRemove;
- vtab->MapRename = MapRename;
- vtab->MapCopy = MapCopy;
- vtab->MapDefined = MapDefined;
- vtab->MapSize = MapSize;
- vtab->MapLenC = MapLenC;
- vtab->MapLength = MapLength;
- vtab->MapType = MapType;
- vtab->MapHasKey = MapHasKey;
- vtab->MapKey = MapKey;
- vtab->MapIterate = MapIterate;
-
- vtab->ClearSizeGuess = ClearSizeGuess;
- vtab->SetSizeGuess = SetSizeGuess;
- vtab->GetSizeGuess = GetSizeGuess;
- vtab->TestSizeGuess = TestSizeGuess;
-
- vtab->ClearSortBy = ClearSortBy;
- vtab->SetSortBy = SetSortBy;
- vtab->GetSortBy = GetSortBy;
- vtab->TestSortBy = TestSortBy;
-
- vtab->ClearKeyError = ClearKeyError;
- vtab->SetKeyError = SetKeyError;
- vtab->GetKeyError = GetKeyError;
- vtab->TestKeyError = TestKeyError;
-
- vtab->ClearKeyCase = ClearKeyCase;
- vtab->SetKeyCase = SetKeyCase;
- vtab->GetKeyCase = GetKeyCase;
- vtab->TestKeyCase = TestKeyCase;
-
- vtab->ClearMapLocked = ClearMapLocked;
- vtab->SetMapLocked = SetMapLocked;
- vtab->GetMapLocked = GetMapLocked;
- vtab->TestMapLocked = TestMapLocked;
-
-/* Save the inherited pointers to methods that will be extended, and
- replace them with pointers to the new member functions. */
- object = (AstObjectVtab *) vtab;
-
-/* Store replacement pointers for methods which will be over-ridden by
- new member functions implemented here. */
- parent_getobjsize = object->GetObjSize;
- object->GetObjSize = GetObjSize;
-
- parent_clearattrib = object->ClearAttrib;
- object->ClearAttrib = ClearAttrib;
- parent_getattrib = object->GetAttrib;
- object->GetAttrib = GetAttrib;
- parent_setattrib = object->SetAttrib;
- object->SetAttrib = SetAttrib;
- parent_testattrib = object->TestAttrib;
- object->TestAttrib = TestAttrib;
-
-#if defined(THREAD_SAFE)
- parent_managelock = object->ManageLock;
- object->ManageLock = ManageLock;
-#endif
-
-/* Declare the destructor, copy constructor and dump function. */
- astSetDelete( vtab, Delete );
- astSetCopy( vtab, Copy );
- astSetDump( vtab, Dump, "KeyMap", "Map of key/value pairs" );
-
-/* If we have just initialised the vtab for the current class, indicate
- that the vtab is now initialised, and store a pointer to the class
- identifier in the base "object" level of the vtab. */
- if( vtab == &class_vtab ) {
- class_init = 1;
- astSetVtabClassIdentifier( vtab, &(vtab->id) );
- }
-}
-
-static void InitMapEntry( AstMapEntry *entry, int type, int nel, int *status ){
-/*
-* Name:
-* InitMapEntry
-
-* Purpose:
-* initialise a MapEntry structure to null values.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* void InitMapEntry( AstMapEntry *entry, int type, int nel, int *status )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function initialises the contents of a MapEntry to null values.
-
-* Parameters:
-* this
-* Pointer to the MapEntry.
-* type
-* The type of the MapEntry.
-* nel
-* The number of elements in the entry: 0 = scalar, >0 = vector.
-* status
-* Pointer to the inherited status variable.
-
-*/
-
-/* Check the global error status. */
- if( !astOK ) return;
-
-/* Initialise all elements with in the MapEntry structure. */
- entry->next = NULL;
- entry->key = NULL;
- entry->hash = 0;
- entry->type = type;
- entry->nel = nel;
- entry->comment = NULL;
- entry->defined = 0;
- entry->snext = NULL;
- entry->sprev = NULL;
- entry->member = 0;
- entry->keymember = 0;
- entry->sortby = SORTBY_NONE;
-
- if( type == AST__OBJECTTYPE ) {
- if( nel == 0 ) {
- ( (Entry0A *) entry )->next = NULL;
- ( (Entry0A *) entry )->prev = NULL;
- } else {
- ( (Entry1A *) entry )->next = NULL;
- ( (Entry1A *) entry )->prev = NULL;
- }
- }
-
-}
-
-static int KeyCmp( const char *key1, const char *key2 ) {
-/*
-* Name:
-* KeyCmp
-
-* Purpose:
-* Compares keys for equality.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* int KeyCmp( const char *key1, const char *key2 )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function compares two strings. It is like strcmp except that it
-* ignores trailing spaces.
-
-* Parameters:
-* key1
-* Pointer to first string.
-* key2
-* Pointer to second string.
-
-* Returned Value:
-* One if the keys differ. Zero if they are identical (except for
-* trailing spaces).
-
-*/
-
-/* Local Variables: */
- const char *k1; /* Pointer to next "key1" character */
- const char *k2; /* Pointer to next "key2" character */
- int result; /* Returned flag */
-
-/* Check the strings are deifned. */
- if ( !key1 || !key2 ) return 0;
-
-/* Get pointers to the first characters to differ, or to the first null
- character, which ever comes first. */
- k1 = key1;
- k2 = key2;
- while( *k1 && ( *k1 == *k2 ) ) {
- k1++;
- k2++;
- }
-
-/* If both characters are null, the strings are identical. If neither is null,
- the string definitely differ. If one is null, we need to check if the
- other one only has spaces to the end of the string. */
- if( *k1 ) {
- if( *k2 ) {
- result = ( *k1 > *k2 ) ? 1 : -1;
- } else {
- while( *k1 == ' ' ) k1++;
- result = ( *k1 == 0 ) ? 0 : 1;
- }
- } else {
- if( *k2 ) {
- while( *k2 == ' ' ) k2++;
- result = ( *k2 == 0 ) ? 0 : -1;
- } else {
- result = 0;
- }
- }
-
-/* Return the result. */
- return result;
-}
-
-#if defined(THREAD_SAFE)
-static int ManageLock( AstObject *this_object, int mode, int extra,
- AstObject **fail, int *status ) {
-/*
-* Name:
-* ManageLock
-
-* Purpose:
-* Manage the thread lock on an Object.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "object.h"
-* AstObject *ManageLock( AstObject *this, int mode, int extra,
-* AstObject **fail, int *status )
-
-* Class Membership:
-* KeyMap member function (over-rides the astManageLock protected
-* method inherited from the parent class).
-
-* Description:
-* This function manages the thread lock on the supplied Object. The
-* lock can be locked, unlocked or checked by this function as
-* deteremined by parameter "mode". See astLock for details of the way
-* these locks are used.
-
-* Parameters:
-* this
-* Pointer to the Object.
-* mode
-* An integer flag indicating what the function should do:
-*
-* AST__LOCK: Lock the Object for exclusive use by the calling
-* thread. The "extra" value indicates what should be done if the
-* Object is already locked (wait or report an error - see astLock).
-*
-* AST__UNLOCK: Unlock the Object for use by other threads.
-*
-* AST__CHECKLOCK: Check that the object is locked for use by the
-* calling thread (report an error if not).
-* extra
-* Extra mode-specific information.
-* fail
-* If a non-zero function value is returned, a pointer to the
-* Object that caused the failure is returned at "*fail". This may
-* be "this" or it may be an Object contained within "this". Note,
-* the Object's reference count is not incremented, and so the
-* returned pointer should not be annulled. A NULL pointer is
-* returned if this function returns a value of zero.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A local status value:
-* 0 - Success
-* 1 - Could not lock or unlock the object because it was already
-* locked by another thread.
-* 2 - Failed to lock a POSIX mutex
-* 3 - Failed to unlock a POSIX mutex
-* 4 - Bad "mode" value supplied.
-
-* Notes:
-* - This function attempts to execute even if an error has already
-* occurred.
-*/
-
-/* Local Variables: */
- AstKeyMap *this; /* Pointer to KeyMap structure */
- AstMapEntry *next; /* Pointer the next MapEntry */
- AstObject **alist; /* Pointer to list of AST object pointers */
- AstObject *obj; /* Pointer to AST object */
- int i; /* Loop count */
- int nel; /* No. of values in entry vector (0 => scalar) */
- int result; /* Returned status value */
-
-/* Initialise */
- result = 0;
-
-/* Check the supplied pointer is not NULL. */
- if( !this_object ) return result;
-
-/* Obtain a pointers to the KeyMap structure. */
- this = (AstKeyMap *) this_object;
-
-/* Invoke the ManageLock method inherited from the parent class. */
- if( !result ) result = (*parent_managelock)( this_object, mode, extra,
- fail, status );
-
-/* Invoke the astManageLock method on any Objects contained within
- the supplied Object. */
-
- next = this->firstA;
- while( next ) {
- nel = next->nel;
- if( nel == 0 ) {
- obj = ( (Entry0A *) next )->value;
- if( !result ) result = astManageLock( obj, mode, extra, fail );
- next = ( (Entry0A *) next)->next;
- } else {
- alist = ( (Entry1A *) next )->value;
- if( alist ) {
- for( i = 0; i < nel; i++ ) {
- if( !result ) result = astManageLock( alist[ i ], mode,
- extra, fail );
- }
- }
- next = ( (Entry1A *) next)->next;
- }
- }
-
- return result;
-
-}
-#endif
-
-static void MapCopy( AstKeyMap *this, AstKeyMap *that, int *status ) {
-/*
-*++
-* Name:
-c astMapCopy
-f AST_MAPCOPY
-
-* Purpose:
-* Copy entries from one KeyMap into another.
-
-* Type:
-* Public virtual function.
-
-* Synopsis:
-c #include "keymap.h"
-c void astMapCopy( AstKeyMap *this, AstKeyMap *that )
-f CALL AST_MAPCOPY( THIS, THAT, STATUS )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-c This function
-f This routine
-* copies all entries from one KeyMap into another.
-
-* Parameters:
-c this
-f THIS = INTEGER (Given)
-* Pointer to the destination KeyMap.
-c that
-f THAT = INTEGER (Given)
-* Pointer to the source KeyMap.
-f STATUS = INTEGER (Given and Returned)
-f The global status.
-
-* Notes:
-* - Entries from the source KeyMap will replace any existing entries in
-* the destination KeyMap that have the same key.
-* - The one exception to the above rule is that if a source entry
-* contains a scalar KeyMap entry, and the destination contains a
-* scalar KeyMap entry with the same key, then the source KeyMap entry
-* will be copied into the destination KeyMap entry using this function,
-* rather than simply replacing the destination KeyMap entry.
-* - If the destination entry has a non-zero value for its MapLocked
-* attribute, then an error will be reported if the source KeyMap
-* contains any keys that do not already exist within the destination
-* KeyMap.
-
-*--
-*/
-
-/* Local Variables: */
- AstMapEntry *in_entry; /* Pointer to next source entry to copy */
- AstMapEntry *out_entry;/* Pointer to existing destination entry */
- AstObject *in_obj; /* Pointer for source Object entry */
- AstObject *out_obj; /* Pointer for destination Object entry */
- const char *key; /* Key for current entry */
- int i; /* Index into source hash table */
- int itab; /* Index of destination hash table element */
- int keymember; /* Identifier for key */
- int merged; /* Were source and destination KeyMaps merged? */
- unsigned long hash; /* Full width hash value */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Loop round all entries in the source hash table. */
- for( i = 0; i < that->mapsize; i++ ) {
-
-/* Get a pointer to the next source KeyMap entry. */
- in_entry = that->table[ i ];
-
-/* Loop round all entries in this element of the source hash table. */
- while( in_entry && astOK ) {
-
-/* Get its key. */
- key = in_entry->key;
-
-/* Search for a destination entry with the same key. */
- itab = HashFun( key, this->mapsize - 1, &hash, status );
- out_entry = SearchTableEntry( this, itab, key, status );
-
-/* If the destination KeyMap does not contain an entry with the current
- key, store a copy of the entry in the destination, or report an error
- if the destination's MapLocked attribute is set. */
- if( !out_entry ) {
- if( astGetMapLocked( this ) ) {
- astError( AST__BADKEY, "astMapCopy(%s): Failed to copy "
- "item \"%s\": \"%s\" is not a known item.", status,
- astGetClass( this ), key, key );
- } else {
- out_entry = CopyMapEntry( in_entry, status );
- out_entry = AddTableEntry( this, itab, out_entry, -1, status );
- }
-
-/* If the destination KeyMap contains an entry with the current key... */
- } else {
-
-/* The usual thing is to just replace the existing entry in the
- destination with a copy of the source entry. The one case where this is
- not done is if both entries are scalar KeyMaps. In this case the source
- KeyMap is merged into the destination KeyMap using this function. First
- see if we have this situation, and if so, copy the entries from the
- source KeyMap to the destination KeyMap. */
- merged = 0;
- if( in_entry->nel == 0 || in_entry->nel == 1 ) {
- if( out_entry->nel == 0 || out_entry->nel == 1 ) {
- if( in_entry->type == AST__OBJECTTYPE &&
- out_entry->type == AST__OBJECTTYPE ) {
-
- if( in_entry->nel == 0 ) {
- in_obj = ((Entry0A *)in_entry)->value;
- } else {
- in_obj = (((Entry1A *)in_entry)->value)[ 0 ];
- }
-
- if( out_entry->nel == 0 ) {
- out_obj = ((Entry0A *)out_entry)->value;
- } else {
- out_obj = (((Entry1A *)out_entry)->value)[ 0 ];
- }
-
- if( astIsAKeyMap( in_obj ) &&
- astIsAKeyMap( out_obj ) ) {
- astMapCopy( (AstKeyMap *) out_obj,
- (AstKeyMap *) in_obj );
- merged = 1;
- }
- }
- }
- }
-
-/* If the source and desination entries are not KeyMaps, then just remove
- the entry in the desination KeyMap and add a copy of the source entry.
- But retain the original keymember value since we are just changing the
- value of an existing key. */
- if( ! merged ) {
- out_entry = RemoveTableEntry( this, itab, key, status );
- keymember = out_entry->keymember;
- (void) FreeMapEntry( out_entry, status );
- out_entry = CopyMapEntry( in_entry, status );
- out_entry = AddTableEntry( this, itab, out_entry, keymember, status );
- }
- }
-
-/* Update the address of the next MapEntry in the source. */
- in_entry = in_entry->next;
- }
- }
-}
-
-static const char *MapKey( AstKeyMap *this, int index, int *status ) {
-/*
-*++
-* Name:
-c astMapKey
-f AST_MAPKEY
-
-* Purpose:
-* Get the key at a given index within the KeyMap.
-
-* Type:
-* Public virtual function.
-
-* Synopsis:
-c #include "keymap.h"
-c const char *astMapKey( AstKeyMap *this, int index )
-f RESULT = AST_MAPKEY( THIS, INDEX, STATUS )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This function returns a string holding the key for the entry with
-* the given index within the KeyMap.
-*
-* This function is intended primarily as a means of iterating round all
-* the elements in a KeyMap. For this purpose, the number of entries in
-* the KeyMap should first be found using
-c astMapSize
-f AST_MAPSIZE
-* and this function should then be called in a loop, with the index
-* value going from
-c zero to one less than the size of the KeyMap.
-f one to the size of the KeyMap.
-* The index associated with a given entry is determined by the SortBy
-* attribute.
-
-* Parameters:
-c this
-f THIS = INTEGER (Given)
-* Pointer to the KeyMap.
-c index
-f INDEX = INTEGER (Given)
-* The index into the KeyMap. The first entry has index
-c zero, and the last has index "size-1", where "size" is the value
-c returned by the astMapSize function.
-f one, and the last has index SIZE, the value returned by the
-f AST_MAPSIZE function.
-f STATUS = INTEGER (Given and Returned)
-f The global status.
-
-* Returned Value:
-c astMapKey()
-c A pointer to a null-terminated string containing the key.
-f AST_MAPKEY = CHARACTER * ( AST__SZCHR )
-f The key value.
-
-* Notes:
-c - The returned pointer is guaranteed to remain valid and the
-c string to which it points will not be over-written for a total
-c of 50 successive invocations of this function. After this, the
-c memory containing the string may be re-used, so a copy of the
-c string should be made if it is needed for longer than this.
-c - A NULL pointer will be returned if this function is invoked
-c with the AST error status set, or if it should fail for any
-c reason.
-f - A blank string will be returned if this function is invoked
-f with STATUS set to an error value, or if it should fail for any
-f reason.
-*--
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Declare the thread specific global data */
- const char *result; /* Pointer value to return */
- const char *value; /* Pointer to key value */
- int i; /* Loop counter for initialisation */
-
-/* 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);
-
-/* If the "mapkey_strings" array has not been initialised, fill it with
- NULL pointers. */
- if ( !mapkey_init ) {
- mapkey_init = 1;
- for ( i = 0; i < AST__KEYMAP_MAPKEY_MAX_STRINGS; i++ ) mapkey_strings[ i ] = NULL;
- }
-
-/* Obtain a pointer to the required key value. */
- value = GetKey( this, index, status );
-
-/* If OK, store a copy of the resulting string in dynamically
- allocated memory, putting a pointer to the copy into the next
- element of the "mapkey_strings" array. (This process also de-allocates
- any previously allocated memory pointed at by this "mapkey_strings"
- element, so the earlier string is effectively replaced by the new
- one.) */
- if ( astOK ) {
- astBeginPM;
- mapkey_strings[ mapkey_istr ] = astStore( mapkey_strings[ mapkey_istr ], value,
- strlen( value ) + (size_t) 1 );
- astEndPM;
-
-/* If OK, return a pointer to the copy and increment "mapkey_istr" to use the
- next element of "mapkey_strings" on the next invocation. Recycle "mapkey_istr" to
- zero when all elements have been used. */
- if ( astOK ) {
- result = mapkey_strings[ mapkey_istr++ ];
- if ( mapkey_istr == ( AST__KEYMAP_MAPKEY_MAX_STRINGS - 1 ) ) mapkey_istr = 0;
- }
- }
-
-/* Return the result. */
- return result;
-
-}
-
-/*
-*++
-* Name:
-c astMapPut0<X>
-f AST_MAPPUT0<X>
-
-* Purpose:
-* Add a scalar value to a KeyMap.
-
-* Type:
-* Public virtual function.
-
-* Synopsis:
-c #include "ast.h"
-c void astMapPut0<X>( AstKeyMap *this, const char *key, <X>type value,
-c const char *comment );
-f CALL AST_MAPPUT0<X>( THIS, KEY, VALUE, COMMENT, STATUS )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-c This is a set of functions
-f This is a set of routine
-* for adding scalar values to a KeyMap. You should use a
-c function
-f routine
-* which matches the data type of the data you wish to add to the KeyMap
-* by replacing <X> in the generic
-c function name astMapPut0<X>
-f routine name AST_MAPPUT0<X>
-* by an appropriate 1-character type code (see the "Data Type Codes"
-* section below for the code appropriate to each supported data type).
-
-* Parameters:
-c this
-f THIS = INTEGER (Given)
-* Pointer to the KeyMap in which to store the supplied value.
-c key
-f KEY = CHARACTER * ( * ) (Given)
-* A character string to be stored with the value, which can later
-* be used to identify the value. Trailing spaces are ignored.
-* The supplied string is converted to upper case before use if the
-* KeyCase attribute is currently set to zero.
-c value
-f VALUE = <X>type (Given)
-* The value to be stored. The data type of this value should match the
-* 1-character type code appended to the
-c function name (e.g. if you are using astMapPut0A, the type of this
-c value should be "pointer to AstObject").
-f routine name (e.g. if you are using AST_MAPPUT0A, the type of this
-f value should be "integer pointer for an AstObject").
-c comment
-f COMMENT = CHARACTER * ( * ) (Given)
-f A comment string to be stored with the value.
-c A pointer to a null-terminated comment string to be stored with the
-c value. A NULL pointer may be supplied, in which case no comment is
-c stored.
-f STATUS = INTEGER (Given and Returned)
-f The global status.
-
-* Notes:
-* - If the supplied key is already in use in the KeyMap, the new value
-* will replace the old value.
-* - If the stored value is an AST Object pointer, the Object's reference
-* count is incremented by this call. Any subsequent changes made to
-* the Object using the returned pointer will be reflected in any
-* any other active pointers for the Object, including any obtained
-* later using
-c astMapget0A.
-f AST_MAPGET0A.
-* The reference count for the Object will be decremented when the
-* KeyMap is destroyed, or the entry is removed or over-written with a
-* different pointer.
-
-* Data Type Codes:
-* To select the appropriate
-c function, you should replace <X> in the generic function name astMapPut0<X>
-f routine, you should replace <X> in the generic routine name AST_MAPPUT0<X>
-* with a 1-character data type code, so as to match the data type <X>type
-* of the data you are processing, as follows:
-c - D: double
-c - F: float
-c - I: int
-c - C: "const" pointer to null terminated character string
-c - A: Pointer to AstObject
-c - P: Generic "void *" pointer
-c - S: short int
-c - B: unsigned byte (i.e. unsigned char)
-f - D: DOUBLE PRECISION
-f - R: REAL
-f - I: INTEGER
-f - C: CHARACTER
-f - A: INTEGER used to identify an AstObject
-f - S: INTEGER*2 (short integer)
-f - B: Unsigned byte
-*
-c For example, astMapPut0D would be used to store a "double" value,
-c while astMapPut0I would be used to store an "int", etc.
-f For example, AST_MAPPUT0D would be used to store a DOUBLE PRECISION value,
-f while AST_MAPPUT0I would be used to store an INTEGER, etc.
-c
-c Note that KeyMaps containing generic "void *" pointers cannot be
-c written out using astShow or astWrite. An error will be reported if
-c this is attempted.
-*--
-*/
-/* Define a macro to implement the function for a specific data type. */
-#define MAKE_MAPPUT0(X,Xtype,Itype,ValExp) \
-static void MapPut0##X( AstKeyMap *this, const char *skey, Xtype value, \
- const char *comment, int *status ) { \
-\
-/* Local Variables: */ \
- AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */ \
- AstMapEntry *oldent; /* Pointer to existing MapEntry */ \
- Entry0##X *entry; /* Structure holding the data for the new Entry */ \
- const char *key; /* Pointer to key string to use */ \
- char *p; /* Pointer to next key character */ \
- char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ \
- int itab; /* Index of hash table element to use */ \
- int keylen; /* Length of supplied key string */ \
- int keymember; /* Identifier for existing key */ \
- int there; /* Did the entry already exist in the KeyMap? */ \
-\
-/* Check the global error status. */ \
- if ( !astOK ) return; \
-\
-/* Perform any necessary checks on the supplied value to be stored. */ \
- CHECK_##X \
-\
-/* Convert the supplied key to upper case if required. */ \
- key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapPut0" #X, \
- status ); \
-\
-/* Allocate memory for the new MapEntry. */ \
- entry = astMalloc( sizeof( Entry0##X ) ); \
- if( astOK ) { \
-\
-/* Initialise the new structure.*/ \
- mapentry = (AstMapEntry *) entry; \
- InitMapEntry( mapentry, Itype, 0, status ); \
-\
-/* Now store the new values. */ \
- keylen = strlen( key ); \
- mapentry->key = astStore( NULL, key, keylen + 1 ); \
- if( comment ) mapentry->comment = astStore( NULL, comment, strlen( comment ) + 1 ); \
- mapentry->defined = 1; \
- entry->value = ValExp; \
-\
-/* Terminate the key string to exclude any trailing spaces. */ \
- if( astOK ) { \
- p = (char *) mapentry->key + keylen; \
- while( --p >= mapentry->key ) { \
- if( *p == ' ' ) { \
- *p = 0; \
- } else { \
- break; \
- } \
- } \
- } \
-\
-/* Use the hash function to determine the element of the hash table in \
- which to store the new entry. */ \
- itab = HashFun( mapentry->key, this->mapsize - 1, &(mapentry->hash), status ); \
-\
-/* Remove any existing entry with the given key from the table element. \
- First save the key identifier. */ \
- oldent = RemoveTableEntry( this, itab, mapentry->key, status ); \
- if( oldent ) { \
- keymember = oldent->keymember; \
- oldent = FreeMapEntry( oldent, status ); \
- there = 1; \
- } else { \
- keymember = -1; \
- there = 0; \
- } \
-\
-/* If the KeyMap is locked we report an error if an attempt is made to add a value for \
- a new key. */ \
- if( !there && astGetMapLocked( this ) ) { \
- astError( AST__BADKEY, "astMapPut0" #X "(%s): Failed to add item \"%s\" to a KeyMap: " \
- "\"%s\" is not a known item.", status, astGetClass( this ), key, key ); \
- } \
-\
-/* If all has gone OK, store the new entry at the head of the linked list \
- associated with the selected table entry. */ \
- if( astOK ) { \
- mapentry = AddTableEntry( this, itab, mapentry, keymember, status ); \
-\
-/* If anything went wrong, try to delete the new entry. */ \
- } else { \
- mapentry = FreeMapEntry( mapentry, status ); \
- } \
- } \
-}
-
-/* Define macros which perform any necessary checks on the supplied value
- to be stored. For Object entries, check that we are not adding a KeyMap
- which already contains "this". This avoids circular dependencies.
- Other types do not need any checks. */
-#define CHECK_A CheckCircle( this, value, "astMapPut0A", status );
-#define CHECK_I
-#define CHECK_D
-#define CHECK_F
-#define CHECK_C
-#define CHECK_P
-#define CHECK_S
-#define CHECK_B
-
-/* Expand the above macro to generate a function for each required
- data type. */
-MAKE_MAPPUT0(I,int,AST__INTTYPE,value)
-MAKE_MAPPUT0(D,double,AST__DOUBLETYPE,value)
-MAKE_MAPPUT0(F,float,AST__FLOATTYPE,value)
-MAKE_MAPPUT0(C,const char *,AST__STRINGTYPE,astStore(NULL,value,strlen(value)+1))
-MAKE_MAPPUT0(A,AstObject *,AST__OBJECTTYPE,(value?astClone(value):NULL))
-MAKE_MAPPUT0(P,void *,AST__POINTERTYPE,value)
-MAKE_MAPPUT0(S,short int,AST__SINTTYPE,value)
-MAKE_MAPPUT0(B,unsigned char,AST__BYTETYPE,value)
-
-/* Undefine the macro. */
-#undef MAKE_MAPPUT0
-#undef CHECK_A
-#undef CHECK_I
-#undef CHECK_S
-#undef CHECK_D
-#undef CHECK_F
-#undef CHECK_C
-#undef CHECK_P
-#undef CHECK_B
-
-/*
-*++
-* Name:
-c astMapPut1<X>
-f AST_MAPPUT1<X>
-
-* Purpose:
-* Add a vector value to a KeyMap.
-
-* Type:
-* Public virtual function.
-
-* Synopsis:
-c #include "ast.h"
-c void astMapPut1<X>( AstKeyMap *this, const char *key, int size,
-c const <X>type value[], const char *comment );
-f CALL AST_MAPPUT1<X>( THIS, KEY, SIZE, VALUE, COMMENT, STATUS )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-c This is a set of functions
-f This is a set of routine
-* for adding vector values to a KeyMap. You should use a
-c function
-f routine
-* which matches the data type of the data you wish to add to the KeyMap
-* by replacing <X> in the generic
-c function name astMapPut1<X>
-f routine name AST_MAPPUT1<X>
-* by an appropriate 1-character type code (see the "Data Type Codes"
-* section below for the code appropriate to each supported data type).
-
-* Parameters:
-c this
-f THIS = INTEGER (Given)
-* Pointer to the KeyMap in which to store the supplied values.
-c key
-f KEY = CHARACTER * ( * ) (Given)
-* A character string to be stored with the values, which can later
-* be used to identify the values. Trailing spaces are ignored.
-* The supplied string is converted to upper case before use if the
-* KeyCase attribute is currently set to zero.
-c size
-f SIZE = INTEGER (Given)
-* The number of elements in the supplied array of values.
-c value
-f VALUE( * ) = <X>type (Given)
-* The array of values to be stored. The data type of this value should
-* match the 1-character type code appended to the
-c function name (e.g. if you are using astMapPut1A, the type of this
-c value should be "array of pointers to AstObject").
-f routine name (e.g. if you are using AST_MAPPUT1A, the type of this
-f value should be "integer pointer for an AstObject)".
-c comment
-f COMMENT = CHARACTER * ( * ) (Given)
-f A comment string to be stored with the values.
-c A pointer to a null-terminated comment string to be stored with the
-c values. A NULL pointer may be supplied, in which case no comment is
-c stored.
-f STATUS = INTEGER (Given and Returned)
-f The global status.
-
-* Notes:
-* - If the supplied key is already in use in the KeyMap, the new values
-* will replace the old values.
-
-* Data Type Codes:
-* To select the appropriate
-c function, you should replace <X> in the generic function name astMapPut1<X>
-f routine, you should replace <X> in the generic routine name AST_MAPPUT1<X>
-* with a 1-character data type code, so as to match the data type <X>type
-* of the data you are processing, as follows:
-c - D: double
-c - F: float
-c - I: int
-c - C: "const" pointer to null terminated character string
-c - A: Pointer to AstObject
-c - P: Generic "void *" pointer
-c - S: short int
-c - B: Unsigned byte (i.e. char)
-f - D: DOUBLE PRECISION
-f - R: REAL
-f - I: INTEGER
-f - C: CHARACTER
-f - A: INTEGER used to identify an AstObject
-f - S: INTEGER*2 (short integer)
-f - B: Unsigned byte
-*
-c For example, astMapPut1D would be used to store "double" values,
-c while astMapPut1I would be used to store "int", etc.
-f For example, AST_MAPPUT1D would be used to store DOUBLE PRECISION values,
-f while AST_MAPPUT1I would be used to store INTEGER, etc.
-c
-c Note that KeyMaps containing generic "void *" pointers cannot be
-c written out using astShow or astWrite. An error will be reported if
-c this is attempted.
-*--
-*/
-/* Define a macro to implement the function for a specific data type. */
-#define MAKE_MAPPUT1(X,Xtype,Itype,ValExp) \
-static void MapPut1##X( AstKeyMap *this, const char *skey, int size, \
- Xtype value[], const char *comment, \
- int *status ) { \
-\
-/* Local Variables: */ \
- AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */ \
- AstMapEntry *oldent; /* Pointer to existing MapEntry */ \
- Entry1##X *entry; /* Structure holding the data for the new Entry */ \
- char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ \
- const char *key; /* Pointer to key string to use */ \
- char *p; /* Pointer to next key character */ \
- int itab; /* Index of hash table element to use */ \
- int i; /* Loop count */ \
- int keylen; /* Length of supplied key string */ \
- int keymember; /* Identifier for existing key */ \
- int there; /* Did the entry already exist in the KeyMap? */ \
-\
-/* Check the global error status. */ \
- if ( !astOK ) return; \
-\
-/* Perform any necessary checks on the supplied value to be stored. */ \
- CHECK_##X \
-\
-/* Convert the supplied key to upper case if required. */ \
- key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapPut1" #X, \
- status ); \
-\
-/* Allocate memory for the new MapEntry. */ \
- entry = astMalloc( sizeof( Entry1##X ) ); \
- if( astOK ) { \
-\
-/* Initialise the new structure.*/ \
- mapentry = (AstMapEntry *) entry; \
- InitMapEntry( mapentry, Itype, size, status ); \
-\
-/* Now store the new values. */ \
- keylen = strlen( key ); \
- mapentry->key = astStore( NULL, key, keylen + 1 ); \
- if( comment ) mapentry->comment = astStore( NULL, comment, strlen( comment ) + 1 ); \
- mapentry->defined = 1; \
- entry->value = astMalloc( sizeof( Xtype )*(size_t)size ); \
-\
- if( astOK ) { \
- for( i = 0; i < size; i++ ) { \
- entry->value[ i ] = ValExp; \
- } \
-\
-/* Terminate the key string to exclude any trailing spaces. */ \
- p = (char *) mapentry->key + keylen; \
- while( --p >= mapentry->key ) { \
- if( *p == ' ' ) { \
- *p = 0; \
- } else { \
- break; \
- } \
- } \
- } \
-\
-/* Use the hash function to determine the element of the hash table in \
- which to store the new entry. */ \
- itab = HashFun( mapentry->key, this->mapsize - 1, &(mapentry->hash), status ); \
-\
-/* Remove any existing entry with the given key from the table element. \
- First save the key identifier. */ \
- oldent = RemoveTableEntry( this, itab, mapentry->key, status ); \
- if( oldent ) { \
- keymember = oldent->keymember; \
- oldent = FreeMapEntry( oldent, status ); \
- there = 1; \
- } else { \
- keymember = -1; \
- there = 0; \
- } \
-\
-/* If the KeyMap is locked we report an error if an attempt is made to add a value for \
- a new key. */ \
- if( !there && astGetMapLocked( this ) ) { \
- astError( AST__BADKEY, "astMapPut1" #X "(%s): Failed to add item \"%s\" to a KeyMap: " \
- "\"%s\" is not a known item.", status, astGetClass( this ), key, key ); \
- } \
-\
-/* If all has gone OK, store the new entry at the head of the linked list \
- associated with the selected table entry. */ \
- if( astOK ) { \
- mapentry = AddTableEntry( this, itab, mapentry, keymember, status ); \
-\
-/* If anything went wrong, try to delete the new entry. */ \
- } else { \
- mapentry = FreeMapEntry( mapentry, status ); \
- } \
- } \
-}
-
-/* Define macros which perform any necessary checks on the supplied values
- to be stored. For Object entries, check that we are not adding a KeyMap
- which already contains "this". This avoids circular dependencies.
- Other types do not need any checks. */
-#define CHECK_A \
-for( i = 0; i < size; i++ ) { \
- CheckCircle( this, value[ i ], "astMapPut1A", status ); \
-}
-#define CHECK_I
-#define CHECK_S
-#define CHECK_B
-#define CHECK_D
-#define CHECK_F
-#define CHECK_C
-#define CHECK_P
-
-/* Expand the above macro to generate a function for each required
- data type. */
-MAKE_MAPPUT1(D,const double,AST__DOUBLETYPE,value[i])
-MAKE_MAPPUT1(F,const float,AST__FLOATTYPE,value[i])
-MAKE_MAPPUT1(I,const int,AST__INTTYPE,value[i])
-MAKE_MAPPUT1(C,const char *const,AST__STRINGTYPE,astStore(NULL,value[i],strlen(value[i])+1))
-MAKE_MAPPUT1(A,AstObject *const,AST__OBJECTTYPE,(value[i]?astClone(value[i]):NULL))
-MAKE_MAPPUT1(P,void *const,AST__POINTERTYPE,value[i])
-MAKE_MAPPUT1(S,const short int,AST__SINTTYPE,value[i])
-MAKE_MAPPUT1(B,const unsigned char,AST__BYTETYPE,value[i])
-
-/* Undefine the macro. */
-#undef MAKE_MAPPUT1
-#undef CHECK_A
-#undef CHECK_I
-#undef CHECK_B
-#undef CHECK_S
-#undef CHECK_D
-#undef CHECK_F
-#undef CHECK_C
-#undef CHECK_P
-
-void astMapPut1AId_( AstKeyMap *this, const char *skey, int size,
- AstObject *const value[], const char *comment,
- int *status ) {
-/*
-* Name:
-* astMapPut1AId_
-
-* Purpose:
-* Add a vector of AstObject pointers to a KeyMap.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "ast.h"
-* void astMapPut1A( AstKeyMap *this, const char *key, int size,
-* AstObject *const value[], const char *comment )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This is the public implementation of the astMapPut1A function
-* It is identical to astMapPut1A_ except that ID values are supplied
-* via the "value" parameter instead of a true C pointers.
-
-* Parameters:
-* (see astMapPut1<X>)
-
-*/
-
-/* Local Variables: */
- AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */
- AstMapEntry *oldent; /* Pointer to existing MapEntry */
- AstObject *op; /* Object pointer */
- Entry1A *entry; /* Structure holding the data for the new Entry */
- char *p; /* Pointer to next key character */
- char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ \
- const char *key; /* Pointer to key string to use */ \
- int i; /* Loop count */
- int itab; /* Index of hash table element to use */
- int keylen; /* Length of supplied key string */
- int keymember; /* Identifier for existing key */
- int there; /* Did the entry already exist in the KeyMap? */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Convert the supplied key to upper case if required. */
- key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapPut1A",
- status );
-
-/* Allocate memory for the new MapEntry. */
- entry = astMalloc( sizeof( Entry1A ) );
- if( astOK ) {
-
-/* Initialise the new structure.*/
- mapentry = (AstMapEntry *) entry;
- InitMapEntry( mapentry, AST__OBJECTTYPE, size, status );
-
-/* Now store the new values. */
- keylen = strlen( key );
- mapentry->key = astStore( NULL, key, keylen + 1 );
- if( comment ) mapentry->comment = astStore( NULL, comment, strlen( comment ) + 1 );
- mapentry->defined = 1;
- entry->value = astMalloc( sizeof( AstObject * )*(size_t)size );
-
- if( astOK ) {
- for( i = 0; i < size; i++ ) {
- op = value[ i ] ? astMakePointer( value[ i ] ) : NULL;
- entry->value[ i ] = op ? astClone( op ) : NULL;
- }
-
-/* Terminate the key string to exclude any trailing spaces. */ \
- p = (char *) mapentry->key + keylen;
- while( --p >= mapentry->key ) {
- if( *p == ' ' ) {
- *p = 0;
- } else {
- break;
- }
- }
- }
-
-/* Use the hash function to determine the element of the hash table in
- which to store the new entry. */
- itab = HashFun( mapentry->key, this->mapsize - 1, &(mapentry->hash), status );
-
-/* Remove any existing entry with the given key from the table element. */
- oldent = RemoveTableEntry( this, itab, mapentry->key, status );
- if( oldent ) {
- keymember = oldent->keymember;
- oldent = FreeMapEntry( oldent, status );
- there = 1;
- } else {
- there = 0;
- keymember = -1;
- }
-
-/* If the KeyMap is locked we report an error if an attempt is made to add a value for
- a new key. */
- if( !there && astGetMapLocked( this ) ) {
- astError( AST__BADKEY, "astMapPut1A(%s): Failed to add item \"%s\" to a KeyMap: "
- "\"%s\" is not a known item.", status, astGetClass( this ), key, key );
- }
-
-/* If all has gone OK, store the new entry at the head of the linked list
- associated with the selected table entry. */
- if( astOK ) {
- mapentry = AddTableEntry( this, itab, mapentry, keymember, status );
-
-/* If anything went wrong, try to delete the new entry. */
- } else {
- mapentry = FreeMapEntry( mapentry, status );
- }
- }
-}
-
-static void MapPutU( AstKeyMap *this, const char *skey, const char *comment,
- int *status ) {
-/*
-*++
-* Name:
-c astMapPutU
-f AST_MAPPUTU
-
-* Purpose:
-* Add an entry to a KeyMap with an undefined value.
-
-* Type:
-* Public virtual function.
-
-* Synopsis:
-c #include "ast.h"
-c void astMapPutU( AstKeyMap *this, const char *key, const char *comment );
-f CALL AST_MAPPUTU( THIS, KEY, COMMENT, STATUS )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-c This function
-f This routine
-* adds a new entry to a KeyMap, but no value is stored with the
-* entry. The entry therefore has a special data type represented by
-* symbolic constant AST__UNDEFTYPE.
-*
-* An example use is to add entries with undefined values to a KeyMap
-* prior to locking them with the MapLocked attribute. Such entries
-* can act as placeholders for values that can be added to the KeyMap
-* later.
-
-* Parameters:
-c this
-f THIS = INTEGER (Given)
-* Pointer to the KeyMap in which to store the supplied value.
-c key
-f KEY = CHARACTER * ( * ) (Given)
-* A character string to be stored with the value, which can later
-* be used to identify the value. Trailing spaces are ignored.
-* The supplied string is converted to upper case before use if the
-* KeyCase attribute is currently set to zero.
-c comment
-f COMMENT = CHARACTER * ( * ) (Given)
-f A comment string to be stored with the value.
-c A pointer to a null-terminated comment string to be stored with the
-c value. A NULL pointer may be supplied, in which case no comment is
-c stored.
-f STATUS = INTEGER (Given and Returned)
-f The global status.
-
-* Notes:
-* - If the supplied key is already in use in the KeyMap, the value
-* associated with the key will be removed.
-
-*--
-*/
-
-/* Local Variables: */
- AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */
- AstMapEntry *oldent; /* Pointer to existing MapEntry */
- char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */
- const char *key; /* Pointer to key string to use */
- char *p; /* Pointer to next key character */
- int itab; /* Index of hash table element to use */
- int keylen; /* Length of supplied key string */
- int keymember; /* Identifier for existing key */
- int there; /* Did the entry already exist in the KeyMap? */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Convert the supplied key to upper case if required. */
- key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapPutU",
- status );
-
-/* Allocate memory for the new MapEntry. */
- mapentry = astMalloc( sizeof( AstMapEntry ) );
- if( astOK ) {
-
-/* Initialise the new structure.*/
- InitMapEntry( mapentry, AST__UNDEFTYPE, 0, status );
-
-/* Now store the new values. */
- keylen = strlen( key );
- mapentry->key = astStore( NULL, key, keylen + 1 );
- if( comment ) mapentry->comment = astStore( NULL, comment, strlen( comment ) + 1 );
- mapentry->defined = 0;
-
-/* Terminate the key string to exclude any trailing spaces. */
- if( astOK ) {
- p = (char *) mapentry->key + keylen;
- while( --p >= mapentry->key ) {
- if( *p == ' ' ) {
- *p = 0;
- } else {
- break;
- }
- }
- }
-
-/* Use the hash function to determine the element of the hash table in
- which to store the new entry. */
- itab = HashFun( mapentry->key, this->mapsize - 1, &(mapentry->hash), status );
-
-/* Remove any existing entry with the given key from the table element. */
- oldent = RemoveTableEntry( this, itab, mapentry->key, status );
- if( oldent ) {
- keymember = oldent->keymember;
- oldent = FreeMapEntry( oldent, status );
- there = 1;
- } else {
- keymember = -1;
- there = 0;
- }
-
-/* If the KeyMap is locked we report an error if an attempt is made to add a value for
- a new key. */
- if( !there && astGetMapLocked( this ) ) {
- astError( AST__BADKEY, "astMapPutU(%s): Failed to add item \"%s\" to a KeyMap: "
- "\"%s\" is not a known item.", status, astGetClass( this ), key, key );
- }
-
-/* If all has gone OK, store the new entry at the head of the linked list
- associated with the selected table entry. */
- if( astOK ) {
- mapentry = AddTableEntry( this, itab, mapentry, keymember, status );
-
-/* If anything went wrong, try to delete the new entry. */
- } else {
- mapentry = FreeMapEntry( mapentry, status );
- }
- }
-}
-
-/*
-*++
-* Name:
-c astMapGet0<X>
-f AST_MAPGET0<X>
-
-* Purpose:
-* Get a scalar value from a KeyMap.
-
-* Type:
-* Public virtual function.
-
-* Synopsis:
-c #include "ast.h"
-c int astMapGet0<X>( AstKeyMap *this, const char *key, <X>type *value );
-f RESULT = AST_MAPGET0<X>( THIS, KEY, VALUE, STATUS )
-
-f RESULT = AST_MAPGET0C( THIS, KEY, VALUE, L, STATUS )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This is a set of functions for retrieving a scalar value from a KeyMap.
-* You should replace <X> in the generic function name
-c astMapGet0<X>
-f AST_MAPGET0<X>
-* by an appropriate 1-character type code (see the "Data Type Codes"
-* section below for the code appropriate to each supported data type).
-* The stored value is converted to the data type indiced by <X>
-* before being returned (an error is reported if it is not possible to
-* convert the stored value to the requested data type).
-f Note, the version of this function which returns character strings,
-f AST_MAPGET0C, has an extra parameter in which is returned the number
-f of characters written into the supplied CHARACTER variable.
-
-* Parameters:
-c this
-f THIS = INTEGER (Given)
-* Pointer to the KeyMap.
-c key
-f KEY = CHARACTER * ( * ) (Given)
-* The character string identifying the value to be retrieved. Trailing
-* spaces are ignored. The supplied string is converted to upper
-* case before use if the KeyCase attribute is currently set to zero.
-c value
-f VALUE = <X>type (Returned)
-c A pointer to a buffer in which to return the requested value.
-f The requested value.
-* If the requested key is not found, or if it is found but has an
-* undefined value (see
-c astMapPutU),
-f AST_MAPPUTU),
-* then the contents of the
-* buffer on entry to this function will be unchanged on exit.
-c For pointer types ("A" and "C"), the buffer should be a suitable
-c pointer, and the address of this pointer should be supplied as the
-c "value" parameter.
-f L = INTEGER (Returned)
-f This parameter is only present in the interface for the AST_MAPGET0C
-f function. It is returned holding the number of characters
-f written into the CHARACTER variable supplied for parameter VALUE.
-f STATUS = INTEGER (Given and Returned)
-f The global status.
-
-* Returned Value:
-c astMapGet0<X>()
-f AST_MAPGET0<X> = LOGICAL
-c A non-zero value
-f .TRUE.
-* is returned if the requested key name was found, and does not have
-* an undefined value (see
-c astMapPutU). Zero
-f AST_MAPPUTU). .FALSE.
-* is returned otherwise.
-
-* Notes:
-* - No error is reported if the requested key cannot be found in the
-* given KeyMap, but a
-c zero
-f .FALSE.
-* value will be returned as the function value. The supplied buffer
-* will be returned unchanged.
-* - If the stored value is a vector value, then the first value in
-* the vector will be returned.
-c - A string pointer returned by astMapGet0C is guaranteed to remain valid
-c and the string to which it points will not be over-written for a
-c total of 50 successive invocations of this function. After this,
-c the memory containing the string may be re-used, so a copy of
-c the string should be made if it is needed for longer than this. The
-c calling code should never attempt to free the returned pointer
-c (for instance, using astFree).
-* - If the returned value is an AST Object pointer, the Object's reference
-* count is incremented by this call. Any subsequent changes made to
-* the Object using the returned pointer will be reflected in any
-* any other active pointers for the Object. The returned pointer
-* should be annulled using
-c astAnnul
-f AST_ANNUL
-* when it is no longer needed.
-
-* Data Type Codes:
-* To select the appropriate
-c function, you should replace <X> in the generic function name astMapGet0<X>
-f routine, you should replace <X> in the generic routine name AST_MAPGET0<X>
-* with a 1-character data type code, so as to match the data type <X>type
-* of the data you are processing, as follows:
-c - F: float
-c - D: double
-c - I: int
-c - C: "const" pointer to null terminated character string
-c - A: Pointer to AstObject
-c - P: Generic "void *" pointer
-c - S: short int
-c - B: Unsigned byte (i.e. word)
-f - D: DOUBLE PRECISION
-f - R: REAL
-f - I: INTEGER
-f - C: CHARACTER
-f - A: INTEGER used to identify an AstObject
-f - S: INTEGER*2 (short integer)
-f - B: Unsigned byte
-*
-c For example, astMapGet0D would be used to get a "double" value,
-c while astMapGet0I would be used to get an "int", etc.
-f For example, AST_MAPGET0D would be used to get a DOUBLE PRECISION value,
-f while AST_MAPGET0I would be used to get an INTEGER, etc.
-*--
-*/
-/* Define a macro to implement the function for a specific data type. */
-#define MAKE_MAPGET0(X,Xtype,Itype) \
-static int MapGet0##X( AstKeyMap *this, const char *skey, Xtype *value, int *status ) { \
-\
-/* Local Variables: */ \
- AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */ \
- const char *key; /* Pointer to key string to use */ \
- char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ \
- int itab; /* Index of hash table element to use */ \
- int raw_type; /* Data type of stored value */ \
- int result; /* Returned flag */ \
- unsigned long hash; /* Full width hash value */ \
- void *raw; /* Pointer to stored value */ \
-\
-/* Initialise */ \
- result = 0; \
-\
-/* Check the global error status. */ \
- if ( !astOK ) return result; \
-\
-/* Convert the supplied key to upper case if required. */ \
- key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapGet0" #X, \
- status ); \
-\
-/* Use the hash function to determine the element of the hash table in \
- which the key will be stored. */ \
- itab = HashFun( key, this->mapsize - 1, &hash, status ); \
-\
-/* Search the relevent table entry for the required MapEntry. */ \
- mapentry = SearchTableEntry( this, itab, key, status ); \
-\
-/* Skip rest if the key was not found. */ \
- if( mapentry ) { \
-\
-/* Get the address of the raw value, and its data type. */ \
- raw_type = mapentry->type; \
- if( raw_type == AST__INTTYPE ){ \
- if( mapentry->nel == 0 ) { \
- raw = &( ((Entry0I *)mapentry)->value ); \
- } else { \
- raw = ((Entry1I *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__SINTTYPE ){ \
- if( mapentry->nel == 0 ) { \
- raw = &( ((Entry0S *)mapentry)->value ); \
- } else { \
- raw = ((Entry1S *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__BYTETYPE ){ \
- if( mapentry->nel == 0 ) { \
- raw = &( ((Entry0B *)mapentry)->value ); \
- } else { \
- raw = ((Entry1B *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__DOUBLETYPE ){ \
- if( mapentry->nel == 0 ) { \
- raw = &( ((Entry0D *)mapentry)->value ); \
- } else { \
- raw = ((Entry1D *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__FLOATTYPE ){ \
- if( mapentry->nel == 0 ) { \
- raw = &( ((Entry0F *)mapentry)->value ); \
- } else { \
- raw = ((Entry1F *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__POINTERTYPE ){ \
- if( mapentry->nel == 0 ) { \
- raw = &( ((Entry0P *)mapentry)->value ); \
- } else { \
- raw = ((Entry1P *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__STRINGTYPE ){ \
- if( mapentry->nel == 0 ) { \
- raw = &( ((Entry0C *)mapentry)->value ); \
- } else { \
- raw = ((Entry1C *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__OBJECTTYPE ){ \
- if( mapentry->nel == 0 ) { \
- raw = &( ((Entry0A *)mapentry)->value ); \
- } else { \
- raw = ((Entry1A *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__UNDEFTYPE ){ \
- raw = NULL; \
-\
- } else { \
- raw = NULL; \
- astError( AST__INTER, "astMapGet0<X>(KeyMap): Illegal map entry data " \
- "type %d encountered (internal AST programming error).", status, \
- raw_type ); \
- } \
-\
-/* Convert the value, storing the result the supplied buffer. Report an \
- error if conversion is not possible. */ \
- if( !raw ) { \
- result = 0; \
-\
- } else if( !ConvertValue( raw, raw_type, value, Itype, status ) && astOK ){ \
- astError( AST__MPGER, "astMapGet0" #X "(%s): The value of KeyMap key " \
- "\"%s\" cannot be read using the requested data " \
- "type.", status,astGetClass( this ), key ); \
-\
- } else { \
- result = 1; \
- } \
-\
-/* If the KeyError attribute is non-zero, report an error if the key is not \
- found */ \
- } else if( astGetKeyError( this ) && astOK ) { \
- astError( AST__MPKER, "astMapGet0" #X "(%s): No value was found for " \
- "%s in the supplied KeyMap.", status, astGetClass( this ), \
- key ); \
- } \
-\
-/* If an error occurred, return zero. */ \
- if( !astOK ) result = 0; \
-\
-/* Return the result.*/ \
- return result; \
-}
-
-/* Expand the above macro to generate a function for each required
- data type. */
-MAKE_MAPGET0(I,int,AST__INTTYPE)
-MAKE_MAPGET0(D,double,AST__DOUBLETYPE)
-MAKE_MAPGET0(F,float,AST__FLOATTYPE)
-MAKE_MAPGET0(C,const char *,AST__STRINGTYPE)
-MAKE_MAPGET0(A,AstObject *,AST__OBJECTTYPE)
-MAKE_MAPGET0(P,void *,AST__POINTERTYPE)
-MAKE_MAPGET0(S,short int,AST__SINTTYPE)
-MAKE_MAPGET0(B,unsigned char,AST__BYTETYPE)
-
-/* Undefine the macro. */
-#undef MAKE_MAPGET0
-
-int astMapGet0AId_( AstKeyMap *this, const char *skey, AstObject **value, int *status ) {
-/*
-* Name:
-* astMapGet0AId_
-
-* Purpose:
-* Get a scalar AstObject pointer from a KeyMap.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "ast.h"
-* int astMapGet0A( AstKeyMap *this, const char *key, AstObject **value )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This is the public implementation of the astMapGet0A function
-* It is identical to astMapGet0A_ except that an ID value is returned
-* via the "value" parameter instead of a true C pointer. This is required
-* because this conversion cannot be performed by the macro that invokes
-* the function.
-
-* Parameters:
-* (see astMapGet0<X>)
-
-*/
-
-/* Local Variables: */
- AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */
- char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ \
- const char *key; /* Pointer to key string to use */ \
- int itab; /* Index of hash table element to use */
- int raw_type; /* Data type of stored value */
- int result; /* Returned flag */
- unsigned long hash; /* Full width hash value */
- void *raw; /* Pointer to stored value */
-
-/* Initialise */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Convert the supplied key to upper case if required. */
- key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapGet0A",
- status );
-
-/* Use the hash function to determine the element of the hash table in
- which the key will be stored. */
- itab = HashFun( key, this->mapsize - 1, &hash, status );
-
-/* Search the relevent table entry for the required MapEntry. */
- mapentry = SearchTableEntry( this, itab, key, status );
-
-/* Skip rest if the key was not found. */
- if( mapentry ) {
-
-/* Get the address of the raw value, and its data type. */
- raw_type = mapentry->type;
- if( raw_type == AST__INTTYPE ){
- if( mapentry->nel == 0 ) {
- raw = &( ((Entry0I *)mapentry)->value );
- } else {
- raw = ((Entry1I *)mapentry)->value;
- }
-
- } else if( raw_type == AST__POINTERTYPE ){
- if( mapentry->nel == 0 ) {
- raw = &( ((Entry0P *)mapentry)->value );
- } else {
- raw = ((Entry1P *)mapentry)->value;
- }
-
- } else if( raw_type == AST__SINTTYPE ){
- if( mapentry->nel == 0 ) {
- raw = &( ((Entry0S *)mapentry)->value );
- } else {
- raw = ((Entry1S *)mapentry)->value;
- }
-
- } else if( raw_type == AST__BYTETYPE ){
- if( mapentry->nel == 0 ) {
- raw = &( ((Entry0B *)mapentry)->value );
- } else {
- raw = ((Entry1B *)mapentry)->value;
- }
-
- } else if( raw_type == AST__DOUBLETYPE ){
- if( mapentry->nel == 0 ) {
- raw = &( ((Entry0D *)mapentry)->value );
- } else {
- raw = ((Entry1D *)mapentry)->value;
- }
-
- } else if( raw_type == AST__FLOATTYPE ){
- if( mapentry->nel == 0 ) {
- raw = &( ((Entry0F *)mapentry)->value );
- } else {
- raw = ((Entry1F *)mapentry)->value;
- }
-
- } else if( raw_type == AST__STRINGTYPE ){
- if( mapentry->nel == 0 ) {
- raw = &( ((Entry0C *)mapentry)->value );
- } else {
- raw = ((Entry1C *)mapentry)->value;
- }
-
- } else if( raw_type == AST__OBJECTTYPE ){
- if( mapentry->nel == 0 ) {
- raw = &( ((Entry0A *)mapentry)->value );
- } else {
- raw = ((Entry1A *)mapentry)->value;
- }
-
- } else if( raw_type == AST__UNDEFTYPE ){
- raw = NULL;
-
- } else {
- raw = NULL;
- astError( AST__INTER, "astMapGet0<X>(KeyMap): Illegal map entry data "
- "type %d encountered (internal AST programming error).", status,
- raw_type );
- }
-
-/* Convert the value, storing the result the supplied buffer. Report an
- error if conversion is not possible. */
- if( !raw ) {
- result = 0;
-
- } else if( !ConvertValue( raw, raw_type, value, AST__OBJECTTYPE, status ) && astOK ){
- astError( AST__MPGER, "astMapGet0A(%s): The value of KeyMap key "
- "\"%s\" cannot be read using the requested data "
- "type.", status, astGetClass( this ), key );
-
- } else {
- result = 1;
- }
-
-/* If the KeyError attribute is non-zero, report an error if the key is not
- found */
- } else if( astGetKeyError( this ) && astOK ) {
- astError( AST__MPKER, "astMapGet0A(%s): No value was found for "
- "%s in the supplied KeyMap.", status, astGetClass( this ),
- key );
- }
-
-/* If required, return an ID value for the Object. */
- if( result && *value ) *value = astMakeId( *value );
-
-/* Return the result.*/
- return result;
-}
-
-/*
-*++
-* Name:
-c astMapGet1<X>
-f AST_MAPGET1<X>
-
-* Purpose:
-* Get a vector value from a KeyMap.
-
-* Type:
-* Public virtual function.
-
-* Synopsis:
-c #include "ast.h"
-c int astMapGet1<X>( AstKeyMap *this, const char *key, int mxval,
-c int *nval, <X>type *value )
-c int astMapGet1C( AstKeyMap *this, const char *key, int l, int mxval,
-c int *nval, const char *value )
-f RESULT = AST_MAPGET1<X>( THIS, KEY, MXVAL, NVAL, VALUE, STATUS )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This is a set of functions for retrieving a vector value from a KeyMap.
-* You should replace <X> in the generic function name
-c astMapGet1<X>
-f AST_MAPGET1<X>
-* by an appropriate 1-character type code (see the "Data Type Codes"
-* section below for the code appropriate to each supported data type).
-* The stored value is converted to the data type indiced by <X>
-* before being returned (an error is reported if it is not possible to
-* convert the stored value to the requested data type).
-c Note, the astMapGet1C function has an extra parameter "l" which
-c specifies the maximum length of each string to be stored in the
-c "value" buffer (see the "astMapGet1C" section below).
-
-* Parameters:
-c this
-f THIS = INTEGER (Given)
-* Pointer to the KeyMap.
-c key
-f KEY = CHARACTER * ( * ) (Given)
-* The character string identifying the value to be retrieved. Trailing
-* spaces are ignored.
-* The supplied string is converted to upper case before use if the
-* KeyCase attribute is currently set to zero.
-c mxval
-f MXVAL = INTEGER (Given)
-* The number of elements in the
-c "value" array.
-f VALUE array.
-c nval
-f NVAL = INTEGER (Returned)
-c The address of an integer in which to put the
-f The
-* number of elements stored in the
-c "value" array.
-* Any unused elements of the array are left unchanged.
-c value
-f VALUE( MXVAL ) = <X>type (Returned)
-c A pointer to an array in which to return the requested values.
-f The requested values.
-* If the requested key is not found, or if it is found but has an
-* undefined value (see
-c astMapPutU),
-f AST_MAPPUTU),
-* then the contents of the
-* buffer on entry to this function will be unchanged on exit.
-f STATUS = INTEGER (Given and Returned)
-f The global status.
-
-* Returned Value:
-c astMapGet1<X>()
-f AST_MAPGET1<X> = LOGICAL
-c A non-zero value
-f .TRUE.
-* is returned if the requested key name was found, and does not have
-* an undefined value (see
-c astMapPutU). Zero
-f AST_MAPPUTU). .FALSE.
-* is returned otherwise.
-
-* Notes:
-* - No error is reported if the requested key cannot be found in the
-* given KeyMap, but a
-c zero
-f .FALSE.
-* value will be returned as the function value. The supplied array
-* will be returned unchanged.
-* - If the stored value is a scalar value, then the value will be
-* returned in the first element of the supplied array, and
-c "nval"
-f NVAL
-* will be returned set to 1.
-
-c astMapGet1C:
-c The "value" buffer supplied to the astMapGet1C function should be a
-c pointer to a character array with "mxval*l" elements, where "l" is
-c the maximum length of a string to be returned. The value of "l"
-c should be supplied as an extra parameter following "key" when
-c invoking astMapGet1C, and should include space for a terminating
-c null character.
-
-* Data Type Codes:
-* To select the appropriate
-c function, you should replace <X> in the generic function name astMapGet1<X>
-f routine, you should replace <X> in the generic routine name AST_MAPGET1<X>
-* with a 1-character data type code, so as to match the data type <X>type
-* of the data you are processing, as follows:
-c - D: double
-c - F: float
-c - I: int
-c - C: "const" pointer to null terminated character string
-c - A: Pointer to AstObject
-c - P: Generic "void *" pointer
-c - S: short int
-c - B: Unsigned byte (i.e. char)
-f - D: DOUBLE PRECISION
-f - R: REAL
-f - I: INTEGER
-f - C: CHARACTER
-f - A: INTEGER used to identify an AstObject
-f - S: INTEGER*2 (short integer)
-f - B: Unsigned byte
-*
-c For example, astMapGet1D would be used to get "double" values, while
-c astMapGet1I would be used to get "int" values, etc. For D or I, the
-c supplied "value" parameter should be a pointer to an array of doubles
-c or ints, with "mxval" elements. For C, the supplied "value" parameter
-c should be a pointer to a character string with "mxval*l" elements.
-c For A, the supplied "value" parameter should be a pointer to an
-c array of AstObject pointers.
-f For example, AST_MAPGET1D would be used to get DOUBLE PRECISION values,
-f while AST_MAPGET1I would be used to get INTEGER values, etc.
-
-*--
-*/
-/* Define a macro to implement the function for a specific data type
-(excluding "C" since that needs an extra parameter). */
-#define MAKE_MAPGET1(X,Xtype,Itype) \
-static int MapGet1##X( AstKeyMap *this, const char *skey, int mxval, int *nval, Xtype *value, int *status ) { \
-\
-/* Local Variables: */ \
- AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */ \
- const char *key; /* Pointer to key string to use */ \
- char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ \
- int i; /* Element index */ \
- int itab; /* Index of hash table element to use */ \
- int nel; /* Number of elements in raw vector */ \
- int raw_type; /* Data type of stored value */ \
- int result; /* Returned flag */ \
- size_t raw_size; /* Size of a single raw value */ \
- unsigned long hash; /* Full width hash value */ \
- void *raw; /* Pointer to stored value */ \
-\
-/* Initialise */ \
- result = 0; \
- *nval = 0; \
-\
-/* Check the global error status. */ \
- if ( !astOK ) return result; \
-\
-/* Convert the supplied key to upper case if required. */ \
- key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapGet1" #X, \
- status ); \
-\
-/* Use the hash function to determine the element of the hash table in \
- which the key will be stored. */ \
- itab = HashFun( key, this->mapsize - 1, &hash, status ); \
-\
-/* Search the relevent table entry for the required MapEntry. */ \
- mapentry = SearchTableEntry( this, itab, key, status ); \
-\
-/* Skip rest if the key was not found. */ \
- if( mapentry ) { \
- result = 1; \
-\
-/* Get the address of the first raw value, and its data type. Also get \
- the size of each element of the vector. */ \
- nel = mapentry->nel; \
- raw_type = mapentry->type; \
- if( raw_type == AST__INTTYPE ){ \
- raw_size = sizeof( int ); \
- if( nel == 0 ) { \
- raw = &( ((Entry0I *)mapentry)->value ); \
- } else { \
- raw = ((Entry1I *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__DOUBLETYPE ){ \
- raw_size = sizeof( double ); \
- if( nel == 0 ) { \
- raw = &( ((Entry0D *)mapentry)->value ); \
- } else { \
- raw = ((Entry1D *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__SINTTYPE ){ \
- raw_size = sizeof( short int ); \
- if( nel == 0 ) { \
- raw = &( ((Entry0S *)mapentry)->value ); \
- } else { \
- raw = ((Entry1S *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__BYTETYPE ){ \
- raw_size = sizeof( unsigned char ); \
- if( nel == 0 ) { \
- raw = &( ((Entry0B *)mapentry)->value ); \
- } else { \
- raw = ((Entry1B *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__POINTERTYPE ){ \
- raw_size = sizeof( void * ); \
- if( nel == 0 ) { \
- raw = &( ((Entry0P *)mapentry)->value ); \
- } else { \
- raw = ((Entry1P *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__FLOATTYPE ){ \
- raw_size = sizeof( float ); \
- if( nel == 0 ) { \
- raw = &( ((Entry0F *)mapentry)->value ); \
- } else { \
- raw = ((Entry1F *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__STRINGTYPE ){ \
- raw_size = sizeof( const char * ); \
- if( nel == 0 ) { \
- raw = &( ((Entry0C *)mapentry)->value ); \
- } else { \
- raw = ((Entry1C *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__OBJECTTYPE ){ \
- raw_size = sizeof( AstObject * ); \
- if( nel == 0 ) { \
- raw = &( ((Entry0A *)mapentry)->value ); \
- } else { \
- raw = ((Entry1A *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__UNDEFTYPE ){ \
- raw_size = 0; \
- raw = NULL; \
-\
- } else { \
- raw_size = 0; \
- raw = NULL; \
- astError( AST__INTER, "astMapGet1<X>(KeyMap): Illegal map entry data " \
- "type %d encountered (internal AST programming error).", status, \
- raw_type ); \
- } \
-\
-/* Treat scalars as single-value vectors. */ \
- if( nel == 0 ) nel = 1; \
-\
-/* Ensure no more than "mxval" values are returned. */ \
- if( nel > mxval ) nel = mxval; \
-\
-/* Return the number of values stored in the buffer. */ \
- *nval = nel; \
-\
-/* Loop round all values in the vector. */ \
- for( i = 0; i < nel && astOK; i++ ) { \
-\
-/* Convert the value, storing the result in the supplied buffer. Report an \
- error if conversion is not possible. */ \
- if( !raw ) { \
- result = 0; \
-\
- } else if( !ConvertValue( raw, raw_type, value + i, Itype, status ) && astOK ){ \
- astError( AST__MPGER, "astMapGet1" #X "(%s): The value of " \
- "element %d of KeyMap key \"%s\" cannot be read using " \
- "the requested data type.", status,astGetClass( this ), i + 1, key ); \
- } \
-\
-/* Increment the pointers to the next raw value. */ \
- raw = (char *) raw + raw_size; \
- } \
-\
-/* If the KeyError attribute is non-zero, report an error if the key is not \
- found */ \
- } else if( astGetKeyError( this ) && astOK ) { \
- astError( AST__MPKER, "astMapGet1" #X "(%s): No value was found for " \
- "%s in the supplied KeyMap.", status, astGetClass( this ), \
- key ); \
- } \
-\
-/* If an error occurred,return zero. */ \
- if( !astOK ) result = 0; \
-\
-/* Return the result.*/ \
- return result; \
-}
-
-/* Expand the above macro to generate a function for each required
- data type (except C which is done differently). */
-MAKE_MAPGET1(I,int,AST__INTTYPE)
-MAKE_MAPGET1(D,double,AST__DOUBLETYPE)
-MAKE_MAPGET1(F,float,AST__FLOATTYPE)
-MAKE_MAPGET1(A,AstObject *,AST__OBJECTTYPE)
-MAKE_MAPGET1(P,void *,AST__POINTERTYPE)
-MAKE_MAPGET1(S,short int,AST__SINTTYPE)
-MAKE_MAPGET1(B,unsigned char,AST__BYTETYPE)
-
-/* Undefine the macro. */
-#undef MAKE_MAPGET1
-
-
-static int MapGet1C( AstKeyMap *this, const char *skey, int l, int mxval,
- int *nval, char *value, int *status ) {
-/*
-* Name:
-* MapGet1C
-
-* Purpose:
-* Get a vector value from a KeyMap.
-
-* Type:
-* Private member function.
-
-* Synopsis:
-* #include "ast.h"
-* int MapGet1C( AstKeyMap *this, const char *key, int l, int mxval,
-* int *nval, char *value, int *status )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This is the implementation of astMapGet1<X> for <X> = "C". We
-* cannot use the MAKE_MAPGET1 macro for this because the string
-* version of this function has an extra parameter giving the maximum
-* length of each string which can be stored in the supplied buffer.
-
-* Parameters:
-* (see astMapGet1<X>)
-*/
-
-/* Local Variables: */
- AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */
- char *val; /* Pointer to next buffer element */
- char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ \
- const char *cvalue; /* Pointer to converted string */
- const char *key; /* Pointer to key string to use */ \
- int i; /* Element index */
- int itab; /* Index of hash table element to use */
- int nel; /* Number of elements in raw vector */
- int raw_type; /* Data type of stored value */
- int result; /* Returned flag */
- size_t raw_size; /* Size of a single raw value */
- unsigned long hash; /* Full width hash value */
- void *raw; /* Pointer to stored value */
-
-/* Initialise */
- result = 0;
- *nval = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Convert the supplied key to upper case if required. */
- key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapGet1C",
- status );
-
-/* Use the hash function to determine the element of the hash table in
- which the key will be stored. */
- itab = HashFun( key, this->mapsize - 1, &hash, status );
-
-/* Search the relevent table entry for the required MapEntry. */
- mapentry = SearchTableEntry( this, itab, key, status );
-
-/* Skip rest if the key was not found. */
- if( mapentry ) {
- result = 1;
-
-/* Get the address of the first raw value, and its data type. Also get
- the size of each element of the vector. */
- nel = mapentry->nel;
- raw_type = mapentry->type;
- if( raw_type == AST__INTTYPE ){
- raw_size = sizeof( int );
- if( nel == 0 ) {
- raw = &( ((Entry0I *)mapentry)->value );
- } else {
- raw = ((Entry1I *)mapentry)->value;
- }
-
- } else if( raw_type == AST__POINTERTYPE ){
- raw_size = sizeof( void * );
- if( nel == 0 ) {
- raw = &( ((Entry0P *)mapentry)->value );
- } else {
- raw = ((Entry1P *)mapentry)->value;
- }
-
- } else if( raw_type == AST__DOUBLETYPE ){
- raw_size = sizeof( double );
- if( nel == 0 ) {
- raw = &( ((Entry0D *)mapentry)->value );
- } else {
- raw = ((Entry1D *)mapentry)->value;
- }
-
- } else if( raw_type == AST__SINTTYPE ){
- raw_size = sizeof( short int );
- if( nel == 0 ) {
- raw = &( ((Entry0S *)mapentry)->value );
- } else {
- raw = ((Entry1S *)mapentry)->value;
- }
-
- } else if( raw_type == AST__BYTETYPE ){
- raw_size = sizeof( unsigned char );
- if( nel == 0 ) {
- raw = &( ((Entry0B *)mapentry)->value );
- } else {
- raw = ((Entry1B *)mapentry)->value;
- }
-
- } else if( raw_type == AST__FLOATTYPE ){
- raw_size = sizeof( float );
- if( nel == 0 ) {
- raw = &( ((Entry0F *)mapentry)->value );
- } else {
- raw = ((Entry1F *)mapentry)->value;
- }
-
- } else if( raw_type == AST__STRINGTYPE ){
- raw_size = sizeof( const char * );
- if( nel == 0 ) {
- raw = &( ((Entry0C *)mapentry)->value );
- } else {
- raw = ((Entry1C *)mapentry)->value;
- }
-
- } else if( raw_type == AST__OBJECTTYPE ){
- raw_size = sizeof( AstObject * );
- if( nel == 0 ) {
- raw = &( ((Entry0A *)mapentry)->value );
- } else {
- raw = ((Entry1A *)mapentry)->value;
- }
-
- } else if( raw_type == AST__UNDEFTYPE ){
- raw_size = 0;
- raw = NULL;
-
- } else {
- raw_size = 0;
- raw = NULL;
- astError( AST__INTER, "astMapGet1C(KeyMap): Illegal map entry data "
- "type %d encountered (internal AST programming error).", status,
- raw_type );
- }
-
-/* Treat scalars as single-value vectors. */
- if( nel == 0 ) nel = 1;
-
-/* Ensure no more than "mxval" values are returned. */
- if( nel > mxval ) nel = mxval;
-
-/* Return the number of values stored in the buffer. */
- *nval = nel;
-
-/* Loop round all values in the vector. */
- val = value;
- for( i = 0; i < nel && astOK; i++ ) {
-
-/* Convert the value, storing the result in the supplied buffer. Report an
- error if conversion is not possible. */
- if( !raw ) {
- result = 0;
-
- } else if( !ConvertValue( raw, raw_type, &cvalue, AST__STRINGTYPE, status ) && astOK ){
- astError( AST__MPGER, "astMapGet1C(%s): The value of "
- "element %d of KeyMap key \"%s\" cannot be read using "
- "the requested data type.", status,astGetClass( this ), i + 1, key );
-
-/* If succesful, copy the string into the supplied buffer, or as much of
- it as will fit. Leave room for a trailing null character. */
- } else {
- strncpy( val, cvalue, l - 1 );
- val[ l - 1 ] = 0;
- }
-
-/* Increment the pointers to the next raw value and the next buffer
- location. */
- raw = (char *) raw + raw_size;
- val += l;
- }
-
-/* If the KeyError attribute is non-zero, report an error if the key is not
- found */
- } else if( astGetKeyError( this ) && astOK ) {
- astError( AST__MPKER, "astMapGet1C(%s): No value was found for "
- "%s in the supplied KeyMap.", status, astGetClass( this ),
- key );
- }
-
-/* If an error occurred,return zero. */
- if( !astOK ) result = 0;
-
-/* Return the result.*/
- return result;
-}
-
-int astMapGet1AId_( AstKeyMap *this, const char *skey, int mxval, int *nval,
- AstObject **value, int *status ) {
-/*
-* Name:
-* astMapGet1AId_
-
-* Purpose:
-* Get a vector of AstObject pointers from a KeyMap.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "ast.h"
-* int astMapGet1A( AstKeyMap *this, const char *key, int mxval, int *nval,
-* AstObject **value )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This is the public implementation of the astMapGet1A function
-* It is identical to astMapGet1A_ except that ID values are returned
-* via the "value" parameter instead of a true C pointers. This is required
-* because this conversion cannot be performed by the macro that invokes
-* the function.
-
-* Parameters:
-* (see astMapGet1<X>)
-
-*/
-
-/* Local Variables: */
- AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */
- AstObject *avalue; /* Pointer to AstObject */
- char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ \
- const char *key; /* Pointer to key string to use */ \
- int i; /* Element index */
- int itab; /* Index of hash table element to use */
- int nel; /* Number of elements in raw vector */
- int raw_type; /* Data type of stored value */
- int result; /* Returned flag */
- size_t raw_size; /* Size of a single raw value */
- unsigned long hash; /* Full width hash value */
- void *raw; /* Pointer to stored value */
-
-/* Initialise */
- result = 0;
- *nval = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Convert the supplied key to upper case if required. */
- key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapGet1A",
- status );
-
-/* Use the hash function to determine the element of the hash table in
- which the key will be stored. */
- itab = HashFun( key, this->mapsize - 1, &hash, status );
-
-/* Search the relevent table entry for the required MapEntry. */
- mapentry = SearchTableEntry( this, itab, key, status );
-
-/* Skip rest if the key was not found. */
- if( mapentry ) {
- result = 1;
-
-/* Get the address of the first raw value, and its data type. Also get
- the size of each element of the vector. */
- nel = mapentry->nel;
- raw_type = mapentry->type;
- if( raw_type == AST__INTTYPE ){
- raw_size = sizeof( int );
- if( nel == 0 ) {
- raw = &( ((Entry0I *)mapentry)->value );
- } else {
- raw = ((Entry1I *)mapentry)->value;
- }
-
- } else if( raw_type == AST__DOUBLETYPE ){
- raw_size = sizeof( double );
- if( nel == 0 ) {
- raw = &( ((Entry0D *)mapentry)->value );
- } else {
- raw = ((Entry1D *)mapentry)->value;
- }
-
- } else if( raw_type == AST__SINTTYPE ){
- raw_size = sizeof( short int );
- if( nel == 0 ) {
- raw = &( ((Entry0S *)mapentry)->value );
- } else {
- raw = ((Entry1S *)mapentry)->value;
- }
-
- } else if( raw_type == AST__BYTETYPE ){
- raw_size = sizeof( unsigned char );
- if( nel == 0 ) {
- raw = &( ((Entry0B *)mapentry)->value );
- } else {
- raw = ((Entry1B *)mapentry)->value;
- }
-
- } else if( raw_type == AST__POINTERTYPE ){
- raw_size = sizeof( void * );
- if( nel == 0 ) {
- raw = &( ((Entry0P *)mapentry)->value );
- } else {
- raw = ((Entry1P *)mapentry)->value;
- }
-
- } else if( raw_type == AST__FLOATTYPE ){
- raw_size = sizeof( float );
- if( nel == 0 ) {
- raw = &( ((Entry0F *)mapentry)->value );
- } else {
- raw = ((Entry1F *)mapentry)->value;
- }
-
- } else if( raw_type == AST__STRINGTYPE ){
- raw_size = sizeof( const char * );
- if( nel == 0 ) {
- raw = &( ((Entry0C *)mapentry)->value );
- } else {
- raw = ((Entry1C *)mapentry)->value;
- }
-
- } else if( raw_type == AST__OBJECTTYPE ){
- raw_size = sizeof( AstObject * );
- if( nel == 0 ) {
- raw = &( ((Entry0A *)mapentry)->value );
- } else {
- raw = ((Entry1A *)mapentry)->value;
- }
-
- } else if( raw_type == AST__UNDEFTYPE ){
- raw_size = 0;
- raw = NULL;
-
- } else {
- raw_size = 0;
- raw = NULL;
- astError( AST__INTER, "astMapGet1A(KeyMap): Illegal map entry data "
- "type %d encountered (internal AST programming error).",
- status, raw_type );
- }
-
-/* Treat scalars as single-value vectors. */
- if( nel == 0 ) nel = 1;
-
-/* Ensure no more than "mxval" values are returned. */
- if( nel > mxval ) nel = mxval;
-
-/* Return the number of values stored in the buffer. */
- *nval = nel;
-
-/* Loop round all values in the vector. */
- for( i = 0; i < nel && astOK; i++ ) {
-
-/* Convert the value, storing the result in the supplied buffer. Report an
- error if conversion is not possible. */
- if( !raw ) {
- result = 0;
-
- } else if( !ConvertValue( raw, raw_type, &avalue, AST__OBJECTTYPE, status ) && astOK ){
- astError( AST__MPGER, "astMapGet1A(%s): The value of "
- "element %d of KeyMap key \"%s\" cannot be read using "
- "the requested data type.", status, astGetClass( this ),
- i + 1, key );
-
-/* If succesful, return an ID value for the Object. */
- } else {
- value[ i ] = avalue ? astMakeId( avalue ) : NULL;
- }
-
-/* Increment the pointers to the next raw value. */
- raw = (char *) raw + raw_size;
- }
-
-/* If the KeyError attribute is non-zero, report an error if the key is not
- found */
- } else if( astGetKeyError( this ) && astOK ) {
- astError( AST__MPKER, "astMapGet1A(%s): No value was found for "
- "%s in the supplied KeyMap.", status, astGetClass( this ),
- key );
- }
-
-/* If an error occurred,return zero. */
- if( !astOK ) result = 0;
-
-/* Return the result.*/
- return result;
-}
-
-/*
-*++
-* Name:
-c astMapGetElem<X>
-f AST_MAPGETELEM<X>
-
-* Purpose:
-* Get a single element of a vector value from a KeyMap.
-
-* Type:
-* Public virtual function.
-
-* Synopsis:
-c #include "ast.h"
-c int astMapGetElem<X>( AstKeyMap *this, const char *key, int elem,
-c <X>type *value )
-c int astMapGetElemC( AstKeyMap *this, const char *key, int l, int elem,
-c char *value )
-f RESULT = AST_MAPGETELEM<X>( THIS, KEY, ELEM, VALUE, STATUS )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This is a set of functions for retrieving a single element of a vector
-* value from a KeyMap. You should replace <X> in the generic function name
-c astMapGetElem<X>
-f AST_MAPGETELEM<X>
-* by an appropriate 1-character type code (see the "Data Type Codes"
-* section below for the code appropriate to each supported data type).
-* The stored value is converted to the data type indiced by <X>
-* before being returned (an error is reported if it is not possible to
-* convert the stored value to the requested data type).
-c Note, the astMapGetElemC function has an extra parameter "l" which
-c specifies the maximum length of the string to be stored in the
-c "value" buffer (see the "astMapGetElemC" section below).
-
-* Parameters:
-c this
-f THIS = INTEGER (Given)
-* Pointer to the KeyMap.
-c key
-f KEY = CHARACTER * ( * ) (Given)
-* The character string identifying the value to be retrieved. Trailing
-* spaces are ignored.
-* The supplied string is converted to upper case before use if the
-* KeyCase attribute is currently set to zero.
-c elem
-f ELEM = INTEGER (Given)
-* The index of the required vector element, starting at
-c zero.
-f one.
-* An error will be reported if the value is outside the range of
-* the vector.
-c value
-f VALUE = <X>type (Returned)
-c A pointer to a buffer in which to return the requested value.
-f The requested value.
-* If the requested key is not found, or if it is found but has an
-* undefined value (see
-c astMapPutU),
-f AST_MAPPUTU),
-* then the contents of the
-* buffer on entry to this function will be unchanged on exit.
-f STATUS = INTEGER (Given and Returned)
-f The global status.
-
-* Returned Value:
-c astMapGetElem<X>()
-f AST_MAPGETELEM<X> = LOGICAL
-c A non-zero value
-f .TRUE.
-* is returned if the requested key name was found, and does not have
-* an undefined value (see
-c astMapPutU). Zero
-f AST_MAPPUTU). .FALSE.
-* is returned otherwise.
-
-* Notes:
-* - No error is reported if the requested key cannot be found in the
-* given KeyMap, or if it has an undefined value, but a
-c zero
-f .FALSE.
-* value will be returned as the function value.
-
-c astMapGetElemC:
-c The "value" buffer supplied to the astMapGetElemC function should be a
-c pointer to a character array with "l" elements, where "l" is the
-c maximum length of the string to be returned. The value of "l"
-c should be supplied as an extra parameter following "key" when
-c invoking astMapGetElemC, and should include space for a terminating
-c null character.
-
-* Data Type Codes:
-* To select the appropriate
-c function, you should replace <X> in the generic function name
-c astMapGetElem<X>
-f routine, you should replace <X> in the generic routine name
-f AST_MAPGETELEM<X>
-* with a 1-character data type code, so as to match the data type <X>type
-* of the data you are processing, as follows:
-c - D: double
-c - F: float
-c - I: int
-c - C: "const" pointer to null terminated character string
-c - A: Pointer to AstObject
-c - P: Generic "void *" pointer
-c - S: short int
-c - B: Unsigned byte (i.e. char)
-f - D: DOUBLE PRECISION
-f - R: REAL
-f - I: INTEGER
-f - C: CHARACTER
-f - A: INTEGER used to identify an AstObject
-f - S: INTEGER*2 (short integer)
-f - B: Unsigned byte
-*
-c For example, astMapGetElemD would be used to get a "double" value, while
-c astMapGetElemI would be used to get an "int" value, etc. For D or I, the
-c supplied "value" parameter should be a pointer to a double or int. For
-c C, the supplied "value" parameter should be a pointer to a character
-c string with "l" elements. For A, the supplied "value" parameter should
-c be a pointer to an AstObject pointer.
-f For example, AST_MAPGETELEMD would be used to get a DOUBLE PRECISION
-f value, while AST_MAPGETELEMI would be used to get an INTEGER value, etc.
-
-*--
-*/
-/* Define a macro to implement the function for a specific data type
-(excluding "C" since that needs an extra parameter). */
-#define MAKE_MAPGETELEM(X,Xtype,Itype) \
-static int MapGetElem##X( AstKeyMap *this, const char *skey, int elem, \
- Xtype *value, int *status ) { \
-\
-/* Local Variables: */ \
- AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */ \
- const char *key; /* Pointer to key string to use */ \
- char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ \
- int itab; /* Index of hash table element to use */ \
- int nel; /* Number of elements in raw vector */ \
- int raw_type; /* Data type of stored value */ \
- int result; /* Returned flag */ \
- size_t raw_size; /* Size of a single raw value */ \
- unsigned long hash; /* Full width hash value */ \
- void *raw; /* Pointer to stored value */ \
-\
-/* Initialise */ \
- result = 0; \
-\
-/* Check the global error status. */ \
- if ( !astOK ) return result; \
-\
-/* Convert the supplied key to upper case if required. */ \
- key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapGetElem" #X, \
- status ); \
-\
-/* Use the hash function to determine the element of the hash table in \
- which the key will be stored. */ \
- itab = HashFun( key, this->mapsize - 1, &hash, status ); \
-\
-/* Search the relevent table entry for the required MapEntry. */ \
- mapentry = SearchTableEntry( this, itab, key, status ); \
-\
-/* Skip rest if the key was not found. */ \
- if( mapentry ) { \
- result = 1; \
-\
-/* Get the address of the first raw value, and its data type. Also get \
- the size of each element of the vector. */ \
- nel = mapentry->nel; \
- raw_type = mapentry->type; \
- if( raw_type == AST__INTTYPE ){ \
- raw_size = sizeof( int ); \
- if( nel == 0 ) { \
- raw = &( ((Entry0I *)mapentry)->value ); \
- } else { \
- raw = ((Entry1I *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__DOUBLETYPE ){ \
- raw_size = sizeof( double ); \
- if( nel == 0 ) { \
- raw = &( ((Entry0D *)mapentry)->value ); \
- } else { \
- raw = ((Entry1D *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__SINTTYPE ){ \
- raw_size = sizeof( short int ); \
- if( nel == 0 ) { \
- raw = &( ((Entry0S *)mapentry)->value ); \
- } else { \
- raw = ((Entry1S *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__BYTETYPE ){ \
- raw_size = sizeof( unsigned char ); \
- if( nel == 0 ) { \
- raw = &( ((Entry0B *)mapentry)->value ); \
- } else { \
- raw = ((Entry1B *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__POINTERTYPE ){ \
- raw_size = sizeof( void * ); \
- if( nel == 0 ) { \
- raw = &( ((Entry0P *)mapentry)->value ); \
- } else { \
- raw = ((Entry1P *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__FLOATTYPE ){ \
- raw_size = sizeof( float ); \
- if( nel == 0 ) { \
- raw = &( ((Entry0F *)mapentry)->value ); \
- } else { \
- raw = ((Entry1F *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__STRINGTYPE ){ \
- raw_size = sizeof( const char * ); \
- if( nel == 0 ) { \
- raw = &( ((Entry0C *)mapentry)->value ); \
- } else { \
- raw = ((Entry1C *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__OBJECTTYPE ){ \
- raw_size = sizeof( AstObject * ); \
- if( nel == 0 ) { \
- raw = &( ((Entry0A *)mapentry)->value ); \
- } else { \
- raw = ((Entry1A *)mapentry)->value; \
- } \
-\
- } else if( raw_type == AST__UNDEFTYPE ){ \
- raw = NULL; \
-\
- } else { \
- raw_size = 0; \
- raw = NULL; \
- astError( AST__INTER, "astMapGetElem<X>(KeyMap): Illegal map entry " \
- "data type %d encountered (internal AST programming " \
- "error).", status, raw_type ); \
- } \
-\
-/* Treat scalars as single-value vectors. */ \
- if( nel == 0 ) nel = 1; \
-\
-/* Ensure the requested element is within the bounds of the vector */ \
- if( elem >= nel || elem < 0 ) { \
- if( astOK ) { \
- astError( AST__MPVIN, "astMapGetElem<X>(KeyMap): Illegal " \
- "zero-based vector index %d supplied for KeyMap " \
- "entry '%s' - the vector has %d elements.", status, \
- elem, key, nel ); \
- } \
-\
-/* Get a pointer to the requested raw value. */ \
- } else if( raw ) { \
- raw = (char *) raw + elem*raw_size; \
-\
-/* Convert the requested value, storing the result in the supplied buffer. \
- Report an error if conversion is not possible. */ \
- if( !ConvertValue( raw, raw_type, value, Itype, status ) && astOK ){ \
- astError( AST__MPGER, "astMapGetElem" #X "(%s): The value of " \
- "element %d of KeyMap key \"%s\" cannot be read using " \
- "the requested data type.", status, astGetClass( this ), \
- elem + 1, key ); \
- } \
- } \
-\
-/* If the KeyError attribute is non-zero, report an error if the key is not \
- found */ \
- } else if( astGetKeyError( this ) && astOK ) { \
- astError( AST__MPKER, "astMapGetElem" #X "(%s): No value was found for " \
- "%s in the supplied KeyMap.", status, astGetClass( this ), \
- key ); \
- } \
-\
-/* If an error occurred,return zero. */ \
- if( !astOK ) result = 0; \
-\
-/* Return the result.*/ \
- return result; \
-}
-
-/* Expand the above macro to generate a function for each required
- data type (except C which is done differently). */
-MAKE_MAPGETELEM(I,int,AST__INTTYPE)
-MAKE_MAPGETELEM(D,double,AST__DOUBLETYPE)
-MAKE_MAPGETELEM(F,float,AST__FLOATTYPE)
-MAKE_MAPGETELEM(A,AstObject *,AST__OBJECTTYPE)
-MAKE_MAPGETELEM(P,void *,AST__POINTERTYPE)
-MAKE_MAPGETELEM(S,short int,AST__SINTTYPE)
-MAKE_MAPGETELEM(B,unsigned char,AST__BYTETYPE)
-
-/* Undefine the macro. */
-#undef MAKE_MAPGETELEM
-
-
-static int MapGetElemC( AstKeyMap *this, const char *skey, int l, int elem,
- char *value, int *status ) {
-/*
-* Name:
-* MapGetElemC
-
-* Purpose:
-* Get a single element of a vector value from a KeyMap.
-
-* Type:
-* Private member function.
-
-* Synopsis:
-* #include "ast.h"
-* int MapGetElemC( AstKeyMap *this, const char *key, int l, int elem,
-* char *value, int *status )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This is the implementation of astMapGetElem<X> for <X> = "C". We
-* cannot use the MAKE_MAPGETELEM macro for this because the string
-* version of this function has an extra parameter giving the maximum
-* length of each string which can be stored in the supplied buffer.
-
-* Parameters:
-* (see astMapGetElem<X>)
-*/
-
-/* Local Variables: */
- AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */
- const char *key; /* Pointer to key string to use */
- char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */
- const char *cvalue; /* Pointer to converted string */
- int itab; /* Index of hash table element to use */
- int nel; /* Number of elements in raw vector */
- int raw_type; /* Data type of stored value */
- int result; /* Returned flag */
- size_t raw_size; /* Size of a single raw value */
- unsigned long hash; /* Full width hash value */
- void *raw; /* Pointer to stored value */
-
-/* Initialise */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Convert the supplied key to upper case if required. */
- key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapGetElemC",
- status );
-
-/* Use the hash function to determine the element of the hash table in
- which the key will be stored. */
- itab = HashFun( key, this->mapsize - 1, &hash, status );
-
-/* Search the relevent table entry for the required MapEntry. */
- mapentry = SearchTableEntry( this, itab, key, status );
-
-/* Skip rest if the key was not found. */
- if( mapentry ) {
- result = 1;
-
-/* Get the address of the first raw value, and its data type. Also get
- the size of each element of the vector. */
- nel = mapentry->nel;
- raw_type = mapentry->type;
- if( raw_type == AST__INTTYPE ){
- raw_size = sizeof( int );
- if( nel == 0 ) {
- raw = &( ((Entry0I *)mapentry)->value );
- } else {
- raw = ((Entry1I *)mapentry)->value;
- }
-
- } else if( raw_type == AST__POINTERTYPE ){
- raw_size = sizeof( void * );
- if( nel == 0 ) {
- raw = &( ((Entry0P *)mapentry)->value );
- } else {
- raw = ((Entry1P *)mapentry)->value;
- }
-
- } else if( raw_type == AST__DOUBLETYPE ){
- raw_size = sizeof( double );
- if( nel == 0 ) {
- raw = &( ((Entry0D *)mapentry)->value );
- } else {
- raw = ((Entry1D *)mapentry)->value;
- }
-
- } else if( raw_type == AST__SINTTYPE ){
- raw_size = sizeof( short int );
- if( nel == 0 ) {
- raw = &( ((Entry0S *)mapentry)->value );
- } else {
- raw = ((Entry1S *)mapentry)->value;
- }
-
- } else if( raw_type == AST__BYTETYPE ){
- raw_size = sizeof( unsigned char );
- if( nel == 0 ) {
- raw = &( ((Entry0B *)mapentry)->value );
- } else {
- raw = ((Entry1B *)mapentry)->value;
- }
-
- } else if( raw_type == AST__FLOATTYPE ){
- raw_size = sizeof( float );
- if( nel == 0 ) {
- raw = &( ((Entry0F *)mapentry)->value );
- } else {
- raw = ((Entry1F *)mapentry)->value;
- }
-
- } else if( raw_type == AST__STRINGTYPE ){
- raw_size = sizeof( const char * );
- if( nel == 0 ) {
- raw = &( ((Entry0C *)mapentry)->value );
- } else {
- raw = ((Entry1C *)mapentry)->value;
- }
-
- } else if( raw_type == AST__OBJECTTYPE ){
- raw_size = sizeof( AstObject * );
- if( nel == 0 ) {
- raw = &( ((Entry0A *)mapentry)->value );
- } else {
- raw = ((Entry1A *)mapentry)->value;
- }
-
- } else if( raw_type == AST__UNDEFTYPE ){
- raw = NULL;
-
- } else {
- raw_size = 0;
- raw = NULL;
- astError( AST__INTER, "astMapGetElemC(KeyMap): Illegal map entry data "
- "type %d encountered (internal AST programming error).", status,
- raw_type );
- }
-
-/* Treat scalars as single-value vectors. */
- if( nel == 0 ) nel = 1;
-
-/* Ensure the requested element is within the bounds of the vector */
- if( elem >= nel || elem < 0 ) {
- if( astOK ) {
- astError( AST__MPVIN, "astMapGetElemC(KeyMap): Illegal vector "
- "index %d supplied for KeyMap entry '%s' - should be "
- "in the range 1 to %d.", status, elem + 1, key, nel + 1 );
- }
-
-/* Get a pointer to the requested raw value. */
- } else if( raw ){
- raw = (char *) raw + elem*raw_size;
-
-/* Convert the value, storing the result in the supplied buffer. Report an
- error if conversion is not possible. */
- if( !ConvertValue( raw, raw_type, &cvalue, AST__STRINGTYPE, status ) && astOK ){
- astError( AST__MPGER, "astMapGetElemC(%s): The value of "
- "element %d of KeyMap key \"%s\" cannot be read using "
- "the requested data type.", status,astGetClass( this ),
- elem + 1, key );
-
-/* If succesful, copy the string into the supplied buffer, or as much of
- it as will fit. Leave room for a trailing null character. */
- } else {
- strncpy( value, cvalue, l - 1 );
- value[ l - 1 ] = 0;
- }
- }
-
-/* If the KeyError attribute is non-zero, report an error if the key is not
- found */
- } else if( astGetKeyError( this ) && astOK ) {
- astError( AST__MPKER, "astMapGetElemC(%s): No value was found for "
- "%s in the supplied KeyMap.", status, astGetClass( this ),
- key );
- }
-
-/* If an error occurred,return zero. */
- if( !astOK ) result = 0;
-
-/* Return the result.*/
- return result;
-}
-
-int astMapGetElemAId_( AstKeyMap *this, const char *skey, int elem,
- AstObject **value, int *status ) {
-/*
-* Name:
-* astMapGetElemAId_
-
-* Purpose:
-* Get a single element of a vector of AstObject pointers from a KeyMap.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "ast.h"
-* int astMapGetElemA( AstKeyMap *this, const char *key, int elem,
-* AstObject **value )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This is the public implementation of the astMapGetElemA function
-* It is identical to astMapGetElemA_ except that an ID value is returned
-* via the "value" parameter instead of a true C pointer. This is required
-* because this conversion cannot be performed by the macro that invokes
-* the function.
-
-* Parameters:
-* (see astMapGet1<X>)
-
-*/
-
-/* Local Variables: */
- AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */
- AstObject *avalue; /* Pointer to AstObject */
- const char *key; /* Pointer to key string to use */
- char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */
- int itab; /* Index of hash table element to use */
- int nel; /* Number of elements in raw vector */
- int raw_type; /* Data type of stored value */
- int result; /* Returned flag */
- size_t raw_size; /* Size of a single raw value */
- unsigned long hash; /* Full width hash value */
- void *raw; /* Pointer to stored value */
-
-/* Initialise */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Convert the supplied key to upper case if required. */
- key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapGetElemA",
- status );
-
-/* Use the hash function to determine the element of the hash table in
- which the key will be stored. */
- itab = HashFun( key, this->mapsize - 1, &hash, status );
-
-/* Search the relevent table entry for the required MapEntry. */
- mapentry = SearchTableEntry( this, itab, key, status );
-
-/* Skip rest if the key was not found. */
- if( mapentry ) {
- result = 1;
-
-/* Get the address of the first raw value, and its data type. Also get
- the size of each element of the vector. */
- nel = mapentry->nel;
- raw_type = mapentry->type;
- if( raw_type == AST__INTTYPE ){
- raw_size = sizeof( int );
- if( nel == 0 ) {
- raw = &( ((Entry0I *)mapentry)->value );
- } else {
- raw = ((Entry1I *)mapentry)->value;
- }
-
- } else if( raw_type == AST__SINTTYPE ){
- raw_size = sizeof( short int );
- if( nel == 0 ) {
- raw = &( ((Entry0S *)mapentry)->value );
- } else {
- raw = ((Entry1S *)mapentry)->value;
- }
-
- } else if( raw_type == AST__BYTETYPE ){
- raw_size = sizeof( unsigned char );
- if( nel == 0 ) {
- raw = &( ((Entry0B *)mapentry)->value );
- } else {
- raw = ((Entry1B *)mapentry)->value;
- }
-
- } else if( raw_type == AST__DOUBLETYPE ){
- raw_size = sizeof( double );
- if( nel == 0 ) {
- raw = &( ((Entry0D *)mapentry)->value );
- } else {
- raw = ((Entry1D *)mapentry)->value;
- }
-
- } else if( raw_type == AST__POINTERTYPE ){
- raw_size = sizeof( void * );
- if( nel == 0 ) {
- raw = &( ((Entry0P *)mapentry)->value );
- } else {
- raw = ((Entry1P *)mapentry)->value;
- }
-
- } else if( raw_type == AST__FLOATTYPE ){
- raw_size = sizeof( float );
- if( nel == 0 ) {
- raw = &( ((Entry0F *)mapentry)->value );
- } else {
- raw = ((Entry1F *)mapentry)->value;
- }
-
- } else if( raw_type == AST__STRINGTYPE ){
- raw_size = sizeof( const char * );
- if( nel == 0 ) {
- raw = &( ((Entry0C *)mapentry)->value );
- } else {
- raw = ((Entry1C *)mapentry)->value;
- }
-
- } else if( raw_type == AST__OBJECTTYPE ){
- raw_size = sizeof( AstObject * );
- if( nel == 0 ) {
- raw = &( ((Entry0A *)mapentry)->value );
- } else {
- raw = ((Entry1A *)mapentry)->value;
- }
-
- } else if( raw_type == AST__UNDEFTYPE ){
- raw = NULL;
-
- } else {
- raw_size = 0;
- raw = NULL;
- astError( AST__INTER, "astMapGetElemA(KeyMap): Illegal map entry data "
- "type %d encountered (internal AST programming error).", status,
- raw_type );
- }
-
-/* Treat scalars as single-value vectors. */
- if( nel == 0 ) nel = 1;
-
-/* Ensure the requested element is within the bounds of the vector */
- if( elem >= nel || elem < 0 ) {
- if( astOK ) {
- astError( AST__MPVIN, "astMapGetElemA(KeyMap): Illegal vector "
- "index %d supplied for KeyMap entry '%s' - should be "
- "in the range 1 to %d.", status, elem + 1, key, nel + 1 );
- }
-
-/* Get a pointer to the requested raw value. */
- } else if( raw ){
- raw = (char *) raw + elem*raw_size;
-
-/* Convert the value, storing the result in the supplied buffer. Report an
- error if conversion is not possible. */
- if( !ConvertValue( raw, raw_type, &avalue, AST__OBJECTTYPE, status ) && astOK ){
- astError( AST__MPGER, "astMapGetElemA(%s): The value of "
- "element %d of KeyMap key \"%s\" cannot be read using "
- "the requested data type.", status,astGetClass( this ),
- elem + 1, key );
-
-/* If succesful, return an ID value for the Object. */
- } else {
- *value = avalue ? astMakeId( avalue ) : NULL;
- }
- }
-
-/* If the KeyError attribute is non-zero, report an error if the key is not
- found */
- } else if( astGetKeyError( this ) && astOK ) {
- astError( AST__MPKER, "astMapGetElemA(%s): No value was found for "
- "%s in the supplied KeyMap.", status, astGetClass( this ),
- key );
- }
-
-/* If an error occurred,return zero. */
- if( !astOK ) result = 0;
-
-/* Return the result.*/
- return result;
-}
-
-static int MapDefined( AstKeyMap *this, const char *skey, int *status ) {
-/*
-*++
-* Name:
-c astMapDefined
-f AST_MAPDEFINED
-
-* Purpose:
-* Check if a KeyMap contains a defined value for a key.
-
-* Type:
-* Public virtual function.
-
-* Synopsis:
-c #include "ast.h"
-c int astMapDefined( AstKeyMap *this, const char *key );
-f RESULT = AST_MAPDEFINED( THIS, KEY, STATUS )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This function checks to see if a KeyMap contains a defined value for
-* a given key. If the key is present in the KeyMap but has an
-* undefined value it returns
-c zero (unlike astMapHasKey which would return non-zero).
-f .FALSE. (unlike AST_MAPHASKEY which would return .TRUE.).
-
-* Parameters:
-c this
-f THIS = INTEGER (Given)
-* Pointer to the KeyMap.
-c key
-f KEY = CHARACTER * ( * ) (Given)
-* The character string identifying the value to be retrieved. Trailing
-* spaces are ignored. The supplied string is converted to upper
-* case before use if the KeyCase attribute is currently set to zero.
-f STATUS = INTEGER (Given and Returned)
-f The global status.
-
-* Returned Value:
-c astMapDefined()
-f AST_MAPDEFINED = LOGICAL
-c A non-zero value
-f .TRUE.
-* is returned if the requested key name is present in the KeyMap
-* and has a defined value.
-
-*--
-*/
-
-/* Local Variables: */
- AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */
- const char *key; /* Pointer to key string to use */
- char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */
- int itab; /* Index of hash table element to use */
- int result; /* Returned flag */
- unsigned long hash; /* Full width hash value */
-
-/* Initialise */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Convert the supplied key to upper case if required. */
- key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapDefined",
- status );
-
-/* Use the hash function to determine the element of the hash table in
- which the key will be stored. */
- itab = HashFun( key, this->mapsize - 1, &hash, status );
-
-/* Search the relevent table entry for the required MapEntry. */
- mapentry = SearchTableEntry( this, itab, key, status );
-
-/* Skip rest if the key was not found. */
- if( mapentry ) {
-
-/* Set the result depending on the entry data type. */
- if( mapentry->type == AST__UNDEFTYPE ){
- result = 0;
- } else {
- result = 1;
- }
-
-/* If the KeyError attribute is non-zero, report an error if the key is not
- found */
- } else if( astGetKeyError( this ) && astOK ) {
- astError( AST__MPKER, "astMapDefined(%s): No value was found for "
- "%s in the supplied KeyMap.", status, astGetClass( this ),
- key );
- }
-
-/* If an error occurred, return zero. */
- if( !astOK ) result = 0;
-
-/* Return the result.*/
- return result;
-}
-
-static int MapHasKey( AstKeyMap *this, const char *skey, int *status ) {
-/*
-*++
-* Name:
-c astMapHasKey
-f AST_MAPHASKEY
-
-* Purpose:
-* Check if an entry with a given key exists in a KeyMap.
-
-* Type:
-* Public virtual function.
-
-* Synopsis:
-c #include "keymap.h"
-c int astMapHasKey( AstKeyMap *this, const char *key )
-f RESULT = AST_MAPHASKEY( THIS, KEY, STATUS )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This function returns a flag indicating if the KeyMap contains an
-* entry with the given key.
-
-* Parameters:
-c this
-f THIS = INTEGER (Given)
-* Pointer to the KeyMap.
-c key
-f KEY = CHARACTER * ( * ) (Given)
-* The character string identifying the KeyMap entry. Trailing spaces are
-* ignored.
-* The supplied string is converted to upper case before use if the
-* KeyCase attribute is currently set to zero.
-f STATUS = INTEGER (Given and Returned)
-f The global status.
-
-* Returned Value:
-c astMapHasKey()
-f AST_MAPHASKEY = LOGICAL
-c Non-zero if the key was found, and zero otherwise.
-f .TRUE. if the key was found, and .FALSE. otherwise.
-
-* Notes:
-c - A non-zero function value
-f - .TRUE.
-* is returned if the key exists but has an undefined value (that is,
-* the returned value does not depend on whether the entry has a
-* defined value or not). See also
-c astMapDefined, which returns zero in such a case.
-f AST_MAPDEFINED, which returns zero in such a case.
-* - A function value of
-c zero
-f .FALSE.
-* will be returned if an error has already occurred, or if this
-* function should fail for any reason.
-
-*--
-*/
-
-/* Local Variables: */
- AstMapEntry *mapentry; /* Pointer to entry in linked list */
- const char *key; /* Pointer to key string to use */
- char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */
- int itab; /* Index of hash table element to use */
- int result; /* Returned value */
- unsigned long hash; /* Full width hash value */
-
-/* Initialise */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Convert the supplied key to upper case if required. */
- key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapHasKey",
- status );
-
-/* Use the hash function to determine the element of the hash table in
- which the key will be stored. */
- itab = HashFun( key, this->mapsize - 1, &hash, status );
-
-/* Search the relevent table entry for the required MapEntry. */
- mapentry = SearchTableEntry( this, itab, key, status );
-
-/* Set a non-zero return value if the key was found. */
- if( mapentry ) result = 1;
-
-/* If an error has occurred, return zero. */
- if( !astOK ) result = 0;
-
-/* Return the result. */
- return result;
-
-}
-
-static void MapRemove( AstKeyMap *this, const char *skey, int *status ) {
-/*
-*++
-* Name:
-c astMapRemove
-f AST_MAPREMOVE
-
-* Purpose:
-* Removed a named entry from a KeyMap.
-
-* Type:
-* Public virtual function.
-
-* Synopsis:
-c #include "keymap.h"
-c void astMapRemove( AstKeyMap *this, const char *key )
-f CALL AST_MAPREMOVE( THIS, KEY, STATUS )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-c This function
-f This routine
-* removes a named entry from a KeyMap. It returns without action if the
-* KeyMap does not contain the specified key.
-
-* Parameters:
-c this
-f THIS = INTEGER (Given)
-* Pointer to the KeyMap.
-c key
-f KEY = CHARACTER * ( * ) (Given)
-* The character string identifying the value to be retrieved. Trailing
-* spaces are ignored.
-* The supplied string is converted to upper case before use if the
-* KeyCase attribute is currently set to zero.
-f STATUS = INTEGER (Given and Returned)
-f The global status.
-*--
-*/
-
-/* Local Variables: */
- const char *key; /* Pointer to key string to use */
- char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */
- int itab; /* Index of hash table element to use */
- unsigned long hash; /* Full width hash value */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Convert the supplied key to upper case if required. */
- key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapRemove",
- status );
-
-/* Use the hash function to determine the element of the hash table in
- which the key will be stored. */
- itab = HashFun( key, this->mapsize - 1, &hash, status );
-
-/* Search the relevent table entry for the required MapEntry and remove it. */
- (void) FreeMapEntry( RemoveTableEntry( this, itab, key, status ), status );
-}
-
-static void MapRename( AstKeyMap *this, const char *soldkey, const char *snewkey,
- int *status ) {
-/*
-*++
-* Name:
-c astMapRename
-f AST_MAPRENAME
-
-* Purpose:
-* Rename an existing KeyMap entry.
-
-* Type:
-* Public virtual function.
-
-* Synopsis:
-c #include "keymap.h"
-c void astMapRename( AstKeyMap *this, const char *oldkey, const char *newkey )
-f CALL AST_MAPRENAME( THIS, OLDKEY, NEWKEY, STATUS )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-c This function
-f This routine
-* associated a new key with an existing entry in a KeyMap. It returns
-* without action if the oldkey does not exist in the KeyMap.
-
-* Parameters:
-c this
-f THIS = INTEGER (Given)
-* Pointer to the KeyMap.
-c oldkey
-f OLDKEY = CHARACTER * ( * ) (Given)
-* The character string identifying the entry to be renamed. Trailing
-* spaces are ignored.
-* The supplied string is converted to upper case before use if the
-* KeyCase attribute is currently set to zero.
-c newkey
-f NEKEY = CHARACTER * ( * ) (Given)
-* The new character string to associated with the renamed entry.
-* Trailing spaces are ignored.
-* The supplied string is converted to upper case before use if the
-* KeyCase attribute is currently set to zero.
-f STATUS = INTEGER (Given and Returned)
-f The global status.
-*--
-*/
-
-/* Local Variables: */
- AstMapEntry *entry; /* Pointer to the entry being renamed */
- AstMapEntry *oldent; /* Pointer to old entry with new name */
- const char *oldkey; /* Pointer to key string to use */
- char oldkeybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */
- const char *newkey; /* Pointer to key string to use */
- char newkeybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */
- char *p; /* Pointer to next key character */
- int itab; /* Index of hash table element to use */
- int keylen; /* Length of supplied key string */
- int keymember; /* Identifier for new key */
- int there; /* Did the entry already exist in the KeyMap? */
- unsigned long hash; /* Full width hash value */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Convert the supplied keys to upper case if required. */
- oldkey = ConvertKey( this, soldkey, oldkeybuf, AST__MXKEYLEN + 1,
- "astMapRename", status );
- newkey = ConvertKey( this, snewkey, newkeybuf, AST__MXKEYLEN + 1,
- "astMapRename", status );
-
-/* Do nothing if the keys are the same. */
- if( strcmp( oldkey, newkey ) ){
-
-/* Use the hash function to determine the element of the hash table in
- which the old key will be stored. */
- itab = HashFun( oldkey, this->mapsize - 1, &hash, status );
-
-/* Search the relevent table entry for the required MapEntry. Remove it
- from the list, but do not free it. */
- entry = RemoveTableEntry( this, itab, oldkey, status );
-
-/* Skip rest if the key was not found. */
- if( entry ) {
-
-/* Store the new key string, and terminate it to exclude any trailing
- spaces. */
- keylen = strlen( newkey );
- entry->key = astStore( (void *) entry->key, newkey, keylen + 1 );
- if( astOK ) {
- p = (char *) entry->key + keylen;
- while( --p >= entry->key ) {
- if( *p == ' ' ) {
- *p = 0;
- } else {
- break;
- }
- }
- }
-
-/* Use the hash function to determine the element of the hash table in
- which to store the entry with its new key. */
- itab = HashFun( entry->key, this->mapsize - 1, &(entry->hash), status );
-
-/* Remove and free any existing entry with the given key from the table
- element. */
- oldent = RemoveTableEntry( this, itab, entry->key, status );
- if( oldent ) {
- keymember = oldent->keymember;
- oldent = FreeMapEntry( oldent, status );
- there = 1;
- } else {
- keymember = -1;
- there = 0;
- }
-
-/* If the KeyMap is locked we report an error if an attempt is made to
- introduce a new key. */
- if( !there && astGetMapLocked( this ) ) {
- astError( AST__BADKEY, "astMapRename(%s): Failed to rename item "
- "\"%s\" in a KeyMap to \"%s\": \"%s\" is not a known "
- "item.", status, astGetClass( this ), oldkey, newkey,
- newkey );
- }
-
-/* If all has gone OK, store the renamed entry at the head of the linked list
- associated with the selected table entry. */
- if( astOK ) {
- entry = AddTableEntry( this, itab, entry, keymember, status );
-
-/* If anything went wrong, try to delete the renamed entry. */
- } else {
- entry = FreeMapEntry( entry, status );
- }
- }
- }
-}
-
-static int MapSize( AstKeyMap *this, int *status ) {
-/*
-*++
-* Name:
-c astMapSize
-f AST_MAPSIZE
-
-* Purpose:
-* Get the number of entries in a KeyMap.
-
-* Type:
-* Public virtual function.
-
-* Synopsis:
-c #include "keymap.h"
-c int astMapSize( AstKeyMap *this )
-f RESULT = AST_MAPSIZE( THIS, STATUS )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This function returns the number of entries in a KeyMap.
-
-* Parameters:
-c this
-f THIS = INTEGER (Given)
-* Pointer to the KeyMap.
-f STATUS = INTEGER (Given and Returned)
-f The global status.
-
-* Returned Value:
-c astMapSize()
-f AST_MAPSIZE = INTEGER
-* The number of entries in the KeyMap.
-
-* Notes:
-* - A function value of zero will be returned if an error has already
-* occurred, or if this function should fail for any reason.
-
-*--
-*/
-
-/* Local Variables: */
- int itab; /* Index of hash table element to use */
- int result; /* Returned value */
-
-/* Initialise */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Add up the number of entries in all elements of the hash table. */
- for( itab = 0; itab < this->mapsize; itab++ ) result += this->nentry[ itab ];
-
-/* Return the result. */
- return result;
-
-}
-
-static int MapLenC( AstKeyMap *this, const char *skey, int *status ) {
-/*
-*++
-* Name:
-c astMapLenC
-f AST_MAPLENC
-
-* Purpose:
-* Get the number of characters in a character entry in a KeyMap.
-
-* Type:
-* Public virtual function.
-
-* Synopsis:
-c #include "keymap.h"
-c int astMapLenC( AstKeyMap *this, const char *key )
-f RESULT = AST_MAPLENC( THIS, KEY, STATUS )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This function returns the minimum length which a character variable
-* which must have in order to be able to store a specified entry in
-* the supplied KeyMap. If the named entry is a vector entry, then the
-* returned value is the length of the longest element of the vector
-* value.
-
-* Parameters:
-c this
-f THIS = INTEGER (Given)
-* Pointer to the KeyMap.
-c key
-f KEY = CHARACTER * ( * ) (Given)
-* The character string identifying the KeyMap entry. Trailing
-* spaces are ignored.
-* The supplied string is converted to upper case before use if the
-* KeyCase attribute is currently set to zero.
-f STATUS = INTEGER (Given and Returned)
-f The global status.
-
-* Returned Value:
-c astMapLenC()
-f AST_MAPLENC = INTEGER
-* The length (i.e. number of characters) of the longest formatted
-* value associated with the named entry.
-c This does not include the trailing null character.
-
-* Notes:
-* - A function value of zero will be returned without error if the
-* named entry cannot be formatted as a character string.
-* - A function value of zero will be returned if an error has already
-* occurred, or if this function should fail for any reason.
-
-*--
-*/
-
-/* Local Variables: */
- AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */
- const char *key; /* Pointer to key string to use */
- char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */
- int i; /* Element index */
- int itab; /* Index of hash table element to use */
- int l; /* Length of formatted vector element */
- int nel; /* Number of elements in raw vector */
- int raw_type; /* Data type of stored value */
- int result; /* Returned value */
- size_t raw_size; /* Size of a single raw value */
- unsigned long hash; /* Full width hash value */
- void *raw; /* Pointer to stored value */
-
-/* Initialise */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Convert the supplied key to upper case if required. */
- key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapLenC",
- status );
-
-/* Use the hash function to determine the element of the hash table in
- which the key will be stored. */
- itab = HashFun( key, this->mapsize - 1, &hash, status );
-
-/* Search the relevent table entry for the required MapEntry. */
- mapentry = SearchTableEntry( this, itab, key, status );
-
-/* Skip rest if the key was not found. */
- if( mapentry ) {
-
-/* Get the address of the first raw value, and its data type. Also get
- the size of each element of the vector. */
- nel = mapentry->nel;
- raw_type = mapentry->type;
- if( raw_type == AST__INTTYPE ){
- raw_size = sizeof( int );
- if( nel == 0 ) {
- raw = &( ((Entry0I *)mapentry)->value );
- } else {
- raw = ((Entry1I *)mapentry)->value;
- }
-
- } else if( raw_type == AST__POINTERTYPE ){
- raw_size = sizeof( void * );
- if( nel == 0 ) {
- raw = &( ((Entry0P *)mapentry)->value );
- } else {
- raw = ((Entry1P *)mapentry)->value;
- }
-
- } else if( raw_type == AST__DOUBLETYPE ){
- raw_size = sizeof( double );
- if( nel == 0 ) {
- raw = &( ((Entry0D *)mapentry)->value );
- } else {
- raw = ((Entry1D *)mapentry)->value;
- }
-
- } else if( raw_type == AST__SINTTYPE ){
- raw_size = sizeof( short int );
- if( nel == 0 ) {
- raw = &( ((Entry0S *)mapentry)->value );
- } else {
- raw = ((Entry1S *)mapentry)->value;
- }
-
- } else if( raw_type == AST__BYTETYPE ){
- raw_size = sizeof( unsigned char );
- if( nel == 0 ) {
- raw = &( ((Entry0B *)mapentry)->value );
- } else {
- raw = ((Entry1B *)mapentry)->value;
- }
-
- } else if( raw_type == AST__FLOATTYPE ){
- raw_size = sizeof( float );
- if( nel == 0 ) {
- raw = &( ((Entry0F *)mapentry)->value );
- } else {
- raw = ((Entry1F *)mapentry)->value;
- }
-
- } else if( raw_type == AST__STRINGTYPE ){
- raw_size = sizeof( const char * );
- if( nel == 0 ) {
- raw = &( ((Entry0C *)mapentry)->value );
- } else {
- raw = ((Entry1C *)mapentry)->value;
- }
-
- } else if( raw_type == AST__OBJECTTYPE ){
- raw_size = sizeof( AstObject * );
- if( nel == 0 ) {
- raw = &( ((Entry0A *)mapentry)->value );
- } else {
- raw = ((Entry1A *)mapentry)->value;
- }
-
- } else if( raw_type == AST__UNDEFTYPE ){
- raw_size = 0;
- raw = NULL;
-
- } else {
- raw_size = 0;
- raw = NULL;
- astError( AST__INTER, "astMapLenC(KeyMap): Illegal map entry data "
- "type %d encountered (internal AST programming error).", status,
- raw_type );
- }
-
-/* Treat scalars as single-value vectors. */
- if( nel == 0 ) nel = 1;
-
-/* Skip undefined values. */
- if( raw ) {
-
-/* Initialise the maximum length of any formatted value in the entry. */
- result= 0;
-
-/* Loop round all values in the vector. */
- for( i = 0; i < nel && astOK; i++ ) {
-
-/* Go through the motions of formatting the value. We do not actually
- need the formatted string (just its length) so we provide a NULL pointer
- for the output buffer. The entry is ignored if it cannot be formatted.
- Note, the length returned by ConvertValue includes the terminating null,
- so decrement it first. */
- l = ConvertValue( raw, raw_type, NULL, AST__STRINGTYPE, status );
- if( --l > result ) result = l;
-
-/* Increment the pointer to the next raw value. */
- raw = (char *) raw + raw_size;
- }
- }
- }
-
-/* If an error has occurred, return zero. */
- if( !astOK ) result = 0;
-
-/* Return the result. */
- return result;
-
-}
-
-static int MapLength( AstKeyMap *this, const char *skey, int *status ) {
-/*
-*++
-* Name:
-c astMapLength
-f AST_MAPLENGTH
-
-* Purpose:
-* Get the vector length of an entry in a KeyMap.
-
-* Type:
-* Public virtual function.
-
-* Synopsis:
-c #include "keymap.h"
-c int astMapLength( AstKeyMap *this, const char *key )
-f RESULT = AST_MAPLENGTH( THIS, KEY, STATUS )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This function returns the vector length of a named entry in a KeyMap,
-* (that is, how many values are associated with the entry).
-
-* Parameters:
-c this
-f THIS = INTEGER (Given)
-* Pointer to the KeyMap.
-c key
-f KEY = CHARACTER * ( * ) (Given)
-* The character string identifying the KeyMap entry. Trailing
-* spaces are ignored.
-* The supplied string is converted to upper case before use if the
-* KeyCase attribute is currently set to zero.
-f STATUS = INTEGER (Given and Returned)
-f The global status.
-
-* Returned Value:
-c astMapLength()
-f AST_MAPLENGTH = INTEGER
-* The length of the entry. One for a scalar, greater than one for
-* a vector. A value of zero is returned if the KeyMap does not
-* contain the named entry.
-
-* Notes:
-* - A function value of zero will be returned if an error has already
-* occurred, or if this function should fail for any reason.
-
-*--
-*/
-
-/* Local Variables: */
- AstMapEntry *mapentry; /* Pointer to entry in linked list */
- const char *key; /* Pointer to key string to use */
- char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */
- int itab; /* Index of hash table element to use */
- int result; /* Returned value */
- unsigned long hash; /* Full width hash value */
-
-/* Initialise */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Convert the supplied key to upper case if required. */
- key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapLength",
- status );
-
-/* Use the hash function to determine the element of the hash table in
- which the key will be stored. */
- itab = HashFun( key, this->mapsize - 1, &hash, status );
-
-/* Search the relevent table entry for the required MapEntry. */
- mapentry = SearchTableEntry( this, itab, key, status );
-
-/* Skip rest if the key was not found. */
- if( mapentry ) {
-
-/* Store the netry length */
- result = mapentry->nel;
-
-/* Return 1 for a scalar. */
- if( result == 0 ) result = 1;
-
- }
-
-/* If an error has occurred, return zero. */
- if( !astOK ) result = 0;
-
-/* Return the result. */
- return result;
-
-}
-
-/*
-*++
-* Name:
-c astMapPutElem<X>
-f AST_MAPPUTELEM<X>
-
-* Purpose:
-* Put a value into an element of a vector value in a KeyMap.
-
-* Type:
-* Public virtual function.
-
-* Synopsis:
-c #include "ast.h"
-c void astMapPutElem<X>( AstKeyMap *this, const char *key, int elem,
-c <X>type *value )
-f CALL AST_MAPPUTELEM<X>( THIS, KEY, ELEM, VALUE, STATUS )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This is a set of functions for storing a value in a single element of
-* a vector value in a KeyMap. You should replace <X> in the generic
-* function name
-c astMapPutElem<X>
-f AST_MAPPUTELEM<X>
-* by an appropriate 1-character type code (see the "Data Type Codes"
-* section below for the code appropriate to each supported data type).
-* The supplied value is converted from the data type indicated by <X>
-* to the data type of the KeyMap entry before being stored (an error
-* is reported if it is not possible to convert the value to the
-* required data type).
-
-* Parameters:
-c this
-f THIS = INTEGER (Given)
-* Pointer to the KeyMap.
-c key
-f KEY = CHARACTER * ( * ) (Given)
-* The character string identifying the value to be retrieved. Trailing
-* spaces are ignored.
-* The supplied string is converted to upper case before use if the
-* KeyCase attribute is currently set to zero.
-c elem
-f ELEM = INTEGER (Given)
-* The index of the vector element to modify, starting at
-c zero.
-f one.
-c value
-f VALUE = <X>type (Given)
-* The value to store.
-f STATUS = INTEGER (Given and Returned)
-f The global status.
-
-* Applicability:
-* KeyMap
-* If the
-c "elem"
-f ELEM
-* index is outside the range of the vector, the length of
-* the vector will be increased by one element and the supplied
-* value will be stored at the end of the vector in the new element.
-* Table
-* If the
-c "elem"
-f ELEM
-* index is outside the range of the vector, an error will be
-* reported. The number of elements in each cell of a column is
-* specified when the column is created using
-c astAddColumn.
-f AST_ADDCOLUMN.
-
-* Notes:
-* - If the entry originally holds a scalar value, it will be treated
-* like a vector entry of length 1.
-* - If the specified key cannot be found in the given KeyMap, or is
-* found but has an undefined value, a new
-* vector entry with the given name, and data type implied by <X>, is
-* created and the supplied value is stored in its first entry.
-
-* Data Type Codes:
-* To select the appropriate
-c function, you should replace <X> in the generic function name
-c astMapPutElem<X>
-f routine, you should replace <X> in the generic routine name
-f AST_MAPPUTELEM<X>
-* with a 1-character data type code, so as to match the data type <X>type
-* of the data you are processing, as follows:
-c - D: double
-c - F: float
-c - I: int
-c - C: "const" pointer to null terminated character string
-c - A: Pointer to AstObject
-c - P: Generic "void *" pointer
-c - S: short int
-c - B: Unsigned byte (i.e. char)
-f - D: DOUBLE PRECISION
-f - R: REAL
-f - I: INTEGER
-f - C: CHARACTER
-f - A: INTEGER used to identify an AstObject
-f - S: INTEGER*2 (short integer)
-f - B: BYTE (unsigned)
-*
-c For example, astMapPutElemD would be used to put a "double" value, while
-c astMapPutElemI would be used to put an "int" value, etc. For D or I, the
-c supplied "value" parameter should be a double or int. For
-c C, the supplied "value" parameter should be a pointer to a character
-c string. For A, the supplied "value" parameter should be an AstObject
-c pointer.
-f For example, AST_MAPPUTELEMD would be used to put a DOUBLE PRECISION
-f value, while AST_MAPPUTELEMI would be used to put an INTEGER value, etc.
-
-*--
-*/
-/* Define a macro to implement the function for a specific data type
-(excluding "C" since that needs an extra parameter). */
-#define MAKE_MAPPUTELEM(X,Xtype,Itype) \
-static void MapPutElem##X( AstKeyMap *this, const char *skey, int elem, \
- Xtype value, int *status ) { \
-\
-/* Local Variables: */ \
- AstMapEntry *mapentry; /* Pointer to parent MapEntry structure */ \
- const char *key; /* Pointer to key string to use */ \
- char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */ \
- int itab; /* Index of hash table element to use */ \
- int nel; /* Number of elements in raw vector */ \
- int new; /* Was a new uninitialised element created? */ \
- int raw_type; /* Data type of stored value */ \
- size_t raw_size; /* Size of a single raw value */ \
- unsigned long hash; /* Full width hash value */ \
- void *raw; /* Pointer to stored value */ \
-\
-/* Check the global error status. */ \
- if ( !astOK ) return; \
-\
-/* Perform any necessary checks on the supplied value to be stored. */ \
- CHECK_##X \
-\
-/* Convert the supplied key to upper case if required. */ \
- key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapPutElem" #X, \
- status ); \
-\
-/* Use the hash function to determine the element of the hash table in \
- which the key will be stored. */ \
- itab = HashFun( key, this->mapsize - 1, &hash, status ); \
-\
-/* Search the relevent table entry for the required MapEntry. */ \
- mapentry = SearchTableEntry( this, itab, key, status ); \
-\
-/* If the key was not found, or was found but has an undefined value, create \
- a new one with a single element, \
- and store the supplied value in it. */ \
- if( !mapentry || mapentry->type == AST__UNDEFTYPE ) { \
- astMapPut1##X( this, key, 1, &value, NULL ); \
-\
-/* If the key was found.... */ \
- } else { \
-\
-/* Get the current length of the vector (0=>scalar), and the data type. */ \
- nel = mapentry->nel; \
- raw_type = mapentry->type; \
-\
-/* Do each data type in turn. */ \
- if( raw_type == AST__INTTYPE ){ \
-\
-/* If the existing entry is scalar, create a new vector entry with the \
- same name, value, data type and comment. Then get a pointer to the new \
- entry, and indicate that we now have a vector entry of length 1. */ \
- if( nel == 0 ) { \
- astMapPut1I( this, key, 1, &( ((Entry0I *)mapentry)->value ), \
- mapentry->comment ); \
- mapentry = SearchTableEntry( this, itab, key, status ); \
- nel = 1; \
- } \
-\
-/* Get the address of the first raw value in the vector. Also get \
- the size of each element of the vector. */ \
- raw = ((Entry1I *)mapentry)->value; \
- raw_size = sizeof( int ); \
-\
-/* Handle other data type in the same way. */ \
- } else if( raw_type == AST__SINTTYPE ){ \
- if( nel == 0 ) { \
- astMapPut1S( this, key, 1, &( ((Entry0S *)mapentry)->value ), \
- mapentry->comment ); \
- mapentry = SearchTableEntry( this, itab, key, status ); \
- nel = 1; \
- } \
- raw = ((Entry1S *)mapentry)->value; \
- raw_size = sizeof( short int ); \
-\
- } else if( raw_type == AST__BYTETYPE ){ \
- if( nel == 0 ) { \
- astMapPut1B( this, key, 1, &( ((Entry0B *)mapentry)->value ), \
- mapentry->comment ); \
- mapentry = SearchTableEntry( this, itab, key, status ); \
- nel = 1; \
- } \
- raw = ((Entry1B *)mapentry)->value; \
- raw_size = sizeof( unsigned char ); \
-\
- } else if( raw_type == AST__DOUBLETYPE ){ \
- if( nel == 0 ) { \
- astMapPut1D( this, key, 1, &( ((Entry0D *)mapentry)->value ), \
- mapentry->comment ); \
- mapentry = SearchTableEntry( this, itab, key, status ); \
- nel = 1; \
- } \
- raw = ((Entry1D *)mapentry)->value; \
- raw_size = sizeof( double ); \
-\
- } else if( raw_type == AST__POINTERTYPE ){ \
- if( nel == 0 ) { \
- astMapPut1P( this, key, 1, &( ((Entry0P *)mapentry)->value ), \
- mapentry->comment ); \
- mapentry = SearchTableEntry( this, itab, key, status ); \
- nel = 1; \
- } \
- raw = ((Entry1P *)mapentry)->value; \
- raw_size = sizeof( void * ); \
-\
- } else if( raw_type == AST__FLOATTYPE ){ \
- if( nel == 0 ) { \
- astMapPut1F( this, key, 1, &( ((Entry0F *)mapentry)->value ), \
- mapentry->comment ); \
- mapentry = SearchTableEntry( this, itab, key, status ); \
- nel = 1; \
- } \
- raw = ((Entry1F *)mapentry)->value; \
- raw_size = sizeof( float ); \
-\
- } else if( raw_type == AST__STRINGTYPE ){ \
- if( nel == 0 ) { \
- astMapPut1C( this, key, 1, &( ((Entry0C *)mapentry)->value ), \
- mapentry->comment ); \
- mapentry = SearchTableEntry( this, itab, key, status ); \
- nel = 1; \
- } \
- raw = ((Entry1C *)mapentry)->value; \
- raw_size = sizeof( const char * ); \
-\
- } else if( raw_type == AST__OBJECTTYPE ){ \
- if( nel == 0 ) { \
- astMapPut1A( this, key, 1, &( ((Entry0A *)mapentry)->value ), \
- mapentry->comment ); \
- mapentry = SearchTableEntry( this, itab, key, status ); \
- nel = 1; \
- } \
- raw = ((Entry1A *)mapentry)->value; \
- raw_size = sizeof( AstObject * ); \
-\
- } else { \
- raw_size = 0; \
- raw = NULL; \
- astError( AST__INTER, "astMapPutElem<X>(KeyMap): Illegal map entry " \
- "data type %d encountered (internal AST programming " \
- "error).", status, raw_type ); \
- } \
-\
-/* If the requested element is outside the bounds of the vector, extend \
- the vector by one element. */ \
- new = ( elem >= nel || elem < 0 ); \
- if( new ) { \
- elem = nel++; \
- raw = astGrow( raw, nel, raw_size ); \
- if( astOK ) { \
- mapentry->nel = nel; \
- if( raw_type == AST__INTTYPE ){ \
- ((Entry1I *)mapentry)->value = (int *) raw; \
- } else if( raw_type == AST__SINTTYPE ){ \
- ((Entry1S *)mapentry)->value = (short int *) raw; \
- } else if( raw_type == AST__BYTETYPE ){ \
- ((Entry1B *)mapentry)->value = (unsigned char *) raw; \
- } else if( raw_type == AST__DOUBLETYPE ){ \
- ((Entry1D *)mapentry)->value = (double *) raw; \
- } else if( raw_type == AST__POINTERTYPE ){ \
- ((Entry1P *)mapentry)->value = (void *) raw; \
- } else if( raw_type == AST__FLOATTYPE ){ \
- ((Entry1F *)mapentry)->value = (float *) raw; \
- } else if( raw_type == AST__STRINGTYPE ){ \
- ((Entry1C *)mapentry)->value = (const char **) raw; \
- } else if( raw_type == AST__OBJECTTYPE ){ \
- ((Entry1A *)mapentry)->value = (AstObject **) raw; \
- } \
- } \
- } \
-\
-/* Get a pointer to the requested element. */ \
- if( astOK ) { \
- raw = (char *) raw + elem*raw_size; \
-\
-/* Free any memory used by the value already in the requested element. */ \
- if( ! new ) { \
- if( raw_type == AST__STRINGTYPE ){ \
- char **cp = (char **) raw; \
- *cp = astFree( *cp ); \
- } else if( raw_type == AST__OBJECTTYPE ){ \
- AstObject **op = (AstObject **) raw; \
- if( *op ) *op = astAnnul( *op ); \
- } \
- } \
-\
-/* Convert the supplied value, storing the result in the requested element. \
- Report an error if conversion is not possible. */ \
- if( !ConvertValue( &value, Itype, raw, raw_type, status ) && astOK ){ \
- astError( AST__MPPER, "astMapPutElem" #X "(%s): The supplied " \
- "value cannot be converted to the data type of " \
- "KeyMap key \"%s\".", status, astGetClass( this ), \
- key ); \
-\
-/* For strings, the "raw" value is a copy of a pointer stored in the global \
- "convertvalue_strings" array. These pointers should never be freed other \
- than within the ConvertValue function (otherwise you can end up with \
- spurious "invalid pointer" errors). But the "raw" value will be freed \
- when as part of the KeyMap when the KeyMap is destroyed. So we replace \
- the "raw" value with a new copy. */ \
- } else if( raw_type == AST__STRINGTYPE ){ \
- char **cp = (char **) raw; \
- *cp = astStore( NULL, *cp, strlen( *cp ) + 1 ); \
- } \
- } \
- } \
-}
-
-/* Define macros which perform any necessary checks on the supplied value
- to be stored. For Object entries, check that we are not adding a KeyMap
- which already contains "this". This avoids circular dependencies.
- Other types do not need any checks. */
-#define CHECK_A CheckCircle( this, value, "astMapPutElemA", status );
-#define CHECK_I
-#define CHECK_B
-#define CHECK_S
-#define CHECK_D
-#define CHECK_F
-#define CHECK_C
-#define CHECK_P
-
-/* Expand the above macro to generate a function for each required
- data type. */
-MAKE_MAPPUTELEM(I,int,AST__INTTYPE)
-MAKE_MAPPUTELEM(D,double,AST__DOUBLETYPE)
-MAKE_MAPPUTELEM(F,float,AST__FLOATTYPE)
-MAKE_MAPPUTELEM(A,AstObject *,AST__OBJECTTYPE)
-MAKE_MAPPUTELEM(P,void *,AST__POINTERTYPE)
-MAKE_MAPPUTELEM(C,const char *,AST__STRINGTYPE)
-MAKE_MAPPUTELEM(S,short int,AST__SINTTYPE)
-MAKE_MAPPUTELEM(B,unsigned char,AST__BYTETYPE)
-
-/* Undefine the macro. */
-#undef MAKE_MAPPUTELEM
-#undef CHECK_A
-#undef CHECK_I
-#undef CHECK_B
-#undef CHECK_S
-#undef CHECK_D
-#undef CHECK_F
-#undef CHECK_C
-#undef CHECK_P
-
-
-static int MapType( AstKeyMap *this, const char *skey, int *status ) {
-/*
-*++
-* Name:
-c astMapType
-f AST_MAPTYPE
-
-* Purpose:
-* Get the data type of an entry in a KeyMap.
-
-* Type:
-* Public virtual function.
-
-* Synopsis:
-c #include "keymap.h"
-c int astMapType( AstKeyMap *this, const char *key )
-f RESULT = AST_MAPTYPE( THIS, KEY, STATUS )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This function returns a value indicating the data type of a
-* named entry in a KeyMap. This is the data type which was used when the
-* entry was added to the KeyMap.
-
-* Parameters:
-c this
-f THIS = INTEGER (Given)
-* Pointer to the KeyMap.
-c key
-f KEY = CHARACTER * ( * ) (Given)
-* The character string identifying the KeyMap entry. Trailing
-* spaces are ignored.
-* The supplied string is converted to upper case before use if the
-* KeyCase attribute is currently set to zero.
-f STATUS = INTEGER (Given and Returned)
-f The global status.
-
-* Returned Value:
-c astMapType()
-f AST_MAPTYPE = INTEGER
-* One of AST__INTTYPE (for integer), AST__SINTTYPE (for
-c short int),
-f INTEGER*2),
-* AST__BYTETYPE (for unsigned bytes
-c - i.e. unsigned chars
-* ) AST__DOUBLETYPE (for double
-* precision floating point), AST__FLOATTYPE (for single
-* precision floating point), AST__STRINGTYPE (for character string),
-* AST__OBJECTTYPE (for AST Object pointer), AST__POINTERTYPE (for
-* arbitrary C pointer) or AST__UNDEFTYPE (for undefined values
-* created by
-c astMapPutU).
-f AST_MAPPUTU).
-* AST__BADTYPE is returned if the supplied key is not found in the KeyMap.
-
-* Notes:
-* - A function value of AST__BADTYPE will be returned if an error has
-* already occurred, or if this function should fail for any reason.
-
-*--
-*/
-
-/* Local Variables: */
- AstMapEntry *mapentry; /* Pointer to entry in linked list */
- const char *key; /* Pointer to key string to use */
- char keybuf[ AST__MXKEYLEN + 1 ]; /* Buffer for upper cas key */
- int itab; /* Index of hash table element to use */
- int result; /* Returned value */
- unsigned long hash; /* Full width hash value */
-
-/* Initialise */
- result = AST__BADTYPE;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Convert the supplied key to upper case if required. */
- key = ConvertKey( this, skey, keybuf, AST__MXKEYLEN + 1, "astMapType",
- status );
-
-/* Use the hash function to determine the element of the hash table in
- which the key will be stored. */
- itab = HashFun( key, this->mapsize - 1, &hash, status );
-
-/* Search the relevent table entry for the required MapEntry. */
- mapentry = SearchTableEntry( this, itab, key, status );
-
-/* Store the type if found. */
- if( mapentry ) result = mapentry->type;
-
-/* If an error has occurred, return zero. */
- if( !astOK ) result = AST__BADTYPE;
-
-/* Return the result. */
- return result;
-
-}
-
-static const char *MapIterate( AstKeyMap *this, int reset, int *status ) {
-/*
-*+
-* Name:
-* astMapIterate
-
-* Purpose:
-* Iterate through the keys in a KeyMap.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "keymap.h"
-* const char *astMapIterate( AstKeyMap *this, int reset, int *status )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* If "reset" is non-zero, this function returns a pointer to a string
-* holding the first key in the KeyMap. On subsequent invocation (if
-* reset is zero) it returns a pointer to the next key in the KeyMap. The
-* context is stored within the KeyMap structure, so calls on different
-* KeyMaps can be mixed.
-*
-* The order in which keys are returned is determined by the KeyMap
-* SortBy attribute.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-* reset
-* If non-zero, return the first key in the KeyMap. Otherwise,
-* returns the key following the one returned by the previous
-* invocation of this function.
-
-* Returned Value:
-* A pointer to the null-terminated string holding the next key,
-* or NULL if there are no more keys in the KeyMap. The returned
-* string should NOT be freed or modified.
-
-* Notes:
-* - A NULL pointer will be returned if this function is invoked
-* with the AST error status set, or if it should fail for any
-* reason.
-*/
-
-/* Local Variables: */
- AstMapEntry *entry; /* Pointer to the entry */
- const char *key; /* Pointer value to return */
- int itab; /* Index into hash table */
- int sortby; /* The value of the SortBy attribute */
-
-/* Initialise. */
- key = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return key;
-
-/* Get the SortBy value. */
- sortby = astGetSortBy( this );
-
-/* First deal with unsorted keys. */
- if( sortby == SORTBY_NONE ) {
-
-/* Get the index of the hash table to check first. Also get a pointer to
- the entry within the hash table to check next. */
- if( reset ){
- itab = 0;
- entry = this->table[ 0 ];
- } else {
- itab = this->iter_itab;
- entry = this->iter_entry;
- }
-
-/* Move through elements of the hash table until we have a non-null entry. */
- while( !entry && ++itab < this->mapsize ) {
- entry = this->table[ itab ];
- }
-
-/* Return a pointer to the key. */
- if( entry ) {
- key = entry->key;
-
-/* Move on to the next entry in the unsorted linked list, saving the context
- in the KeyMap structure. */
- this->iter_itab = itab;
- this->iter_entry = entry->next;
- }
-
-/* Now deal with sorted keys. */
- } else {
-
-/* If starting from the beginning, use the "first" entry. Otherwise, use
- the nxt entry. */
- if( reset ) {
- entry = this->first;
- } else {
- entry = this->iter_entry;
- }
-
-/* If we have an entry, return a pointer to its key, and then update the
- context to point to the next entry in the *sorted* list. */
- if( entry ) {
- key = entry->key;
- this->iter_entry = entry->snext;
- }
- }
-
-/* If no more entries were found, reset the context in the KeyMap
- structure. */
- if( ! key ) {
- this->iter_itab = 0;
- this->iter_entry = NULL;
- }
-
-/* Return the result.*/
- return key;
-}
-
-static void NewTable( AstKeyMap *this, int size, int *status ){
-/*
-* Name:
-* NewTable
-
-* Purpose:
-* Create a new hash table.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* void NewTable( AstKeyMap *this, int size, int *status )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function removes any existing hash table and allocates memory
-* for a new one of the specified size (except that the supplied size
-* is modified to be the next higher power of 2). The table is
-* initialised to indicate that it is empty.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-* size
-* The reuqired size of the hash table.
-* status
-* Pointer to the inherited status variable.
-
-*/
-
-/* Local Variables: */
- int i;
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Ensure the table size is at least MIN_TABLE_SIZE and is a power of 2. */
- if( size <= MIN_TABLE_SIZE ) {
- size = MIN_TABLE_SIZE;
- } else {
- size = (int) ( 0.5 + pow( 2.0, ceil( log( size )/log( 2.0 ) ) ) );
- }
-
-/* Remove any existing entries. */
- for( i = 0; i < this->mapsize; i++ ) FreeTableEntry( this, i, status );
-
-/* Do nothing more if the table size is not changing. */
- if( size != this->mapsize ) {
-
-/* Modify the size of the existing table. */
- this->mapsize = size;
- this->table = astGrow( this->table, size, sizeof( AstMapEntry * ) );
- this->nentry = astGrow( this->nentry, size, sizeof( int ) );
-
-/* Initialise the new table. */
- if( astOK ) {
- for( i = 0; i < size; i++ ) {
- this->table[ i ] = NULL;
- this->nentry[ i ] = 0;
- }
- }
- }
-}
-
-static void RemoveFromObjectList( AstKeyMap *this, AstMapEntry *entry,
- int *status ){
-/*
-* Name:
-* RemoveFromObjectList
-
-* Purpose:
-* Remove an entry from the linked-list of AST__OBJECTTYPE entries.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* void RemoveFromObjectList( AstKeyMap *this, AstMapEntry *entry,
-* int *status )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function removes the supplied MapEntry from the linked list of
-* AST__OBJECTTYPE entries.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-* entry
-* Pointer to the MapEntry to be removed.
-* status
-* Pointer to the inherited status variable.
-
-*/
-
-/* Local Variables: */
- AstMapEntry *a; /* Previous entry */
- AstMapEntry *b; /* Next entry */
- Entry0A *scalar; /* Pointer to a scalar AST__OBJECTTYPE entry */
- Entry1A *vector; /* Pointer to a vector AST__OBJECTTYPE entry */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Do nothing if the entry does not hold AST Object pointers. */
- if( entry->type == AST__OBJECTTYPE ) {
-
-/* Get pointers to the MapEntries before and after the entry being
- removed. At the same time, nullify both pointers in the entry itself. */
- if( entry->nel == 0 ) {
- scalar = (Entry0A *) entry;
- a = scalar->prev;
- b = scalar->next;
- scalar->prev = NULL;
- scalar->next = NULL;
- } else {
- vector = (Entry1A *) entry;
- a = vector->prev;
- b = vector->next;
- vector->prev = NULL;
- vector->next = NULL;
- }
-
-/* Set the forward link in the previous entry. */
- if( a ) {
- if( a->nel == 0 ) {
- scalar = (Entry0A *) a;
- scalar->next = b;
- } else {
- vector = (Entry1A *) a;
- vector->next = b;
- }
-
-/* If we are removing the list head, store the following entry as the new head. */
- } else {
- this->firstA = b;
- }
-
-/* Set the backward link in the next entry. */
- if( b ) {
- if( b->nel == 0 ) {
- scalar = (Entry0A *) b;
- scalar->prev = a;
- } else {
- vector = (Entry1A *) b;
- vector->prev = a;
- }
- }
- }
-}
-
-static void RemoveFromSortedList( AstKeyMap *this, AstMapEntry *entry,
- int *status ){
-/*
-* Name:
-* RemoveFromSortedList
-
-* Purpose:
-* Remove an entry from the linked-list of sorted KeyMap entries.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* void RemoveFromSortedList( AstKeyMap *this, AstMapEntry *entry,
-* int *status )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function removes the supplied MapEntry from the linked list of
-* sorted MapEntries.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-* entry
-* Pointer to the MapEntry to be removed.
-* status
-* Pointer to the inherited status variable.
-
-*/
-
-/* Local Variables: */
- AstMapEntry *next; /* Next higher MapEntry */
- AstMapEntry *prev; /* Next lower MapEntry */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Get pointers to the entries on either side of the entry to be removed. */
- next = entry->snext;
- prev = entry->sprev;
-
-/* If the entry is not in the sorted list, abort. */
- if( next && prev ) {
-
-/* Connect the previous to the next, bypassing the entry being removed. */
- next->sprev = prev;
- prev->snext = next;
-
-/* NULLify the next and previous entries stored in the entry being
- removed. */
- entry->snext = NULL;
- entry->sprev = NULL;
-
-/* Decrement the number of entries in the sorted list. */
- (this->nsorted)--;
-
-/* If the entry being removed is the first entry, store a pointer to the new
- first entry. */
- if( this->nsorted == 0 ) {
- this->first = NULL;
- } else if( entry == this->first ) {
- this->first = next;
- }
- }
-}
-
-static AstMapEntry *RemoveTableEntry( AstKeyMap *this, int itab,
- const char *key, int *status ){
-/*
-* Name:
-* RemoveTableEntry
-
-* Purpose:
-* Remove an entry from a linked-list of KeyMap entries.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* AstMapEntry *RemoveTableEntry( AstKeyMap *this, int itab,
-* const char *key, int *status )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function removes any entries with the specified key from the
-* linked-list of entries stored at the specified entry of the hash
-* table. If the supplied key is found in the list, a pointer to the
-* first removed entry is returned. Otherwise, a NULL pointer is returned.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-* itab
-* Index of the hash table element to be searched.
-* key
-* The key string to be searched for. Trailing spaces are ignored.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Pointer to the removed Entry, or NULL if no matching entry found.
-
-*/
-
-/* Local Variables: */
- AstMapEntry **link; /* Address to store foward link */
- AstMapEntry *next; /* Pointer to next Entry to copy */
- AstMapEntry *result;
-
-/* Initialise */
- result = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* The "next" variable holds the address of the next MapEntry to be
- checked. Initialise this to the MapEntry at the head of the linked
- list associated with the supplied element of the hash table. */
- next = this->table[ itab ];
-
-/* The "link" variable holds the address of the location at which the
- pointer to the MapEntry following the removed MapEntry should be stored.
- Initialise this to be the address of the hash table element. */
- link = &( this->table[ itab ] );
-
-/* Loop round until we have checked all entries. */
- while( next && astOK ) {
-
-/* If the key for the current entry macthes the supplied key... */
- if( !KeyCmp( next->key, key ) ) {
-
-/* Remove the MapEntry from the list sorted by key. */
- RemoveFromSortedList( this, next, status );
-
-/* If the entry is of type AST__OBJECTTYPE, remove it from the
- list of AST__OBJECTTYPE entries. */
- RemoveFromObjectList( this, next, status );
-
-/* Store a pointer to the next MapEntry in the list, replacing the
- original pointer to the MapEntry which is being deleted. */
- *link = next->next;
-
-/* Return a pointer to the first matching MapEntry. Free any subsequent
- matching MapEntries. */
- if( result ) {
- FreeMapEntry( next, status );
- } else {
- result = next;
- }
-
-/* Decrement the number of entries in the linked list. */
- this->nentry[ itab ]--;
-
-/* Set up the next MapEntry to be freed. */
- next = *link;
-
-/* If the key for the current entry does not match the supplied key... */
- } else {
-
-/* Update the address at which to store the pointer to the next MapEntry
- in the list. */
- link = &(next->next);
-
-/* Update the address of the next MapEntry in the list. */
- next = next->next;
- }
- }
-
-/* Return the result */
- return result;
-}
-
-static AstMapEntry *SearchTableEntry( AstKeyMap *this, int itab, const char *key, int *status ){
-/*
-* Name:
-* SearchTableEntry
-
-* Purpose:
-* Search an element of a has table for a given key.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* AstMapEntry *SearchTableEntry( AstKeyMap *this, int itab, const char *key, int *status )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function searches the specified element of the KeyMaps hash table
-* until an element is found which has a key matching the supplied key.
-* The address of this entry is returned. If no suitable entry is found,
-* then NULL is returned.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-* itab
-* The index of the hash table to be searched.
-* key
-* The key string to be searched for. Trailing spaces are ignored.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The address of the first MapEntry in the linked list which refers
-* to the given key, or NULL if the key is not found.
-
-*/
-
-/* Local Variables: */
- AstMapEntry *next; /* Pointer to next Entry to check */
- AstMapEntry *result; /* Returned pointer */
-
-/* Initialise */
- result = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* The "next" variable holds the address of the next MapEntry to be
- checked. Initialise this to the supplied MapEntry. */
- next = this->table[ itab ];
-
-/* Loop round until we have checked all entries. */
- while( next ) {
-
-/* If the key for the current entry matches the supplied key, store the
- MapEntry pointer and break. */
- if( !KeyCmp( next->key, key ) ) {
- result = next;
- break;
- }
-
-/* Update the address of the next MapEntry in the list. */
- next = next->next;
-
- }
-
-/* Return the result. */
- return result;
-}
-
-static void SetAttrib( AstObject *this_object, const char *setting, int *status ) {
-/*
-* Name:
-* SetAttrib
-
-* Purpose:
-* Set an attribute value for a KeyMap.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* void SetAttrib( AstObject *this, const char *setting )
-
-* Class Membership:
-* KeyMap member function (over-rides the astSetAttrib protected
-* method inherited from the Mapping class).
-
-* Description:
-* This function assigns an attribute value for a KeyMap, 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 KeyMap.
-* setting
-* Pointer to a null-terminated string specifying the new attribute
-* value.
-*/
-
-/* Local Variables: */
- AstKeyMap *this; /* Pointer to the KeyMap structure */
- int ival; /* Attribute value */
- int len; /* Length of setting string */
- int nc; /* Number of characters read by astSscanf */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the KeyMap structure. */
- this = (AstKeyMap *) 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. */
-
-/* SizeGuess. */
-/* ---------- */
- if ( nc = 0,
- ( 1 == astSscanf( setting, "sizeguess= %d %n", &ival, &nc ) )
- && ( nc >= len ) ) {
- astSetSizeGuess( this, ival );
-
-/* KeyCase. */
-/* --------- */
- } else if ( nc = 0,
- ( 1 == astSscanf( setting, "keycase= %d %n", &ival, &nc ) )
- && ( nc >= len ) ) {
- astSetKeyCase( this, ival );
-
-/* KeyError. */
-/* --------- */
- } else if ( nc = 0,
- ( 1 == astSscanf( setting, "keyerror= %d %n", &ival, &nc ) )
- && ( nc >= len ) ) {
- astSetKeyError( this, ival );
-
-/* MapLocked. */
-/* --------- */
- } else if ( nc = 0,
- ( 1 == astSscanf( setting, "maplocked= %d %n", &ival, &nc ) )
- && ( nc >= len ) ) {
- astSetMapLocked( this, ival );
-
-/* SortBy. */
-/* ------- */
- } else if ( nc = 0,
- ( 0 == astSscanf( setting, "sortby= %n%*s %n", &ival, &nc ) )
- && ( nc >= len ) ) {
- astSetSortBy( this, SortByInt( setting + ival, "astSetAttrib", status ) );
-
-/* 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 SetKeyCase( AstKeyMap *this, int keycase, int *status ) {
-/*
-*+
-* Name:
-* astSetKeyCase
-
-* Purpose:
-* Set the value of the KeyCase attribute for a KeyMap.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "keymap.h"
-* void astSetKeyCase( AstKeyMap *this, int keycase )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This function sets a new value for the KeyCase attribute of a
-* KeyMap. It reports an error if the KeyMap contains any entries.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-* keycase
-* The new attribute value.
-
-*-
-*/
-
-/* Local Variables: */
- int ok; /* Can the KeyCase value be changed? */
- int itab; /* Index into hash table */
- int newval; /* New KeyCase value */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Normalise the new value */
- newval = keycase ? 1 : 0;
-
-/* If the KeyCase value is to be changed, see if the KeyMap is empty. */
- ok = 1;
- if( astGetKeyCase( this ) != newval ) {
- for( itab = 0; itab < this->mapsize; itab++ ) {
- if( this->nentry[ itab ] > 0 ) {
- ok = 0;
- break;
- }
- }
- }
-
-/* If not report an error. */
- if( !ok ) {
- astError( AST__NOWRT, "astSetAttrib(KeyMap): Illegal attempt to "
- "change the KeyCase attribute of a non-empty KeyMap." , status);
-
-/* Otherwise, store the new value. */
- } else {
- this->keycase = newval;
- }
-}
-
-static void SetKeyError( AstKeyMap *this, int keyerror, int *status ) {
-/*
-*+
-* Name:
-* astSetKeyError
-
-* Purpose:
-* Set the value of the KeyError attribute for a KeyMap.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "keymap.h"
-* void astSetKeyError( AstKeyMap *this, int keyerror )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This function sets the value of the KeyError attribute for a
-* KeyMap. It also sets the attribute recursively in any KeyMaps
-* contained within the supplied KeyMap.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-* keyerror
-* The new value for the attribute.
-*-
-*/
-
-/* Local Variables: */
- AstMapEntry *next; /* Pointer to next Entry to copy */
- AstObject **obj_list; /* List of pointers to AST Object entries */
- int i; /* Index into hash table */
- int iel; /* Index of current vector element */
- int nel; /* Number of elements in vector */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Set the KeyError value in the supplied KeyMap. */
- this->keyerror = keyerror ? 1 : 0;
-
-/* Loop round each entry in the hash table. */
- for( i = 0; i < this->mapsize; i++ ) {
-
-/* Get a pointer to the next KeyMap entry. */
- next = this->table[ i ];
-
-/* Loop round all entries in this element of the hash table. */
- while( next && astOK ) {
-
-/* If this entry has an Object data type, see if holds any KeyMaps. */
- if( next->type == AST__OBJECTTYPE ) {
-
-/* Get the number of objects to check, and a pointer to the first. */
- nel = next->nel;
- if( nel == 0 ) {
- obj_list = &( ((Entry0A *)next)->value );
- nel = 1;
- } else {
- obj_list = ((Entry1A *)next)->value;
- }
-
-/* Loop round checking all Objects. */
- for( iel = 0; iel < nel; iel++ ) {
-
-/* If this Object is a KeyMap, set its KeyError attribute. */
- if( astIsAKeyMap( obj_list[ iel ] ) ) {
- astSetKeyError( (AstKeyMap *) obj_list[ iel ], keyerror );
- }
- }
- }
-
-/* Get a pointer to the next entry. */
- next = next->next;
- }
- }
-}
-
-static void SetMapLocked( AstKeyMap *this, int maplocked, int *status ) {
-/*
-*+
-* Name:
-* astSetMapLocked
-
-* Purpose:
-* Set the value of the MapLocked attribute for a KeyMap.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "keymap.h"
-* void astSetMapLocked( AstKeyMap *this, int maplocked )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This function sets the value of the MapLocked attribute for a
-* KeyMap. It also sets the attribute recursively in any KeyMaps
-* contained within the supplied KeyMap.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-* maplocked
-* The new value for the attribute.
-*-
-*/
-
-/* Local Variables: */
- AstMapEntry *next; /* Pointer to next Entry to copy */
- AstObject **obj_list; /* List of pointers to AST Object entries */
- int i; /* Index into hash table */
- int iel; /* Index of current vector element */
- int nel; /* Number of elements in vector */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Set the MapLocked value in the supplied KeyMap. */
- this->maplocked = maplocked ? 1 : 0;
-
-/* Loop round each entry in the hash table. */
- for( i = 0; i < this->mapsize; i++ ) {
-
-/* Get a pointer to the next KeyMap entry. */
- next = this->table[ i ];
-
-/* Loop round all entries in this element of the hash table. */
- while( next && astOK ) {
-
-/* If this entry has an Object data type, see if holds any KeyMaps. */
- if( next->type == AST__OBJECTTYPE ) {
-
-/* Get the number of objects to check, and a pointer to the first. */
- nel = next->nel;
- if( nel == 0 ) {
- obj_list = &( ((Entry0A *)next)->value );
- nel = 1;
- } else {
- obj_list = ((Entry1A *)next)->value;
- }
-
-/* Loop round checking all Objects. */
- for( iel = 0; iel < nel; iel++ ) {
-
-/* If this Object is a KeyMap, set its MapLocked attribute. */
- if( astIsAKeyMap( obj_list[ iel ] ) ) {
- astSetMapLocked( (AstKeyMap *) obj_list[ iel ], maplocked );
- }
- }
- }
-
-/* Get a pointer to the next entry. */
- next = next->next;
- }
- }
-}
-
-static void SetSizeGuess( AstKeyMap *this, int sizeguess, int *status ) {
-/*
-*+
-* Name:
-* astSetSizeGuess
-
-* Purpose:
-* Set the value of the SizeGuess attribute for a KeyMap.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "keymap.h"
-* void astSetSizeGuess( AstKeyMap *this, int sizeguess )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This function sets a new value for the SizeGuess attribute of a
-* KeyMap. It reports an error if the KeyMap contains any entries.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-* sizeguess
-* The new attribute value.
-
-*-
-*/
-
-/* Local Variables: */
- int empty; /* Is the KeyMap empty? */
- int itab; /* Index into hash table */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* See if the KeyMap is empty. */
- empty = 1;
- for( itab = 0; itab < this->mapsize; itab++ ) {
- if( this->nentry[ itab ] > 0 ) {
- empty = 0;
- break;
- }
- }
-
-/* If not report an error. */
- if( !empty ) {
- astError( AST__NOWRT, "astSetAttrib(KeyMap): Illegal attempt to "
- "change the SizeGuess attribute of a non-empty KeyMap." , status);
-
-/* Otherwise, store the new value and change the size of the hash
- table. */
- } else {
- this->sizeguess = sizeguess;
- NewTable( this, sizeguess/MAX_ENTRIES_PER_TABLE_ENTRY, status );
- }
-}
-
-static void SetSortBy( AstKeyMap *this, int sortby, int *status ) {
-/*
-*+
-* Name:
-* astSetSortBy
-
-* Purpose:
-* Set the value of the SortBy attribute for a KeyMap.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "keymap.h"
-* void astSetSortBy( AstKeyMap *this, int sortby )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This function sets the value of the SortBy attribute for a
-* KeyMap.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-* sortby
-* The new value for the attribute.
-*-
-*/
-
-/* Local Variables: */
- int oldval; /* The old sortby value */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Get the old SortBy value. */
- oldval = astGetSortBy( this );
-
-/* Set the new SortBy value. */
- this->sortby = sortby;
-
-/* If the value has changed, re-sort the keys. */
- if( oldval != sortby ) SortEntries( this, status );
-
-}
-
-static size_t SizeOfEntry( AstMapEntry *entry, int *status ){
-/*
-* Name:
-* SizeOfEntry
-
-* Purpose:
-* Return the size of the supplied MapEntry structure.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* size_t SizeOfEntry( AstMapEntry *entry, int *status )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function returns the size of the supplied MapEntry structure.
-
-* Parameters:
-* entry
-* Pointer to the MapEntry.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The size of the MapEntry structure. This does not include the size
-* of any data for which pointers are stored in the MapEntry structure.
-
-* 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: */
- size_t result; /* Returned value */
- int nel; /* Entry length */
- int type; /* Data type */
-
-/* Initialise. */
- result = 0;
-
-/* Check the global error status and the supplied pointer. */
- if ( !astOK || !entry ) return result;
-
-/* Get the data type and length of the MapEntry. */
- type = entry->type;
- nel = entry->nel;
-
-/* Deal with each type. */
- if( type == AST__STRINGTYPE ) {
- result = ( nel == 0 ) ? sizeof( Entry0C ) : sizeof( Entry1C );
-
- } else if( type == AST__OBJECTTYPE ) {
- result = ( nel == 0 ) ? sizeof( Entry0A ) : sizeof( Entry1A );
-
- } else if( type == AST__INTTYPE ) {
- result = ( nel == 0 ) ? sizeof( Entry0I ) : sizeof( Entry1I );
-
- } else if( type == AST__POINTERTYPE ) {
- result = ( nel == 0 ) ? sizeof( Entry0P ) : sizeof( Entry1P );
-
- } else if( type == AST__SINTTYPE ) {
- result = ( nel == 0 ) ? sizeof( Entry0S ) : sizeof( Entry1S );
-
- } else if( type == AST__BYTETYPE ) {
- result = ( nel == 0 ) ? sizeof( Entry0B ) : sizeof( Entry1B );
-
- } else if( type == AST__DOUBLETYPE ) {
- result = ( nel == 0 ) ? sizeof( Entry0D ) : sizeof( Entry1D );
-
- } else if( type == AST__FLOATTYPE ) {
- result = ( nel == 0 ) ? sizeof( Entry0F ) : sizeof( Entry1F );
-
- } else if( type == AST__UNDEFTYPE ) {
- result = sizeof( AstMapEntry );
-
-/* Report an error if the data type is unknown. */
- } else {
- astError( AST__INTER, "SizeOfEntry(KeyMap): Illegal map entry data "
- "type %d encountered (internal AST programming error).", status,
- type );
- }
-
-/* Return the result. */
- return result;
-}
-
-static int SortByInt( const char *sortby, const char *method, int *status ){
-/*
-* Name:
-* SortByInt
-
-* Purpose:
-* Get the integer associated with a string SortBy value.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* int SortByInt( const char *sortby, const char *method, int *status )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function returns the integer associated with the supplied
-* string SortBy value.
-
-* Parameters:
-* sortby
-* Pointer to the string SortBy value (case insensitive).
-* method
-* Pointer to a string holding the name of the calling method for
-* inclusion in error messages.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The associated SortBy integer.
-
-*/
-
-/* Local Variables: */
- int result; /* The returned integer */
-
-/* Initialise. */
- result = SORTBY_NONE;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Check each known value. */
- if( astChrMatch( sortby, "None" ) ) {
- result = SORTBY_NONE;
-
- } else if( astChrMatch( sortby, "AgeUp" ) ) {
- result = SORTBY_AGEUP;
-
- } else if( astChrMatch( sortby, "AgeDown" ) ) {
- result = SORTBY_AGEDOWN;
-
- } else if( astChrMatch( sortby, "KeyAgeUp" ) ) {
- result = SORTBY_KEYAGEUP;
-
- } else if( astChrMatch( sortby, "KeyAgeDown" ) ) {
- result = SORTBY_KEYAGEDOWN;
-
- } else if( astChrMatch( sortby, "KeyUp" ) ) {
- result = SORTBY_KEYUP;
-
- } else if( astChrMatch( sortby, "KeyDown" ) ) {
- result = SORTBY_KEYDOWN;
-
- } else {
- astError( AST__INTER, "%s(KeyMap): Illegal SortBy value %s "
- "encountered.", status, method, sortby );
- }
-
-/* Return the result. */
- return result;
-}
-
-static const char *SortByString( int sortby, const char *method, int *status ){
-/*
-* Name:
-* SortByString
-
-* Purpose:
-* Get the string associated with an integer SortBy value.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* const char *SortByString( int sortby, const char *method, int *status )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function returns the string associated with the supplied
-* integer SortBy value.
-
-* Parameters:
-* sortby
-* The integer SortBy value.
-* method
-* Pointer to a string holding the name of the calling method for
-* inclusion in error messages.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Pointer to the associated SortBy string.
-
-*/
-
-/* Local Variables: */
- const char *result; /* The returned string */
-
-/* Initialise. */
- result = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Check each value. */
- if( sortby == SORTBY_NONE ) {
- result = "None";
-
- } else if( sortby == SORTBY_AGEUP ) {
- result = "AgeUp";
-
- } else if( sortby == SORTBY_AGEDOWN ) {
- result = "AgeDown";
-
- } else if( sortby == SORTBY_KEYAGEUP ) {
- result = "KeyAgeUp";
-
- } else if( sortby == SORTBY_KEYAGEDOWN ) {
- result = "KeyAgeDown";
-
- } else if( sortby == SORTBY_KEYUP ) {
- result = "KeyUp";
-
- } else if( sortby == SORTBY_KEYDOWN ) {
- result = "KeyDown";
-
- } else {
- astError( AST__INTER, "%s(KeyMap): Illegal integer SortBy value %d "
- "encountered (internal AST programming error).", status,
- method, sortby );
- }
-
-/* Return the result. */
- return result;
-}
-
-static void SortEntries( AstKeyMap *this, int *status ){
-/*
-* Name:
-* SortEntries
-
-* Purpose:
-* Ensure the entries in a KeyMap are sorted correctly.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* void SortEntries( AstKeyMap *this, int *status )
-
-* Class Membership:
-* KeyMap member function.
-
-* Description:
-* This function sorts all the entries in the supplied KeyMap in
-* the manner indicated by the SortBy attribute value in the KeyMap.
-* A double linked list is maintained indicating the ordering, with
-* the first entry in the sorted list being pointed to by "this->first".
-* Each entry contains "snext" and "sprev" pointers that point to the
-* next and previous entries in the sorted list. The number of entries
-* in the sorted list (which should usually equal the total number of
-* entries currently in the KeyMap), is stored in "this->nsorted".
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-* status
-* Pointer to the inherited status variable.
-
-*/
-
-/* Local Variables: */
- AstMapEntry **ents;
- AstMapEntry **pent;
- AstMapEntry **a;
- AstMapEntry **b;
- AstMapEntry *entry;
- int i;
- int nent;
- int sortby;
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Empty the sorted list. */
- this->nsorted = 0;
- this->first = NULL;
-
-/* Get the SortBy value. */
- sortby = astGetSortBy( this );
-
-/* Do nothing more if no sorting is required. */
- if( sortby != SORTBY_NONE ) {
-
-/* Get the number of entries in the keyMap. */
- nent = astMapSize( this );
-
-/* Only sort if the KeyMap is not empty. */
- if( nent > 0 ) {
-
-/* Allocate an array with one element for each entry. Each element is a
- pointer to a MapEntry structure. */
- ents = astMalloc( sizeof( *ents )*nent );
- if( astOK ) {
-
-/* Loop round all entries in the hash table. */
- pent = ents;
- for( i = 0; i < this->mapsize; i++ ) {
-
-/* Get a pointer to the next KeyMap entry. */
- entry = this->table[ i ];
-
-/* Loop round all entries in this element of the hash table. */
- while( entry ) {
-
-/* Store the sorting method in the MapEntry. */
- entry->sortby = sortby;
-
-/* Put a pointer to the MapEntry into the array. */
- *(pent++) = entry;
-
-/* Update the address of the next MapEntry in the source. */
- entry = entry->next;
- }
- }
-
-/* No need for sorting if there is only one entry. */
- if( nent == 1 ) {
- ents[ 0 ]->snext = ents[ 0 ];
- ents[ 0 ]->sprev = ents[ 0 ];
-
-/* Sort the array of pointers if there is more than one entry... */
- } else {
- qsort( ents, nent, sizeof( *ents ), CompareEntries );
-
-/* Establish the double linked list. */
- a = ents;
- b = ents + 1;
- for( i = 1; i < nent; i++ ) {
- (*b)->sprev = *a;
- (*a)->snext = *b;
- a = b++;
- }
-
- b = ents;
- (*b)->sprev = *a;
- (*a)->snext = *b;
-
- }
-
-/* Store a pointer to the first entry in the sorted list. */
- this->first = ents[ 0 ];
-
-/* Store the number of entrie sin the sorted list. */
- this->nsorted = nent;
- }
-
-/* Free resources. */
- ents = astFree( ents );
- }
- }
-}
-
-static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) {
-/*
-* Name:
-* TestAttrib
-
-* Purpose:
-* Test if a specified attribute value is set for a KeyMap.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* int TestAttrib( AstObject *this, const char *attrib, int *status )
-
-* Class Membership:
-* KeyMap member function (over-rides the astTestAttrib protected
-* method inherited from the Mapping class).
-
-* Description:
-* This function returns a boolean result (0 or 1) to indicate whether
-* a value has been set for one of a KeyMap's attributes.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-* 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: */
- AstKeyMap *this; /* Pointer to the KeyMap structure */
- int result; /* Result value to return */
-
-/* Initialise. */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the KeyMap structure. */
- this = (AstKeyMap *) this_object;
-
-/* Check the attribute name and test the appropriate attribute. */
-
-/* SizeGuess. */
-/* ---------- */
- if ( !strcmp( attrib, "sizeguess" ) ) {
- result = astTestSizeGuess( this );
-
-/* KeyCase. */
-/* --------- */
- } else if ( !strcmp( attrib, "keycase" ) ) {
- result = astTestKeyCase( this );
-
-/* KeyError. */
-/* --------- */
- } else if ( !strcmp( attrib, "keyerror" ) ) {
- result = astTestKeyError( this );
-
-/* MapLocked. */
-/* --------- */
- } else if ( !strcmp( attrib, "maplocked" ) ) {
- result = astTestMapLocked( this );
-
-/* SortBy. */
-/* ------- */
- } else if ( !strcmp( attrib, "sortby" ) ) {
- result = astTestSortBy( this );
-
-/* If the attribute is still not recognised, pass it on to the parent
- method for further interpretation. */
- } else {
- result = (*parent_testattrib)( this_object, attrib, status );
- }
-
-/* Return the result, */
- return result;
-}
-
-static int TestSizeGuess( AstKeyMap *this, int *status ) {
-/*
-*+
-* Name:
-* astTestSizeGuess
-
-* Purpose:
-* Test the value of the SizeGuess attribute for a KeyMap.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "keymap.h"
-* int astTestSizeGuess( AstKeyMap *this )
-
-* Class Membership:
-* KeyMap method.
-
-* Description:
-* This function returns a non-zero value if the SizeGuess attribute
-* has been set in a KeyMap.
-
-* Parameters:
-* this
-* Pointer to the KeyMap.
-
-* Returned Value:
-* Non-zero if the SizeGuess attribute is set.
-
-* Notes:
-* - A value of zero is returned if this function is invoked with the
-* global error status set.
-
-*-
-*/
-
-/* Local Variables: */
- int result; /* Returned value */
-
-/* Initialise */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Return non-zero if the attribute is still set to its "not set" value. */
- return ( this->sizeguess != INT_MAX );
-}
-
-/* Functions which access class attributes. */
-/* ---------------------------------------- */
-
-/*
-*att++
-* Name:
-* SizeGuess
-
-* Purpose:
-* The expected size of the KeyMap.
-
-* Type:
-* Public attribute.
-
-* Synopsis:
-* Integer.
-
-* Description:
-* This is attribute gives an estimate of the number of entries that
-* will be stored in the KeyMap. It is used to tune the internal
-* properties of the KeyMap for speed and efficiency. A larger value
-* will result in faster access at the expense of increased memory
-* requirements. However if the SizeGuess value is much larger than
-* the actual size of the KeyMap, then there will be little, if any,
-* speed gained by making the SizeGuess even larger. The default value
-* is 300.
-*
-* The value of this attribute can only be changed if the KeyMap is
-* empty. Its value can be set conveniently when creating the KeyMap.
-* An error will be reported if an attempt is made to set or clear the
-* attribute when the KeyMap contains any entries.
-
-* Applicability:
-* KeyMap
-* All KeyMaps have this attribute.
-*att--
-*/
-
-/*
-*att++
-* Name:
-* KeyCase
-
-* Purpose:
-* Are keys case sensitive?
-
-* Type:
-* Public attribute.
-
-* Synopsis:
-* Integer (boolean).
-
-* Description:
-* This attribute is a boolean value which controls how keys are
-* used. If KeyCase is zero, then key strings supplied to any method
-* are automatically converted to upper case before being used. If
-* KeyCase is non-zero (the default), then supplied key strings are
-* used without modification.
-*
-* The value of this attribute can only be changed if the KeyMap is
-* empty. Its value can be set conveniently when creating the KeyMap.
-* An error will be reported if an attempt is made to change the
-* attribute value when the KeyMap contains any entries.
-
-* Applicability:
-* KeyMap
-* All KeyMaps have this attribute.
-* Table
-* The Table class over-rides this attribute by forcing it to zero.
-* That is, keys within a Table are always case insensitive.
-*att--
-*/
-astMAKE_GET(KeyMap,KeyCase,int,1,(this->keycase == -1 ? 1 : this->keycase))
-astMAKE_TEST(KeyMap,KeyCase,( this->keycase != -1 ))
-
-/*
-*att++
-* Name:
-* KeyError
-
-* Purpose:
-* Report an error when getting the value of a non-existant KeyMap entry?
-
-* Type:
-* Public attribute.
-
-* Synopsis:
-* Integer (boolean).
-
-* Description:
-* This attribute is a boolean value which controls how the
-c astMapGet...
-f AST_MAPGET...
-* functions behave if the requested key is not found in the KeyMap.
-* If KeyError is zero (the default), then these functions will return
-c zero
-f .FALSE.
-* but no error will be reported. If KeyError is non-zero, then the
-* same values are returned but an error is also reported.
-
-* Notes:
-* - When setting a new value for KeyError, the supplied value is
-* propagated to any KeyMaps contained within the supplied KeyMap.
-* - When clearing the KeyError attribute, the attribute is also
-* cleared in any KeyMaps contained within the supplied KeyMap.
-
-* Applicability:
-* KeyMap
-* All KeyMaps have this attribute.
-*att--
-*/
-astMAKE_GET(KeyMap,KeyError,int,0,( ( this->keyerror != -INT_MAX ) ?
- this->keyerror : 0 ))
-astMAKE_TEST(KeyMap,KeyError,( this->keyerror != -INT_MAX ))
-
-/*
-*att++
-* Name:
-* MapLocked
-
-* Purpose:
-* Prevent new entries being added to a KeyMap?
-
-* Type:
-* Public attribute.
-
-* Synopsis:
-* Integer (boolean).
-
-* Description:
-* If this boolean attribute is set to
-c a non-zero value,
-f .TRUE.,
-* an error will be reported if an attempt is made to add a new entry
-* to the KeyMap. Note, the value associated with any existing entries
-* can still be changed, but no new entries can be stored in the KeyMap.
-* The default value
-c (zero)
-f (.FALSE.)
-* allows new entries to be added to the KeyMap.
-
-* Notes:
-* - When setting a new value for MapLocked, the supplied value is
-* propagated to any KeyMaps contained within the supplied KeyMap.
-* - When clearing the MapLocked attribute, the attribute is also
-* cleared in any KeyMaps contained within the supplied KeyMap.
-
-* Applicability:
-* KeyMap
-* All KeyMaps have this attribute.
-*att--
-*/
-astMAKE_GET(KeyMap,MapLocked,int,0,( ( this->maplocked != -INT_MAX ) ?
- this->maplocked : 0 ))
-astMAKE_TEST(KeyMap,MapLocked,( this->maplocked != -INT_MAX ))
-
-/*
-*att++
-* Name:
-* SortBy
-
-* Purpose:
-* Determines how keys are sorted in a KeyMap.
-
-* Type:
-* Public attribute.
-
-* Synopsis:
-* String.
-
-* Description:
-* This attribute determines the order in which keys are returned by the
-c astMapKey
-f AST_MAPKEY
-* function. It may take the following values (the default is "None"):
-*
-* - "None": The keys are returned in an arbitrary order. This is the
-* fastest method as it avoids the need for a sorted list of keys to
-* be maintained and used.
-*
-* - "AgeDown": The keys are returned in the order in which values were
-* stored in the KeyMap, with the key for the most recent value being
-* returned last. If the value of an existing entry is changed, it goes
-* to the end of the list.
-*
-* - "AgeUp": The keys are returned in the order in which values were
-* stored in the KeyMap, with the key for the most recent value being
-* returned first. If the value of an existing entry is changed, it goes
-* to the top of the list.
-*
-* - "KeyAgeDown": The keys are returned in the order in which they
-* were originally stored in the KeyMap, with the most recent key being
-* returned last. If the value of an existing entry is changed, its
-* position in the list does not change.
-*
-* - "KeyAgeUp": The keys are returned in the order in which they
-* were originally stored in the KeyMap, with the most recent key being
-* returned first. If the value of an existing entry is changed, its
-* position in the list does not change.
-*
-* - "KeyDown": The keys are returned in alphabetical order, with "A..."
-* being returned last.
-*
-* - "KeyUp": The keys are returned in alphabetical order, with "A..."
-* being returned first.
-
-* Notes:
-* - If a new value is assigned to SortBy (or if SortBy is cleared),
-* all entries currently in the KeyMap are re-sorted according to the
-* new SortBy value.
-
-* Applicability:
-* KeyMap
-* All KeyMaps have this attribute.
-*att--
-*/
-astMAKE_GET(KeyMap,SortBy,int,SORTBY_NONE,( ( this->sortby != -INT_MAX ) ?
- this->sortby : SORTBY_NONE ))
-astMAKE_TEST(KeyMap,SortBy,( this->sortby != -INT_MAX ))
-
-/* Copy constructor. */
-/* ----------------- */
-static void Copy( const AstObject *objin, AstObject *objout, int *status ) {
-/*
-* Name:
-* Copy
-
-* Purpose:
-* Copy constructor for KeyMap objects.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* void Copy( const AstObject *objin, AstObject *objout, int *status )
-
-* Description:
-* This function implements the copy constructor for KeyMap objects.
-
-* Parameters:
-* objin
-* Pointer to the object to be copied.
-* objout
-* Pointer to the object being constructed.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* void
-
-* Notes:
-* - This constructor makes a deep copy.
-*/
-
-/* Local Variables: */
- AstKeyMap *in; /* Pointer to input KeyMap */
- AstKeyMap *out; /* Pointer to output KeyMap */
- int i; /* Index into hash table */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain pointers to the input and output KeyMap structures. */
- in = (AstKeyMap *) objin;
- out = (AstKeyMap *) objout;
-
-/* For safety, first clear any references to the input memory from
- the output KeyMap. */
- out->table = NULL;
- out->nentry = NULL;
- out->first = NULL;
- out->firstA = NULL;
-
-/* Make copies of the table entries. */
- out->table = astMalloc( sizeof( AstMapEntry * )*( out->mapsize ) );
- out->nentry = astMalloc( sizeof( int )*( out->mapsize ) );
-
- for( i = 0; i < out->mapsize; i++ ) CopyTableEntry( in, out, i, status );
-
-/* Create the required sorted key list in the new KeyMap. */
- SortEntries( out, status );
-
-/* If an error occurred, clean up by freeing all memory allocated above. */
- if ( !astOK ) {
- for( i = 0; i < out->mapsize; i++ ) FreeTableEntry( out, i, status );
- out->table = astFree( out->table );
- out->nentry = astFree( out->nentry );
- }
-}
-
-/* Destructor. */
-/* ----------- */
-static void Delete( AstObject *obj, int *status ) {
-/*
-* Name:
-* Delete
-
-* Purpose:
-* Destructor for KeyMap objects.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* void Delete( AstObject *obj, int *status )
-
-* Description:
-* This function implements the destructor for KeyMap objects.
-
-* Parameters:
-* obj
-* Pointer to the object to be deleted.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* void
-
-* Notes:
-* This function attempts to execute even if the global error status is
-* set.
-*/
-
-/* Local Variables: */
- AstKeyMap *this; /* Pointer to the KeyMap structure */
- int i; /* Loop count */
-
-/* Obtain a pointer to the KeyMap structure. */
- this = (AstKeyMap *) obj;
-
-/* Free all allocated memory. */
- for( i = 0; i < this->mapsize; i++ ) FreeTableEntry( this, i, status );
-
-/* Free memory used to hold tables. */
- this->table = astFree( this->table );
- this->nentry = astFree( this->nentry );
-
-/* Nullify other pointers. */
- this->first = NULL;
- this->firstA = NULL;
-}
-
-/* Dump function. */
-/* -------------- */
-static void Dump( AstObject *this_object, AstChannel *channel, int *status ) {
-/*
-* Name:
-* Dump
-
-* Purpose:
-* Dump function for KeyMap 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 KeyMap class to an output Channel.
-
-* Parameters:
-* this
-* Pointer to the KeyMap 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: */
- AstKeyMap *this; /* Pointer to the KeyMap structure */
- AstMapEntry *next; /* Pointer to the next AstMapEntry to dump */
- int i; /* Index into hash table */
- int nentry; /* Number of entries dumped so far */
- int set; /* Is attribute set? */
- int ival; /* Attribute value */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the KeyMap structure. */
- this = (AstKeyMap *) this_object;
-
-/* Initialise the number of KeyMap entries dumped so far. */
- nentry = 0;
-
-/* SizeGuess. */
-/* ---------- */
- set = TestSizeGuess( this, status );
- ival = set ? GetSizeGuess( this, status ) : astGetSizeGuess( this );
- astWriteInt( channel, "SzGss", set, 0, ival, "Guess at KeyMap size" );
-
-/* SortBy. */
-/* ------- */
- set = TestSortBy( this, status );
- ival = set ? GetSortBy( this, status ) : astGetSortBy( this );
- astWriteString( channel, "SortBy", set, 0, SortByString( ival, "astDump",
- status ),
- "Sorting scheme for keys" );
-
-/* KeyCase. */
-/* --------- */
- set = TestKeyCase( this, status );
- ival = set ? GetKeyCase( this, status ) : astGetKeyCase( this );
- astWriteInt( channel, "KyCas", set, 0, ival, "Are keys case sensitive?" );
-
-/* KeyError. */
-/* --------- */
- set = TestKeyError( this, status );
- ival = set ? GetKeyError( this, status ) : astGetKeyError( this );
- astWriteInt( channel, "KyErr", set, 0, ival, "Report non-existant keys?" );
-
-/* MapLocked. */
-/* --------- */
- set = TestMapLocked( this, status );
- ival = set ? GetMapLocked( this, status ) : astGetMapLocked( this );
- astWriteInt( channel, "MpLck", set, 0, ival, "Prevent addition of new entries?" );
-
-/* MapSize. */
-/* -------- */
- astWriteInt( channel, "MapSz", 1, 1, this->mapsize, "Size of hash table" );
-
-/* member count. */
- astWriteInt( channel, "MemCnt", 1, 1, this->member_count, "Total member count" );
-
-/* Loop round each entry in the hash table. */
- for( i = 0; i < this->mapsize; i++ ) {
-
-/* Get a pointer to the next KeyMap entry to dump. */
- next = this->table[ i ];
-
-/* Loop round dumping all KeyMap entries in this element of the hash table. */
- while( next && astOK ) {
- DumpEntry( next, channel, ++nentry, status );
-
-/* Get a pointer to the next entry to dump. */
- next = next->next;
-
- }
- }
-}
-
-/* Standard class functions. */
-/* ========================= */
-/* Implement the astIsAKeyMap and astCheckKeyMap functions using the macros
- defined for this purpose in the "object.h" header file. */
-astMAKE_ISA(KeyMap,Object)
-astMAKE_CHECK(KeyMap)
-
-AstKeyMap *astKeyMap_( const char *options, int *status, ...) {
-/*
-*++
-* Name:
-c astKeyMap
-f AST_KEYMAP
-
-* Purpose:
-* Create a KeyMap.
-
-* Type:
-* Public function.
-
-* Synopsis:
-c #include "keymap.h"
-c AstKeyMap *astKeyMap( const char *options, ... )
-f RESULT = AST_KEYMAP( OPTIONS, STATUS )
-
-* Class Membership:
-* KeyMap constructor.
-
-* Description:
-* This function creates a new empty KeyMap and optionally initialises its
-* attributes. Entries can then be added to the KeyMap using the
-c astMapPut0<X> and astMapPut1<X> functions.
-f AST_MAPPUT0<X> and AST_MAPPUT1<X> functions.
-*
-* The KeyMap class is used to store a set of values with associated keys
-* which identify the values. The keys are strings. These may be case
-* sensitive or insensitive as selected by the KeyCase attribute, and
-* trailing spaces are ignored. The value associated with a key can be
-* integer (signed 4 and 2 byte, or unsigned 1 byte), floating point
-* (single or double precision),
-c void pointer,
-* character string or AST Object pointer. Each
-* value can be a scalar or a one-dimensional vector. A KeyMap is
-* conceptually similar to a Mapping in that a KeyMap transforms an
-* input into an output - the input is the key, and the output is the
-* value associated with the key. However, this is only a conceptual
-* similarity, and it should be noted that the KeyMap class inherits from
-* the Object class rather than the Mapping class. The methods of the
-* Mapping class cannot be used with a KeyMap.
-
-* Parameters:
-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 KeyMap. 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 KeyMap. 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 astKeyMap()
-f AST_MAP = INTEGER
-* A pointer to the new KeyMap.
-
-* Notes:
-* - 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.
-
-* Status Handling:
-* The protected interface to this function includes an extra
-* parameter at the end of the parameter list descirbed above. This
-* parameter is a pointer to the integer inherited status
-* variable: "int *status".
-
-*--
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Pointer to thread-specific global data */
- AstKeyMap *new; /* Pointer to new KeyMap */
- 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 KeyMap, allocating memory and initialising the
- virtual function table as well if necessary. */
- new = astInitKeyMap( NULL, sizeof( AstKeyMap ), !class_init, &class_vtab, "KeyMap" );
-
-/* 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 KeyMap'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 KeyMap. */
- return new;
-}
-
-AstKeyMap *astKeyMapId_( const char *options, ... ) {
-/*
-* Name:
-* astKeyMapId_
-
-* Purpose:
-* Create a KeyMap.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "keymap.h"
-* AstKeyMap *astKeyMapId_( const char *options, ... )
-
-* Class Membership:
-* KeyMap constructor.
-
-* Description:
-* This function implements the external (public) interface to the
-* astKeyMap constructor function. It returns an ID value (instead
-* of a true C pointer) to external users, and must be provided
-* because astKeyMap_ 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 astKeyMap_ directly, so it must be a re-implementation
-* of it in all respects, except for the final conversion of the
-* result to an ID value.
-
-* Parameters:
-* As for astKeyMap_.
-
-* Returned Value:
-* The ID value associated with the new KeyMap.
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Pointer to thread-specific global data */
- AstKeyMap *new; /* Pointer to new KeyMap */
- 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 KeyMap, allocating memory and initialising the
- virtual function table as well if necessary. */
- new = astInitKeyMap( NULL, sizeof( AstKeyMap ), !class_init, &class_vtab, "KeyMap" );
-
-/* 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 KeyMap'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 KeyMap. */
- return astMakeId( new );
-}
-
-AstKeyMap *astInitKeyMap_( void *mem, size_t size, int init, AstKeyMapVtab *vtab,
- const char *name, int *status ) {
-/*
-*+
-* Name:
-* astInitKeyMap
-
-* Purpose:
-* Initialise a KeyMap.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "keymap.h"
-* AstKeyMap *astInitKeyMap( void *mem, size_t size, int init, AstKeyMapVtab *vtab,
-* const char *name )
-
-* Class Membership:
-* KeyMap initialiser.
-
-* Description:
-* This function is provided for use by class implementations to initialise
-* a new KeyMap object. It allocates memory (if necessary) to accommodate
-* the KeyMap plus any additional data associated with the derived class.
-* It then initialises a KeyMap 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 KeyMap at the start of the memory passed via the
-* "vtab" parameter.
-
-* Parameters:
-* mem
-* A pointer to the memory in which the KeyMap is to be created. This
-* must be of sufficient size to accommodate the KeyMap data
-* (sizeof(KeyMap)) 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 KeyMap (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 KeyMap
-* structure, so a valid value must be supplied even if not required for
-* allocating memory.
-* init
-* A logical flag indicating if the KeyMap'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 KeyMap.
-* name
-* Pointer to a constant null-terminated character string which contains
-* the name of the class to which the new object belongs (it is this
-* pointer value that will subsequently be returned by the astClass
-* method).
-
-* Returned Value:
-* A pointer to the new KeyMap.
-
-* 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: */
- AstKeyMap *new; /* Pointer to the new KeyMap */
-
-/* Check the global error status. */
- if ( !astOK ) return NULL;
-
-/* If necessary, initialise the virtual function table. */
- if ( init ) astInitKeyMapVtab( vtab, name );
-
-/* Initialise an Object structure (the parent class) as the first component
- within the KeyMap structure, allocating memory if necessary. */
- new = (AstKeyMap *) astInitObject( mem, size, 0, (AstObjectVtab *) vtab,
- name );
-
- if ( astOK ) {
-
-/* Initialise the KeyMap data. */
-/* ---------------------------- */
-/* Initialise all attributes to their "undefined" values. */
- new->sizeguess = INT_MAX;
- new->mapsize = 0;
- new->table = NULL;
- new->nentry = NULL;
- new->keycase = -1;
- new->keyerror = -INT_MAX;
- new->maplocked = -INT_MAX;
- new->sortby = -INT_MAX;
- new->first = NULL;
- new->nsorted = 0;
- new->member_count = 0;
- new->firstA = NULL;
- new->iter_itab = 0;
- new->iter_entry = NULL;
-
- NewTable( new, MIN_TABLE_SIZE, status );
-
-/* If an error occurred, clean up by deleting the new KeyMap. */
- if ( !astOK ) new = astDelete( new );
- }
-
-/* Return a pointer to the new KeyMap. */
- return new;
-}
-
-AstKeyMap *astLoadKeyMap_( void *mem, size_t size, AstKeyMapVtab *vtab,
- const char *name, AstChannel *channel, int *status ) {
-/*
-*+
-* Name:
-* astLoadKeyMap
-
-* Purpose:
-* Load a KeyMap.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "keymap.h"
-* AstKeyMap *astLoadKeyMap( void *mem, size_t size, AstKeyMapVtab *vtab,
-* const char *name, AstChannel *channel )
-
-* Class Membership:
-* KeyMap loader.
-
-* Description:
-* This function is provided to load a new KeyMap 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
-* KeyMap 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 KeyMap at the start of the memory
-* passed via the "vtab" parameter.
-
-
-* Parameters:
-* mem
-* A pointer to the memory into which the KeyMap is to be
-* loaded. This must be of sufficient size to accommodate the
-* KeyMap data (sizeof(KeyMap)) 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 KeyMap (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 KeyMap 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(AstKeyMap) is used instead.
-* vtab
-* Pointer to the start of the virtual function table to be
-* associated with the new KeyMap. If this is NULL, a pointer
-* to the (static) virtual function table for the KeyMap 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 "KeyMap" is used instead.
-
-* Returned Value:
-* A pointer to the new KeyMap.
-
-* 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: */
- AstKeyMap *new; /* Pointer to the new KeyMap */
- AstObject **alist; /* Pointer to vector of entry values */
- AstObject *aval; /* AST Object value for an entry */
- astDECLARE_GLOBALS /* Pointer to thread-specific global data */
- char *com; /* Pointer to comment string for an entry */
- char *key; /* Pointer to key string for an entry */
- char *sval; /* String value for an entry */
- char buff[ 30 ]; /* Buffer for key names */
- const char **slist; /* Pointer to vector of entry values */
- double *dlist; /* Pointer to vector of entry values */
- double dval; /* Floating point value for an entry */
- float *flist; /* Pointer to vector of entry values */
- int *ilist; /* Pointer to vector of entry values */
- int index; /* Index of next array element in a vector entry */
- int ival; /* Integer value for an entry */
- int mapsize; /* Size for new hash table */
- int nel; /* Vector length */
- int nentry; /* Number of KeyMap entries read so far */
- int type; /* Data type for an entry */
- short int *wlist; /* Pointer to vector of entry values */
- short int wval; /* Short int value for an entry */
- unsigned char *blist; /* Pointer to vector of entry values */
- unsigned char bval; /* Byte value for an entry */
-
-/* Get a pointer to the thread specific global data structure. */
- astGET_GLOBALS(channel);
-
-/* Initialise. */
- new = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return new;
-
-/* If a NULL virtual function table has been supplied, then this is
- the first loader to be invoked for this KeyMap. In this case the
- KeyMap belongs to this class, so supply appropriate values to be
- passed to the parent class loader (and its parent, etc.). */
- if ( !vtab ) {
- size = sizeof( AstKeyMap );
- vtab = &class_vtab;
- name = "KeyMap";
-
-/* If required, initialise the virtual function table for this class. */
- if ( !class_init ) {
- astInitKeyMapVtab( 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 KeyMap. */
- new = astLoadObject( mem, size, (AstObjectVtab *) vtab, name, channel );
-
- if ( astOK ) {
-
-/* Inidicate the KeyMap is empty. */
- new->mapsize = 0;
- new->table = NULL;
- new->nentry = NULL;
- new->firstA = NULL;
- new->iter_itab = 0;
- new->iter_entry = NULL;
-
-/* Read input data. */
-/* ================ */
-/* Request the input Channel to read all the input data appropriate to
- this class into the internal "values list". */
- astReadClassData( channel, "KeyMap" );
-
-/* Now read each individual data item from this list and use it to
- initialise the appropriate instance variable(s) for this class. */
-
-/* SizeGuess. */
-/* ---------- */
- new->sizeguess = astReadInt( channel, "szgss", INT_MAX );
- if ( TestSizeGuess( new, status ) ) SetSizeGuess( new, new->sizeguess, status );
-
-/* KeyCase. */
-/* --------- */
- new->keycase = astReadInt( channel, "kycas", -INT_MAX );
- if ( TestKeyCase( new, status ) ) SetKeyCase( new, new->keycase, status );
-
-/* KeyError. */
-/* --------- */
- new->keyerror = astReadInt( channel, "kyerr", -INT_MAX );
- if ( TestKeyError( new, status ) ) SetKeyError( new, new->keyerror, status );
-
-/* MapLocked. */
-/* --------- */
- new->maplocked = astReadInt( channel, "mplck", -INT_MAX );
- if ( TestMapLocked( new, status ) ) SetMapLocked( new, new->maplocked, status );
-
-/* SortBy. */
-/* ------- */
- sval = astReadString( channel, "sortby", " " );
- new->sortby = -INT_MAX;
- if( astOK && strcmp( sval, " " ) ) {
- new->sortby = SortByInt( sval, "astRead", status );
- }
- if( TestSortBy( new, status ) ) SetSortBy( new, new->sortby, status );
- sval = astFree( sval );
-
-/* MapSize. */
-/* -------- */
- mapsize = astReadInt( channel, "mapsz", MIN_TABLE_SIZE );
- NewTable( new, mapsize, status );
-
-/* Entries... */
-/* ---------- */
-
-/* Initialise the index of the next AstMapEntry to be read. */
- nentry = 0;
-
-/* Read Entries until no more are found */
- while( astOK ) {
- nentry++;
-
-/* Get the entry key. */
- (void) sprintf( buff, "key%d", nentry );
- key = astReadString( channel, buff, NULL );
-
-/* We have finished reading entries if no key was found. */
- if( !key ) break;
-
-/* Get the entry comment. */
- (void) sprintf( buff, "com%d", nentry );
- com = astReadString( channel, buff, NULL );
-
-/* Get the entry data type. */
- (void) sprintf( buff, "typ%d", nentry );
- type = astReadInt( channel, buff, AST__BADTYPE );
-
- if( type == AST__BADTYPE && astOK ) {
- astError( AST__BDFTS, "astLoadKeyMap(%s): No data type code found "
- "whilst reading a %s.", status, name, name );
-
- }
-
-/* Get the vector length. */
- (void) sprintf( buff, "nel%d", nentry );
- nel = astReadInt( channel, buff, 0 );
-
-/* Get the entry member number. Set the KeyMap member count to this value
- so that the next entry added to the KeyMap will get this value as its
- member index. */
- (void) sprintf( buff, "mem%d", nentry );
- new->member_count = astReadInt( channel, buff, 0 );
-
-/* First deal with integer entries. */
- if( type == AST__INTTYPE ) {
-
-/* For scalar entries, use "val<nentry>" to get the value then create a new
- entry and add it to the KeyMap. */
- if( nel == 0 ) {
- (void) sprintf( buff, "val%d", nentry );
- ival = astReadInt( channel, buff, 0 );
- MapPut0I( new, key, ival, com, status );
-
-/* If we must have an array of values... */
- } else {
-
-/* Create an array to hold the values. */
- ilist = astMalloc( sizeof(int)*nel );
-
-/* Loop round reading values. */
- for( index = 0; astOK && index < nel; index++ ) {
- (void) sprintf( buff, "v%d_%d", nentry, index + 1 );
- ilist[ index ] = astReadInt( channel, buff, 0 );
- }
-
-/* Create the KeyMap entry. */
- MapPut1I( new, key, nel, ilist, com, status );
-
-/* Free resources. */
- ilist = astFree( ilist );
- }
-
-/* Do the same for short int values. */
- } else if( type == AST__SINTTYPE ) {
- if( nel == 0 ) {
- (void) sprintf( buff, "val%d", nentry );
- wval = (short int) astReadInt( channel, buff, 0 );
- MapPut0S( new, key, wval, com, status );
- } else {
- wlist = astMalloc( sizeof(short int)*nel );
- for( index = 0; astOK && index < nel; index++ ) {
- (void) sprintf( buff, "v%d_%d", nentry, index + 1 );
- wlist[ index ] = (short int) astReadInt( channel, buff, 0 );
- }
- MapPut1S( new, key, nel, wlist, com, status );
- wlist = astFree( wlist );
- }
-
-/* Do the same for byte values. */
- } else if( type == AST__BYTETYPE ) {
- if( nel == 0 ) {
- (void) sprintf( buff, "val%d", nentry );
- bval = (unsigned char) astReadInt( channel, buff, 0 );
- MapPut0B( new, key, bval, com, status );
- } else {
- blist = astMalloc( sizeof(unsigned char)*nel );
- for( index = 0; astOK && index < nel; index++ ) {
- (void) sprintf( buff, "v%d_%d", nentry, index + 1 );
- blist[ index ] = (unsigned char) astReadInt( channel, buff, 0 );
- }
- MapPut1B( new, key, nel, blist, com, status );
- blist = astFree( blist );
- }
-
-/* Do the same for double values. */
- } else if( type == AST__DOUBLETYPE ) {
- if( nel == 0 ) {
- (void) sprintf( buff, "val%d", nentry );
- dval = astReadDouble( channel, buff, AST__BAD );
- MapPut0D( new, key, dval, com, status );
- } else {
- dlist = astMalloc( sizeof(double)*nel );
- for( index = 0; astOK && index < nel; index++ ) {
- (void) sprintf( buff, "v%d_%d", nentry, index + 1 );
- dlist[ index ] = astReadDouble( channel, buff, AST__BAD );
- }
- MapPut1D( new, key, nel, dlist, com, status );
- dlist = astFree( dlist );
- }
-
-/* Do the same for float values. */
- } else if( type == AST__FLOATTYPE ) {
- if( nel == 0 ) {
- (void) sprintf( buff, "val%d", nentry );
- dval = astReadDouble( channel, buff, 0.0 );
- MapPut0F( new, key, (float) dval, com, status );
- } else {
- flist = astMalloc( sizeof(float)*nel );
- for( index = 0; astOK && index < nel; index++ ) {
- (void) sprintf( buff, "v%d_%d", nentry, index + 1 );
- flist[ index ] = (float) astReadDouble( channel, buff, 0.0 );
- }
- MapPut1F( new, key, nel, flist, com, status );
- flist = astFree( flist );
- }
-
-/* Do the same for string values. */
- } else if( type == AST__STRINGTYPE ) {
- if( nel == 0 ) {
- (void) sprintf( buff, "val%d", nentry );
- sval = astReadString( channel, buff, "" );
- MapPut0C( new, key, sval, com, status );
- sval = astFree( sval );
- } else {
- slist = astMalloc( sizeof(const char *)*nel );
- for( index = 0; astOK && index < nel; index++ ) {
- (void) sprintf( buff, "v%d_%d", nentry, index + 1 );
- slist[ index ] = astReadString( channel, buff, "" );
- }
- MapPut1C( new, key, nel, slist, com, status );
- for( index = 0; astOK && index < nel; index++ ) {
- slist[ index ] = astFree( (void *) slist[ index ] );
- }
- slist = astFree( slist );
- }
-
-/* Do the same for object values. */
- } else if( type == AST__OBJECTTYPE ) {
- if( nel == 0 ) {
- (void) sprintf( buff, "val%d", nentry );
- aval = astReadObject( channel, buff, NULL );
- MapPut0A( new, key, aval, com, status );
- if( aval ) aval = astAnnul( aval );
- } else {
- alist = astMalloc( sizeof(AstObject *)*nel );
- for( index = 0; astOK && index < nel; index++ ) {
- (void) sprintf( buff, "v%d_%d", nentry, index + 1 );
- alist[ index ] = astReadObject( channel, buff, NULL );
- }
- MapPut1A( new, key, nel, alist, com, status );
- for( index = 0; astOK && index < nel; index++ ) {
- if( alist[ index ] ) alist[ index ] = astAnnul( alist[ index ] );
- }
- alist = astFree( alist );
- }
-
-/* Undef values have no value. */
- } else if( type == AST__UNDEFTYPE ) {
- MapPutU( new, key, com, status );
-
-/* Report an error if the data type is unknown. */
- } else if( astOK ) {
- astError( AST__BDFTS, "astLoadKeyMap(%s): Unknown data type code "
- "(%d) encountered whilst reading a %s.", status, name, type,
- name );
- }
-/* Free resources. */
- key = astFree( key );
- if( com ) com = astFree( com );
-
- }
-
-/* Set the final member count for the KeyMap. */
- new->member_count = astReadInt( channel, "memcnt", 0 );
-
-/* If an error occurred, clean up by deleting the new KeyMap. */
- if ( !astOK ) new = astDelete( new );
- }
-
-/* Return the new KeyMap 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. */
-
-#define MAKE_MAPPUT0_(X,Xtype) \
-void astMapPut0##X##_( AstKeyMap *this, const char *key, Xtype value, \
- const char *comment, int *status ){ \
- if ( !astOK ) return; \
- (**astMEMBER(this,KeyMap,MapPut0##X))(this,key,value,comment, status ); \
-}
-MAKE_MAPPUT0_(D,double)
-MAKE_MAPPUT0_(F,float)
-MAKE_MAPPUT0_(I,int)
-MAKE_MAPPUT0_(C,const char *)
-MAKE_MAPPUT0_(A,AstObject *)
-MAKE_MAPPUT0_(P,void *)
-MAKE_MAPPUT0_(S,short int)
-MAKE_MAPPUT0_(B,unsigned char)
-#undef MAKE_MAPPUT0_
-
-
-#define MAKE_MAPPUT1_(X,Xtype) \
-void astMapPut1##X##_( AstKeyMap *this, const char *key, int size, \
- Xtype value[], const char *comment, \
- int *status ){ \
- if ( !astOK ) return; \
- (**astMEMBER(this,KeyMap,MapPut1##X))(this,key,size,value,comment, status ); \
-}
-MAKE_MAPPUT1_(S,const short int)
-MAKE_MAPPUT1_(B,const unsigned char)
-MAKE_MAPPUT1_(D,const double)
-MAKE_MAPPUT1_(F,const float)
-MAKE_MAPPUT1_(I,const int)
-MAKE_MAPPUT1_(C,const char *const)
-MAKE_MAPPUT1_(A,AstObject *const)
-MAKE_MAPPUT1_(P,void *const)
-#undef MAKE_MAPPUT1_
-
-#define MAKE_MAPGET0_(X,Xtype) \
-int astMapGet0##X##_( AstKeyMap *this, const char *key, Xtype *value, int *status ){ \
- if ( !astOK ) return 0; \
- return (**astMEMBER(this,KeyMap,MapGet0##X))(this,key,value, status ); \
-}
-MAKE_MAPGET0_(D,double)
-MAKE_MAPGET0_(S,short int)
-MAKE_MAPGET0_(B,unsigned char)
-MAKE_MAPGET0_(F,float)
-MAKE_MAPGET0_(I,int)
-MAKE_MAPGET0_(C,const char *)
-MAKE_MAPGET0_(A,AstObject *)
-MAKE_MAPGET0_(P,void *)
-#undef MAKE_MAPGET0_
-
-
-#define MAKE_MAPGET1_(X,Xtype) \
-int astMapGet1##X##_( AstKeyMap *this, const char *key, int mxval, int *nval, \
- Xtype *value, int *status ){ \
- if ( !astOK ) return 0; \
- return (**astMEMBER(this,KeyMap,MapGet1##X))(this,key,mxval,nval,value,status); \
-}
-MAKE_MAPGET1_(B,unsigned char)
-MAKE_MAPGET1_(S,short int)
-MAKE_MAPGET1_(D,double)
-MAKE_MAPGET1_(F,float)
-MAKE_MAPGET1_(I,int)
-MAKE_MAPGET1_(A,AstObject *)
-MAKE_MAPGET1_(P,void *)
-#undef MAKE_MAPGET1_
-
-#define MAKE_MAPGETELEM_(X,Xtype) \
-int astMapGetElem##X##_( AstKeyMap *this, const char *key, int elem, \
- Xtype *value, int *status ){ \
- if ( !astOK ) return 0; \
- return (**astMEMBER(this,KeyMap,MapGetElem##X))(this,key,elem,value,status); \
-}
-MAKE_MAPGETELEM_(B,unsigned char)
-MAKE_MAPGETELEM_(S,short int)
-MAKE_MAPGETELEM_(D,double)
-MAKE_MAPGETELEM_(F,float)
-MAKE_MAPGETELEM_(I,int)
-MAKE_MAPGETELEM_(A,AstObject *)
-MAKE_MAPGETELEM_(P,void *)
-#undef MAKE_MAPGETELEM_
-
-int astMapGet1C_( AstKeyMap *this, const char *key, int l, int mxval, int *nval,
- char *value, int *status ){
- if ( !astOK ) return 0;
- return (**astMEMBER(this,KeyMap,MapGet1C))(this,key,l,mxval,nval,value,status);
-}
-
-int astMapGetElemC_( AstKeyMap *this, const char *key, int l, int elem,
- char *value, int *status ){
- if ( !astOK ) return 0;
- return (**astMEMBER(this,KeyMap,MapGetElemC))(this,key,l,elem,value,status);
-}
-
-#define MAKE_MAPPUTELEM_(X,Xtype) \
-void astMapPutElem##X##_( AstKeyMap *this, const char *key, int elem, \
- Xtype value, int *status ){ \
- if ( !astOK ) return; \
- (**astMEMBER(this,KeyMap,MapPutElem##X))(this,key,elem,value,status); \
-}
-MAKE_MAPPUTELEM_(B,unsigned char)
-MAKE_MAPPUTELEM_(S,short int)
-MAKE_MAPPUTELEM_(D,double)
-MAKE_MAPPUTELEM_(F,float)
-MAKE_MAPPUTELEM_(I,int)
-MAKE_MAPPUTELEM_(A,AstObject *)
-MAKE_MAPPUTELEM_(C,const char *)
-MAKE_MAPPUTELEM_(P,void *)
-#undef MAKE_MAPPUTELEM_
-
-void astMapPutU_( AstKeyMap *this, const char *key, const char *comment, int *status ){
- if ( !astOK ) return;
- (**astMEMBER(this,KeyMap,MapPutU))(this,key,comment,status);
-}
-
-void astMapRemove_( AstKeyMap *this, const char *key, int *status ){
- if ( !astOK ) return;
- (**astMEMBER(this,KeyMap,MapRemove))(this,key,status);
-}
-void astMapRename_( AstKeyMap *this, const char *oldkey, const char *newkey,
- int *status ){
- if ( !astOK ) return;
- (**astMEMBER(this,KeyMap,MapRename))(this,oldkey,newkey,status);
-}
-void astMapCopy_( AstKeyMap *this, AstKeyMap *that, int *status ){
- if ( !astOK ) return;
- (**astMEMBER(this,KeyMap,MapCopy))(this,that,status);
-}
-int astMapDefined_( AstKeyMap *this, const char *key, int *status ){
- if ( !astOK ) return 0;
- return (**astMEMBER(this,KeyMap,MapDefined))(this,key,status);
-}
-int astMapSize_( AstKeyMap *this, int *status ){
- if ( !astOK ) return 0;
- return (**astMEMBER(this,KeyMap,MapSize))(this,status);
-}
-int astMapLenC_( AstKeyMap *this, const char *key, int *status ){
- if ( !astOK ) return 0;
- return (**astMEMBER(this,KeyMap,MapLenC))(this,key,status);
-}
-int astMapLength_( AstKeyMap *this, const char *key, int *status ){
- if ( !astOK ) return 0;
- return (**astMEMBER(this,KeyMap,MapLength))(this,key,status);
-}
-int astMapType_( AstKeyMap *this, const char *key, int *status ){
- if ( !astOK ) return 0;
- return (**astMEMBER(this,KeyMap,MapType))(this,key,status);
-}
-int astMapHasKey_( AstKeyMap *this, const char *key, int *status ){
- if ( !astOK ) return 0;
- return (**astMEMBER(this,KeyMap,MapHasKey))(this,key,status);
-}
-const char *astMapKey_( AstKeyMap *this, int index, int *status ){
- if ( !astOK ) return NULL;
- return (**astMEMBER(this,KeyMap,MapKey))(this,index,status);
-}
-const char *astMapIterate_( AstKeyMap *this, int reset, int *status ){
- if ( !astOK ) return NULL;
- return (**astMEMBER(this,KeyMap,MapIterate))(this,reset,status);
-}
-int astGetSizeGuess_( AstKeyMap *this, int *status ){
- if( !astOK ) return 0;
- return (**astMEMBER(this,KeyMap,GetSizeGuess))(this,status);
-}
-int astTestSizeGuess_( AstKeyMap *this, int *status ){
- if( !astOK ) return 0;
- return (**astMEMBER(this,KeyMap,TestSizeGuess))(this,status);
-}
-void astClearSizeGuess_( AstKeyMap *this, int *status ){
- if( !astOK ) return;
- (**astMEMBER(this,KeyMap,ClearSizeGuess))(this,status);
-}
-void astSetSizeGuess_( AstKeyMap *this, int sizeguess, int *status ){
- if( !astOK ) return;
- (**astMEMBER(this,KeyMap,SetSizeGuess))(this,sizeguess,status);
-}
-
-void astClearMapLocked_( AstKeyMap *this, int *status ){
- if( !astOK ) return;
- (**astMEMBER(this,KeyMap,ClearMapLocked))(this,status);
-}
-void astSetMapLocked_( AstKeyMap *this, int maplocked, int *status ){
- if( !astOK ) return;
- (**astMEMBER(this,KeyMap,SetMapLocked))(this,maplocked,status);
-}
-
-void astClearKeyError_( AstKeyMap *this, int *status ){
- if( !astOK ) return;
- (**astMEMBER(this,KeyMap,ClearKeyError))(this,status);
-}
-void astSetKeyError_( AstKeyMap *this, int keyerror, int *status ){
- if( !astOK ) return;
- (**astMEMBER(this,KeyMap,SetKeyError))(this,keyerror,status);
-}
-
-void astClearSortBy_( AstKeyMap *this, int *status ){
- if( !astOK ) return;
- (**astMEMBER(this,KeyMap,ClearSortBy))(this,status);
-}
-void astSetSortBy_( AstKeyMap *this, int sortby, int *status ){
- if( !astOK ) return;
- (**astMEMBER(this,KeyMap,SetSortBy))(this,sortby,status);
-}
-
-void astClearKeyCase_( AstKeyMap *this, int *status ){
- if( !astOK ) return;
- (**astMEMBER(this,KeyMap,ClearKeyCase))(this,status);
-}
-void astSetKeyCase_( AstKeyMap *this, int keycase, int *status ){
- if( !astOK ) return;
- (**astMEMBER(this,KeyMap,SetKeyCase))(this,keycase,status);
-}
-