\documentstyle{article}
% @(#) $Id: ACMM:sds/TexDocs/sds.tex,v 3.94 09-Dec-2020 17:15:24+11 ks $
%+                              M A N . S T Y
%
%  Module name:
%    MAN.STY
%
%  Function:
%    Default definitions for \LaTeX\ macros used in MAN output
%
%  Description:
%    As much as possible of the output from the MAN automatic manual generator
%    uses calls to user-alterable macros rather than direct calls to built-in
%    \LaTeX\ macros. This file contains the default definitions for these
%    macros.
%
%  Language:
%    \LaTeX
%
%  Support:
%    William Lupton, {AAO}
%-
%  History:
%    16-Nov-88 - WFL - Add definitions to permit hyphenation to work on
%		 words containing special characters and in teletype fonts.
%    21-Mar-90 - WFL - Use \makeatletter and \makeatother; tidy
%    14-Nov-91 - WFL - Add \manroutinebreakitem that inserts a line break
%	       after any text that appears on the initial line of the paragraph
%    15-Nov-91 - WFL - Always put \mbox{} after \item to protect against missing
%	       item text; remove spaces before { and [
%    20-Aug-92 - WFL - Extra parameter to \manroutine and shunt up existing ones
%	       (to facilitate use of \label and \ref)
%    10-Aug-94 - WFL - Cut out "\_" definition (screws up latex2html!); added
%	       unprocessed item name argument to \mansectionitem
%    18-Oct-94 - WFL - Decided that changing args to macros is too naughty so
%	       instead added new \mansectionitemA macro with the extra arg
%    19-Jul-96 - WFL - replaced hyphenchar with DeclreFontFamily for LaTeX2e

\typeout{Default MAN macros. Released 19th July 1996}

% permit use of @ characters in names

\makeatletter

% permit hyphenation when in teletype font (support 9,10,11,12 point only -
% could extend), define lccodes for special characters so that the hyphen-
% ation algorithm is not switched off. Define underscore character to be
% explicit underscore rather than lots of kerns etc.

%\hyphenchar\nintt=`-\hyphenchar\tentt=`-\hyphenchar\elvtt=`-\hyphenchar\twltt=`-
% Latex2e - tell cmtt to hyphenate
\DeclareFontFamily{OT1}{cmtt}{\hyphenchar\font=45}

\lccode`_=`_\lccode`$=`$

%\renewcommand{\_}{{\tt\char'137}}

%+                      M A N _ I N T R O
%
%  Section name:
%    MAN_INTRO
%                                 
%  Function:
%    Macros used in the .TEX_INTRO file
%
%  Description:
%    There are no such special macros.
%-

%+                      M A N _ S U M M A R Y
%
%  Section name:
%    MAN_SUMMARY
%
%  Function:
%    Macros used in the .TEX_SUMMARY file
%
%  Description:
%    There is a command to introduce a new section (mansection) and a list-like
%    environment (mansectionroutines) that handles the list of routines in the
%    current section. In addition a mansectionitem command can be used instead
%    of the item command to introduce a new routine in the current section.
%-

\newcommand{\mansection}[2]{\subsection{#1 --- #2}}

\newenvironment{mansectionroutines}{\begin{description}\begin{description}}%
{\end{description}\end{description}}

\newcommand{\mansectionitem}[1]{\item[#1:]\mbox{}}

% This form (which wflman V2.0 generates) passes an un-processed version of the
% section item name, useful for cross-references
\newcommand{\mansectionitemA}[2]{\item[#1:]\mbox{}}

%+                      M A N _ D E S C R
%
%  Section name:
%    MAN_DESCR
%
%  Function:
%    Macros used in the .TEX_DESCR file
%
%  Description:
%    There is a command to introduce a new routine (manroutine) and a list-like
%    environment (manroutinedescription) that handles the list of paragraphs
%    describing the current routine. In addition a manroutineitem or
%    manroutinebreakitem command can be used instead of the item command to
%    introduce a new paragraph for the current routine.
%
%    Two-column tables (the ones that can occur anywhere and which are
%    triggered by "=>" as the second token on a line) are bracketed by a
%    new environment (mantwocolumntable). Other sorts of table are introduced
%    by relevant  environments (manparametertable, manfunctiontable and
%    manvaluetable). The definitions of these environments call various other
%    user-alterable commands, thus allowing considerable user control over such
%    tables... (to be filled in when the commands have been written)
%-

\newcommand{\manrule}{\rule{\textwidth}{0.5mm}}

\newcommand{\manroutine}[3]{\subsection{#1 --- #2}}

\newenvironment{manroutinedescription}{\begin{description}}{\end{description}%
\manrule}

\newenvironment{mansubparameterdescription}{\begin{description}}%
{\end{description}}

\newcommand{\manroutineitem}[2]{\item[#1:] #2\mbox{}}

\newcommand{\manroutinebreakitem}[2]{\item[#1:] #2\hfill\\}

% two column tables

\newcommand{\mantwocolumncols}{||l|p{80mm}||}

\newcommand{\mantwocolumntop}{\hline}

\newcommand{\mantwocolumnblank}{\mantwocolumn@ss\mantwocolumn@hl%
\gdef\mantwocolumn@hl{}\gdef\mantwocolumn@ss{}}

\newcommand{\mantwocolumnbottom}{\mantwocolumn@ss\mantwocolumn@hl}

\newenvironment{mantwocolumntable}{%
\hspace*{\fill}\vspace*{-\partopsep}%
\begin{center}%
\begin{tabular}{\mantwocolumncols}%
\mantwocolumntop%
\gdef\mantwocolumn@ss{}\gdef\mantwocolumn@hl{}}%
{\mantwocolumnbottom%
\end{tabular}%
\end{center}}

\newcommand{\mantwocolumnentry}[1]{\mantwocolumn@ss\gdef\mantwocolumn@ss{\\}%
\gdef\mantwocolumn@hl{\hline}#1 & }

% parameter tables

\newcommand{\manparametercols}{lllp{80mm}}

\newcommand{\manparameterorder}[3]{#1 & #2 & #3 & }

\newcommand{\manparametertop}{}

\newcommand{\manparameterblank}{\gdef\manparameter@hl{}\gdef\manparameter@ss{}}

\newcommand{\manparameterbottom}{}

\newenvironment{manparametertable}{\gdef\manparameter@ss{}%
\gdef\manparameter@hl{}\hspace*{\fill}\vspace*{-\partopsep}\begin{trivlist}%
\item[]\begin{tabular}{\manparametercols}\manparametertop}{\manparameterbottom%
\end{tabular}\end{trivlist}}

\newcommand{\manparameterentry}[3]{\manparameter@ss\gdef\manparameter@ss{\\}%
\gdef\manparameter@hl{\hline}\manparameterorder{#1}{#2}{#3}}

% return tables

\newcommand{\manreturncols}{lllp{80mm}}

\newcommand{\manreturnorder}[3]{#1 & #2 & #3 & }

\newcommand{\manreturntop}{}

\newcommand{\manreturnblank}{\gdef\manreturn@hl{}\gdef\manreturn@ss{}}

\newcommand{\manreturnbottom}{}

\newenvironment{manreturntable}{\gdef\manreturn@ss{}%
\gdef\manreturn@hl{}\hspace*{\fill}\vspace*{-\partopsep}\begin{trivlist}%
\item[]\begin{tabular}{\manreturncols}\manreturntop}{\manreturnbottom%
\end{tabular}\end{trivlist}}

\newcommand{\manreturnentry}[3]{\manreturn@ss\gdef\manreturn@ss{\\}%
\gdef\manreturn@hl{\hline}\manreturnorder{#1}{#2}{#3}}

% function tables

\newcommand{\manfunctioncols}{||l|l|p{80mm}||}

\newcommand{\manfunctionorder}[2]{#1 & #2 & }

\newcommand{\manfunctiontop}{\hline}

\newcommand{\manfunctionblank}{\manfunction@ss\manfunction@hl%
\gdef\manfunction@ss{}\gdef\manfunction@hl{}}

\newcommand{\manfunctionbottom}{\manfunction@ss\manfunction@hl}

\newenvironment{manfunctiontable}{\gdef\manfunction@ss{}\gdef\manfunction@hl{}%
\hspace*{\fill}\vspace*{-\partopsep}\begin{center}\begin{tabular}%
{\manfunctioncols}\manfunctiontop}{\manfunctionbottom\end{tabular}\end{center}}

\newcommand{\manfunctionentry}[2]{\manfunction@ss\gdef\manfunction@ss{\\}%
\gdef\manfunction@hl{\hline}\manfunctionorder{#1}{#2}}

% value tables

\newcommand{\manvaluecols}{||l|l|l|p{80mm}||}

\newcommand{\manvalueorder}[3]{#1 & #2 & #3 & }

\newcommand{\manvaluetop}{\hline}

\newcommand{\manvalueblank}{\manvalue@ss\manvalue@hl\gdef\manvalue@ss{}%
\gdef\manvalue@hl{}}

\newcommand{\manvaluebottom}{\manvalue@ss\manvalue@hl}

\newenvironment{manvaluetable}{\gdef\manvalue@ss{}\gdef\manvalue@hl{}%
\hspace*{\fill}\vspace*{-\partopsep}\begin{center}\begin{tabular}%
{\manvaluecols}\manvaluetop}{\manvaluebottom\end{tabular}\end{center}}

\newcommand{\manvalueentry}[3]{\manvalue@ss\gdef\manvalue@ss{\\}%
\gdef\manvalue@hl{\hline}\manvalueorder{#1}{#2}{#3}}

% list environments

\newenvironment{manenumerate}{\begin{enumerate}}{\end{enumerate}}

\newcommand{\manenumerateitem}[1]{\item[#1]\mbox{}}

\newenvironment{manitemize}{\begin{itemize}}{\end{itemize}}

\newcommand{\manitemizeitem}{\item\mbox{}}

\newenvironment{mandescription}{\begin{description}\begin{description}}%
{\end{description}\end{description}}

\newcommand{\mandescriptionitem}[1]{\item[#1]\mbox{}}

% teletype conversion

\newcommand{\mantt}{\tt}

% "semi-verbatim" environment (modified from LaTeX source)

\def\@mansemiverbatim{\trivlist\item[]\if@minipage\else\vskip\parskip\fi%
\leftskip\@totalleftmargin\rightskip\z@%
\parindent\z@\parfillskip\@flushglue\parskip\z@%
\@tempswafalse\def\par{\if@tempswa\hbox{}\fi\@tempswatrue\@@par}%
\obeylines}

\def\mansemiverbatim{\@mansemiverbatim\frenchspacing\@vobeyspaces}

\let\endmansemiverbatim=\endtrivlist

% forbid use of @ characters in names

\makeatother

 
\setlength{\textwidth}{160mm}
\setlength{\textheight}{225mm}
\setlength{\topmargin}{-5mm}
\setlength{\oddsidemargin}{0mm}
\setlength{\evensidemargin}{0mm}
\setlength{\parindent}{0mm}
\setlength{\parskip}{\medskipamount}
\newenvironment{cozy}[1]%
{\begin{list}{}{%
\settowidth{\labelwidth}{\large\tt #1}%
\setlength{\labelsep}{5mm}%
\setlength{\leftmargin}{\labelwidth}\addtolength{\leftmargin}{\labelsep}%
\setlength{\parsep}{\medskipamount}%
}}{\end{list}}

\begin{document}

\begin{center}
{\LARGE  Self-defining Data System (SDS) \\ Version 2.3 }

\vspace{2cm}
{\large Jeremy Bailey}

\vspace{1cm}
{\large Anglo-Australian Observatory}

\vspace{1cm}
{\large 25 July 2001}

\end{center}

\tableofcontents

\newpage
\section{Summary}

The Self-Defining data system (SDS) is a system which allows the creation of
self-defining hierarchical data structures in a form which allows the data to
be moved between different machine architectures. Because, the structures are
self-defining they can be used for communication between independent modules
in a distributed system. The data structures are dynamic, allowing components
to be added or deleted, or the size of arrays to be changed.

\section{Introduction to SDS}

SDS allows us to build essentially the same sort of data structures that we 
can build in most programming languages, for example in C using the
\verb$struct$ keyword. A C struct groups together a number of items, each of
which may be a simple variable, or may itself be another struct (thus giving
rise to the hierarchical nature of the structures). Given this analogy, why do
we need SDS? The reason is that SDS structures provide a number of features
which are not present if we simply use the C struct. SDS structures have three
important features:

\begin{itemize}

\item SDS structures are portable.

\item SDS structures are dynamic.

\item SDS structures are self-defining.

\end{itemize}

\subsection{Portable Structures}

Although it is easy to write a C struct to a file, and then read it back
on another machine, the result will probably not be what was expected if the
second machine is of a different architecture to the original. Differences may
be encountered in the byte order of numeric items, in the representation of
floating point numbers, and in the alignment requirements for structure
components. The DEC VAX and SUN Sparc architectures, for example, differ in all
these respects.

SDS is designed to look after all these architectural dependencies, and enable
structures to be moved between machines, while guaranteeing to provide data in
the correct format for the local machine.

\subsection{Dynamic Structures}

A C struct is a static structure, fixed at compile time. It is is not possible
to dynamically add or delete components at run time. It is of course possible
to create dynamic structures in C using pointers, linked lists etc., but such
a structure is not then easily accessible as a single localized entity which can
be written to a file or moved between machines.

SDS allows structures to be manipulated dynamically, while retaining the
ability to move a structure as a single entity between machines.

\subsection{Self-Defining Structures}

If a data structure is to be passed between two communicating programs, then
both programs need to have an identical copy of the structure definition to
ensure they interpret the structure identically. In the case of a C struct this
definition is the C source code declaring the structure. The same definition
must be included in the source of both programs. For two tightly linked
programs, it may not be too difficult to ensure that the two programs are
always using the same copy of the definition. For data moved around a widely
distributed system, this can be much more difficult to accomplish, and it
becomes very difficult to safely make any changes to a data structure without
undesirable effects on other programs.

SDS solves this problem by including the definition of the structure with the
data. This definition contains the name, type and dimensionality of each data
item, and enables an item to be accessed by name, without the program
necessarily having to know everything about the contents of the structure. It is
thus much easier to develop communicating programs independently, since a new
item may be added to a structure without requiring any changes in another
program which reads that structure.

\subsection{What SDS is}

SDS consists of the SDS format defined in appendix~\ref{SDS-format}, and a
library of C functions which are used for building and accessing SDS structures
(appendix~\ref{SDS-kernel-functions}). There is also a package of utility
functions (Appendix~\ref{SDS-utility-functions}) and a Fortran interface to SDS
(appendix~\ref{SDS-fortran-interface}).

\subsection{What SDS isn't}

SDS is not a disk format, tape format, or any other device specific format. The
SDS format simply specifies how a hierarchical structure can be encoded into an
array of bytes. Given that in UNIX a file is simply a sequence of bytes, the
representation of an SDS structure as a file is fairly obvious, but the SDS
kernel itself includes no I/O operations.

SDS ascribes no meaning to the data contained in its structures. The use of 
the structure components is up to whatever higher level software calls SDS.
The only thing SDS has to know about the data, is to recognize integer and
floating point numbers which may need conversion for other architectures.

\subsection{Comparison with XDR}

There are other systems which address some of the problems which SDS solves.
One of these is the eXternal Data Representation (XDR) standard used by 
the Sun RPC (Remote Procedure Call) system. XDR handles the problems of
portability of data but falls short of the features provided by SDS in a number
of ways.

\begin{itemize}

\item XDR is not a self-defining data format. Both sides of a connection must
know the structure of the data in order to interpret it correctly, and serious
problems could be encountered if the structure definitions at the two ends get
out of step. This makes it more difficult to develop reliable modular software,
particularly in cases where two communicating modules may be developed by
independent programmers working at geographically separated locations.

\item XDR handles portability by converting all data to a standard format.
Thus, when moving data from a SUN to another SUN no data conversion is required
since the standard format is already that for a Sun, but when moving data from
a VAX to another VAX the data must first be converted to the standard format on
one machine and then converted back to VAX format on the second machine. In the
case of SDS no conversion is required in either of these cases, since data is
simply flagged with its format, and converted only when it is read on a machine
of different architecture.

\item XDR is limited in the range of data types supported. In particular it
does not support 16 bit integer types, nor does it support multi-dimensional
arrays.

\end{itemize}

\subsection{Comparison with HDS}

Starlink's Hierarchical Data System (HDS), allows the building of hierarchical
data structures similar to those of SDS, and in it's latest version supports
portable structures across three different machine types, using the same
approach as SDS, i.e. converting data only when it is read on a machine with
different architecture to that on which it was written. HDS is self-defining,
dynamic and portable. The differences between HDS and SDS are as follows:

\begin{itemize}

\item HDS constructs its data structures in disk files only. SDS by comparison
manipulates data structures in memory. This is at least part of the reason that
SDS is much faster than HDS (factors of 20 to 100 times faster for operations
such as creating structures, navigating structures and reading and writing
data). It also means that HDS structures cannot be transmitted between processes
as messages or via shared memory as is possible with SDS.

\item The definition of HDS is as a subroutine interface. The HDS format is
nowhere defined. In contrast SDS has both a defined format and software for
accessing the format.

\item HDS has only a Fortran interface defined. SDS has both C and Fortran
interfaces.

\item HDS is written in a mixture of C and Fortran. This restricts its
portability to machines which have a Fortran compiler and an implementation of
the CNF package used to handle mixed language calls. SDS is written in pure C
and can easily be ported to a wide range of systems, including systems which
have no Fortran compiler, and which may not have access to disks, as will be
the case for some real-time systems.

\end{itemize}

The SDS format is sufficiently compatible with the HDS format, that it is
relatively straightforward to convert structures between the two formats, and
programs to do this in both directions have been written (HDS2SDS and SDS2HDS).

\subsection{Typical Use of SDS}

Although SDS could be useful within the context of a single program, it really
comes into its own when used to move data around a distributed system,
particularly one which involves machines of different types. 

Typically a program running on one machine would create a structure, write
data into it and then write the structure to a file. A program running on
another machine could then read the file, import the structure into SDS and
read the data. If necessary it could further modify the structure before
writing it out as a file again.

A file is only one possible way of moving an SDS structure between machines.
Other possible ways would be by means of a message sent over the network, or by
means of shared memory.


\section{SDS Concepts}

\subsection{SDS Objects}

An SDS structure is built out of three types of objects.

\begin{description}

\item{Primitive items} - A primitive item is an item which can contain some
data and may be either a scalar or an n dimensional array (where n $\leq$ 7) 
of one of the primitive types described below.

\item{Structures} - A structure is a list of named items each of which may be a
primitive item, a structure or a structure array. The number of items may be
between zero and 65535.

\item{Structure Arrays} - A structure array is an n-dimensional array (where 
n $\leq$ 7) of items, each of which is a structure.

\end{description}

We use the term {\em object} as a generic term for these three types of item.
An object can range in complexity from a single primitive item, to a complex
tree structure built up using structures and structure arrays.

\subsection{Top Level Objects}

A top level object is one that is not a member of any other structure or
structure array. Most SDS functions can operate equally well on either top level
objects, or on objects which are part of structures.

\subsection{Primitive Types}

There are nine types of primitive items as described in the following table.

\begin{tabular}{|l|l|l|}
\hline
SDS type code & C type & range \\
\hline
SDS\_CHAR & char & \\
SDS\_BYTE & signed char & -127 to 127 \\
SDS\_UBYTE & unsigned char & 0 to 255 \\
SDS\_SHORT & short & -32767 to 32767 \\
SDS\_USHORT & unsigned short & 0 to 65535 \\
SDS\_INT & int or long & -2147483647 to 2147483647 \\
SDS\_UINT & unsigned int or long & 0 to 4294967295 \\
SDS\_I64 & long (64 bit) & -2$^{63}-1$ to $2^{63}-1$ \\
SDS\_UI64 & unsigned long (64 bit) & 0 to $2^{64}-1$ \\
SDS\_FLOAT & float & machine dependent \\
SDS\_DOUBLE & double & machine dependent \\
\hline
\end{tabular}

The types mostly correspond to the ANSI C types, and the ranges represent the minimum
range guaranteed by ANSI C. It is possible that some SDS representations will
support a greater range in some cases, but only numbers within the range listed
above can be successfully transported between machines.

The SDS\_INT and SDS\_UINT types correspond to 32 bit integers. On many systems
C int and long types are both 32 bits in length, but on some systems int may
be a 16 bit type, and on some long may be a 64 bit type, so there is no
C type which can be guaranteed to provide a 32 bit integer. The sds.h
header files therefore define types INT32 and UINT32 which will provide a 32 bit integer type on any system, and will aid in writing portable SDS applications.

The SDS\_I64 and SDS\_UI64 types correspond to 64 bit integers. Only 64 bit
architectures such as the Dec Alpha provide a 64 bit integer type in C. The 
sds.h header file defines types INT64 and UINT64 which can be used to hold 
a 64 bit integer. On 64 bit systems these types are equivalent to a long int.
On 32 bit systems they will be defined as structs containing two 32 bit 
integers.

In C there is no distinction between a char type and a byte used to represent a
number. SDS however, distinguishes between the two cases using the type
SDS\_CHAR to represent actual characters, and SDS\_BYTE or SDS\_UBYTE to represent
byte length integers. This is required because future implementations may need
to support character sets other than ASCII and will need to convert data
between the different character sets, whereas byte length integers will not
require such conversion.

\subsection{SDS arrays}

When SDS is used to create a primitive array, the array dimension information
is stored in the structure, and a data block sufficient to hold the array will
be used for the data. For example a 10 by 20 real array will cause a data block
large enough to hold 200 real numbers to be used. SDS however does not ascribe
any meaning to individual elements within the array, and has no functions which 
access specific elements by means of indices. The interpretation of the data is
left to the high level software which makes used of SDS. SDS does not therefore 
enforce any particular index numbering scheme for arrays. The only functions
which can access part of an array are \verb$SdsPut$ and \verb$SdsGet$ using the
offset parameters, which specifies an offset into the data buffer treated as a
one dimensional array, whatever the actual dimensionality.

Structure arrays have one (and only one) function which accesses array elements
by indices and this is SdsCell. Array elements are numbered from 1 to n where
n is the dimension specified on creation. 

\subsection{Internal and External Objects}

SDS objects can exist in either internal or external forms. An internal
structure has the following properties: 

\begin{itemize}

\item An internal object exists in memory managed by SDS itself.

\item The object is dynamic. All SDS functions are permitted including
those which alter the structure, and delete or add components.

\item The detailed representation of the structure is hidden from the user, and
may be implementation dependent. The object can only be accessed through SDS
functions.

\end{itemize}

External objects have the following properties:

\begin{itemize}

\item The objects exists in a data buffer supplied by the user.

\item The object is static. Operations which read and write data, or
navigate the structure are permitted, but operations which add or delete
components or change the size of an item are not permitted.

\item The structure is represented in the format described in
appendix~\ref{SDS-format} of
this document.

\end{itemize}

Objects are converted between external and internal form by the 
\verb$SdsExport$ and \verb$SdsImport$ functions.

\subsection{Identifiers}

SDS objects are referenced by the use of identifiers. An identifier is a
variable which is passed to an SDS function to identify the object to operate
on. Functions which create new SDS objects return identifiers to them.
Identifiers can also be obtained using the functions which navigate structures.
An identifier should be declared with the type {\bf SdsIdType} defined in the include file
{\bf sds.h}.

\subsection{Extra Information Field}

Every SDS object contains in addition to the data, a field which can be used
for any additional information which a higher level software package might want
to associate with the object. The field is a character array of up to 128 bytes
in length. It could be used, for example, to associate a type name with
structured items (which all have the same type code of SDS\_STRUCT), or to indicate
the units of a numeric item. This field is specified when the object is
created, and can be subsequently modified and accessed using the
\verb$SdsPutExtra$ and \verb$SdsGetExtra$ functions.

If the extra information field is not required its length should be specified
as zero to minimize the space required by the object.

\section{SDS Functions}

\subsection{Status Values}

All SDS functions have a status argument which operates on the inherited status
convention. The status argument should be set to the value SDS\_\_OK (defined
in sds.h) initially. If any SDS function is called with status set to any other
value it will return immediately and do nothing. If an error is found during 
operation of an SDS function this is signalled by returning an appropriate
error code in the status argument. The possible error codes returned by each
function are listed in the function descriptions, and are defined in sds.h.

\subsection{Structure Creation}

New structures are created using the function
\verb$SdsNew$. To create a new top level object \verb$SdsNew$ is called with
a \verb$parent_id$ of 0. The identifier returned can be used as the 
\verb$parent_id$ in 
subsequent calls to add components to a structure. \verb$SdsNew$ can be used to
create structures, structure arrays and primitives.

When \verb$SdsNew$ is used to create a primitive object, the data for the
object is initially in an undefined state, and no memory is allocated for the
data. Memory only gets allocated when the data is accessed using \verb$SdsPut$
or \verb$SdsPointer$. This {\em deferred creation} makes it possible to produce
compact template objects which contain the definition of a structure, but no
data.

\begin{verbatim}

/*  Structure creation example   */

#include "sds.h"

main(void)

{

  SdsIdType topid;   /* Top level identifier  */
  SdsIdType id1;     /* Identifier of first component  */
  SdsIdType id2;     /* Identifier of second component  */
  SdsIdType id3;     /* Identifier of third component  */
  unsigned long dims[2];   /*   Array dimensions   */
  long status;   /* Inherited status variable  */

/* Initialize status variable  */

  status = SDS__OK;
  
/* Create the top level object  */

  SdsNew(0, "Top", 0, NULL, SDS_STRUCT, 0, NULL, &topid, &status);

/* Create the first component - a primitive scalar integer */

  SdsNew(topid, "Comp1", 0, NULL, SDS_INT, 0, NULL, &id1, &status);

/* Create the second component - a two dimensional double array  */

  dims[0] = 10;
  dims[1] = 20;
  SdsNew(topid, "Comp2", 0, NULL, SDS_DOUBLE, 2, dims, &id2, &status);

/* Create the third component - a structure array - also illustrate the setting
   of the extra information field  */

  dims[0] = 4;
  SdsNew(topid, "Comp3", 17 ,"A Structure Array", SDS_STRUCT, 1, dims, &id3,
         &status);

/* Check everything is OK */

  if (status != SDS__OK) printf(" Error creating structure - %d\n",status);

  .
  .

\end{verbatim}


\subsection{Structure Navigation}

These functions allow navigation through a structure tree and return
identifiers to objects within it.

\verb$SdsFind$ is used to find a structure component by name and return an
identifier to it.

\verb$SdsIndex$ is used to find a structure component by position. The position
of a structure component is determined by the order in which the components
were created using \verb$SdsNew$. The first component has index number 1, the
second 2, etc. 

Generally \verb$SdsFind$ is the preferred way of finding structure components,
since the self-defining nature of the structures is only fully used if
components are accessed by name. However, \verb$SdsIndex$ is useful for
programs which do not know what components to expect in a structure, for
example, in a general program to list the contents of a structure.

The third navigation function is \verb$SdsCell$ which is used to find a
component of a structure array and return an identifier to it.

\subsection{Reading and Writing Data}

Data is written into an SDS object using the function \verb$SdsPut$. It copies
data from a data buffer into the object. The object to be written into may be
either a primitive, a structure or a structure array. If it is a structure the
data buffer is assumed to contain a C struct equivalent to the SDS structure
being written into. Equivalent means here having the same primitive components
in the same order. \verb$SdsPut$ automatically skips over any padding regions
which would be needed in the C struct to meet alignment requirements.

In the case of a primitive object, the offset parameter can be used to specify
that the data will be written at some offset value into a primitive array. Thus
\verb$SdsPut$ can be used to write only part of an array. The offset parameter
is ignored when putting to a structure or structure array.

If the data for the primitive object is undefined, \verb$SdsPut$ causes the
memory for the data to be allocated. Note, however, that it is not possible to
do this in an external object, so data can only be written to an external
object if the data is already defined.

Data is read back from an SDS object using \verb$SdsGet$. This operates in a
very similar way to \verb$SdsPut$ and can read data from primitives, structures
or structure arrays.

\begin{verbatim}

/*  Example illustrating Structure get and put operations   */

#include <stdio.h>
#include "sds.h"

main(void)

{
long status;
SdsIdType topid,id1,id2,id3,id4;
unsigned long actlen;

/*  Define a C structure containing 4 items of different types  */
/*  The use of the INT32 type is necessary to ensure portability  */
/*  to all architectures  */

typedef struct block
   {
      char   c1;
      double d1;
      INT32  i1;
      float  f1; 
   }  block;

block block1 = {'Q', 1.23456789, 9999, 3.1415926};
block block2;

/*  Create an SDS structure equivalent to the C structure   */

   status = SDS__OK;
   SdsNew(0,"test",0,NULL,SDS_STRUCT,0,NULL,&topid,&status);
   SdsNew(topid,"char1",0,NULL,SDS_CHAR,0,NULL,&id1,&status);
   SdsNew(topid,"double1",0,NULL,SDS_DOUBLE,0,NULL,&id2,&status);
   SdsNew(topid,"int1",0,NULL,SDS_INT,0,NULL,&id3,&status);
   SdsNew(topid,"float1",0,NULL,SDS_FLOAT,0,NULL,&id4,&status);

/*  Write the C structure (block1) into the SDS structure  */

   SdsPut(topid,sizeof(block),0,&block1,&status);

/*  Read from the SDS structure back into the C structure block2  */

   SdsGet(topid,sizeof(block),0,&block2,&actlen,&status);
 
/*  Print contents of block2  */

   printf(" %c %g %d %f \n",block2.c1,block2.d1,block2.i1,block2.f1);

}
\end{verbatim}

An alternative way of accessing the data in an object is to use
\verb$SdsPointer$. This returns a pointer to the location of the data in the
object itself. \verb$SdsPointer$ like \verb$SdsPut$ causes memory to be
allocated for the data if it was previously undefined. SdsPointer can only be
used with primitive items, not with structures or structure arrays.

When any change has been made to data which has been accessed via a pointer 
returned from \verb$SdsPointer$, a call to \verb$SdsFlush$ must be made to
ensure that the data is updated into the original structure. This is needed to
handle cases where SDS has to provide a copy of the data rather than the
original data in the structure.

\begin{verbatim}

void* ptr;

/*  Get a pointer to an item  */

   SdsPointer(id,&ptr,&status);
.
.  Make changes to item using pointer
.
/*  Flush the item to ensure it is updated in original structure  */

   SdsFlush(id,&status);

\end{verbatim}

Note that a pointer can become invalid as a result of subsequent operations
which may delete or move the data of an object such as \verb$SdsDelete$ or
\verb$SdsResize$. No checks are incorporated to guard against such problems.

\subsection{Export and Import Functions}

An internal SDS object is exported into a caller supplied buffer by the
function \verb$SdsExport$. Before exporting an object it is necessary to
determine the size of buffer required to export it, and this can be obtained
using \verb$SdsSize$. This size can then be used to allocate a buffer of the
required size (e.g. using \verb$malloc$). Thus the following sequence could be
used to export the object referenced by identifier id:

\begin{verbatim}

  unsigned long size;
  void *buffer;
  long status;
  SdsIdType id;

  status = SDS__OK;
  SdsSize(id,&size,&status);
  buffer = malloc(size);
  if (buffer != NULL)
    SdsExport(id,size,buffer,&status);
  
\end{verbatim}

An exported object can be reimported into SDS using \verb$SdsImport$. This
function returns an identifier to a new internal copy of the object which can
subsequently be accessed or manipulated using any SDS function.

In many cases, however, it will not be necessary to import an object in order
to access it. The function \verb$SdsAccess$ returns an identifier to an object
contained in a buffer, but accesses it in place as an external object. 
Operations which read and write data and navigate the structure are permitted
on such an external object, but operations which alter the structure are not
permitted.

If an SDS item contains undefined primitive data (i.e. items that have been
created with \verb$SdsNew$, but not had any data yet written to them, then
these items are undefined and occupy no space in the exported item, they
cannot be written to until the structure is reimported. This feature allows
compact template objects to be created for structures which contain large data
arrays. If this behaviour is not wanted, there is an alternate export function
\verb$SdsExportDefined$ which exports an object, allocating space for all
primitve objects even those which were originally undefined. Use
\verb$SdsSizeDefined$ to get the buffer size needed for this function.

\subsection{Editing Structures}

The function \verb$SdsDelete$ deletes an object. If the object is a component
of a structure, then subsequent components in the structure are shifted down by
one in position.

Deletion, like all the operations in this section, is to be understood as a
recursive operation deleting all the components of the object, if it is a
structure.

When an object has been deleted any identifiers which refer to it or its
components become invalid, and any attempt to use them will result in an
SDS\_\_BADID status being returned.

The function \verb$SdsCopy$ makes a complete copy of an object as a new top
level object. The original object may be either external or internal. The copy
is always internal.

\verb$SdsExtract$ extracts an object from a structure. The extracted object
becomes an independent top level object, and is deleted from the original
structure.

\verb$SdsInsert$ inserts an object into a structure. The object to be inserted
must be a top level object (it is not permitted in SDS for the same object to
be a member of two different structures). The object is inserted at a position
following all the existing objects in the structure.

\verb$SdsResize$ changes the number and/or size of the dimensions of an array. 
This operation can be performed on primitive arrays or structure arrays. Note
that \verb$SdsResize$ does not move the data elements in the storage
representing the array, so there is no guarantee that after resizing the array
the same data will be found at the same array index positions as before
resizing, though this will be the case for simple changes such as a change in
the last dimension only.

\verb$SdsRename$ is used to change the name of an object.

\subsection{Freeing Identifiers}

Each identifier used by SDS requires allocation of resources within SDS.
Allocation of a very large number of identifiers can cause degradation of
performance. The function \verb$SdsFreeId$ can be used to free up resources allocated
to an identifier so that they can be reallocated to a subsequent identifier.

\subsection{Other Functions}

\verb$SdsInfo$ returns the name and type code of an object. If it is an array
it also returns the array dimensions.

\verb$SdsIsExternal$ is used to enquire whether an SDS object os external.
\verb$SdsExternInfo$ returns the address of the buffer containing an
external item (i.e. the address which was originally given to \verb$SdsAccess$

\verb$SdsGetExtra$ and \verb$SdsPutExtra$ are used to read and write the extra
information field of the object. Note that if the object is external,
\verb$SdsPutExtra$ may not increase the number of bytes in the field.

\section{The SDS Utility Package}

The functions described in the previous section form the SDS kernel. The kernel
is designed to be implemented with minimal system requirements, and in
particular includes no I/O functions. The SDS utility package includes some
additional functions which are implemented in terms of the kernel functions.

\verb$SdsList$ is used to list the contents of an SDS structure on the standard
output stream. The listing includes the name and type of each item, and the
value of primitive items (the first few values only for arrays).

\verb$SdsWrite$ is used to write an SDS structure to a file. The file can then
be read back using \verb$SdsRead$.

The following example program uses SdsRead and SdsList to list the contents of
an SDS file.

\begin{verbatim}
#include "sds.h"

main(int argc, char* argv[])

{
  long status;
  long id;
 
  if (argc > 1)
    {
      status = SDS__OK;
      SdsRead(argv[1],&id,&status);
      SdsList(id,&status);
    }
}
\end{verbatim}

\section{The SDS Compiler}

A C structure can be put and retrieved from a similar SDS
structure using SdsPut and SdsGet.  This makes it desirable to be
able to automatically generate SDS calls to produce an SDS
structure equivalent to the C structure.  {\bf \tt sdsc} does this job.
 
{\bf \tt sdsc} first runs its input through a C preprocessor.  During
this the macros `{\tt SDS}' and `{\tt \_\_\_SDS\_\_\_}' will be defined (in addition
to any macros defined by default).   The result should be a series
of C definitions followed by one and only one structure declaration.

For example:
\begin{verbatim}
typedef long int mytype ;

typedef struct honey { 
                long int iiii; } pppp;

struct mystruct { long int jenny ;
                char john ;
                unsigned char fred ;
                pppp p;
                mytype aaaa ;
                } jim;
\end{verbatim}

In this example, the declaration of the structure {\tt jim}, of type
``mystruct'' is the required structure.  The {\tt typedef}'s define
some of its elements.  (Note, the required definitions could be
extracted from C source code by use of the {\tt SDS} or {\tt \_\_\_SDS\_\_\_}  macros).

The result of running this though sdsc is a C routine body.  In this
case we get (minus some comments)-
\begin{verbatim}
{
    int tid0 = 0;
    int id = 0;
    if (*status != SDS__OK) return;

    SdsNew(0,"mystruct", 0 , NULL, SDS_STRUCT, 0, NULL, &tid0, status);
    SdsNew(tid0, "jenny", 0, NULL, SDS_UINT, 0 , NULL,  &id, status);
    SdsNew(tid0, "john", 0, NULL, SDS_CHAR, 0 , NULL,  &id, status);
    SdsNew(tid0, "fred", 0, NULL, SDS_BYTE, 0 , NULL,  &id, status);
    { 
        int tid1 = 0; 
        SdsNew(tid0,"p", 0 , NULL, SDS_STRUCT, 0, NULL, &tid1, status);
        SdsNew(tid1, "iiii", 0, NULL, SDS_UINT, 0 , NULL,  &id, status);
    }
    SdsNew(tid0, "aaaa", 0, NULL, SDS_UINT, 0 , NULL,  &id, status);
 
    return(tid0);
}
\end{verbatim}

The user should provide the routine declaration.  A full example of
users' code follows-
\begin{verbatim}
/* An example illustrating the used of sdsc */
struct mystruct { long int fred;
                  unsigned char john;
                } aaaa;


/* This rest is not passed to sdsc, only to the C compiler */
#ifndef SDS
#include "sds.h"
#include "stdio.h"

/* CreateStruct uses the result of running this module through sdsc */
/* These results should be put in the file test2.h		    */
int CreateStruct(int *status)
#include "test2.h"

/* Now the main routine		*/
struct mystruct jjj = { 1, 'c' };
int main()

{
    int status = SDS__OK;
    int id;
    id = CreateStruct(&status);

    SdsPut(id,sizeof(struct mystruct), 0, &jjj, &status);	
    SdsList(id,&status);
    return(0);
}

#endif
\end{verbatim}
To make the above you would use the commands-
\begin{verbatim}
sdsc test2.c test2.h
gcc -o test2 test2.c
\end{verbatim}

There is also a callable interface to the compiler.  This takes as its input
a string containing the structure definition.  

\begin{verbatim}
/*  Example illustrating the use of SdsCompiler()	*/

#include "sds.h"
#include "stdio.h"
int main()
{
    struct thestruct {
                long int john;
               	char fred;
		};

    struct thestruct b1 = { 10, 'c' };
    struct thestruct b2 = { 0,0};
    int status  = 0;
    int id;
    SdsCompiler("struct thestruct { long int john ; char fred ; } i;",
                 1, &id, &status);
   
    if (status != 0)
        fprintf(stderr, "sdscompiler returned a status of %d\n",status);
    else
    {
        int actlen;
        printf("Contents should be - %d, %c\n",b1.john,b1.fred);
        SdsPut(id,sizeof(struct thestruct),0,&b1,&status);
        SdsList(id,&status);
        SdsGet(id,sizeof(struct thestruct),0,&b2,&actlen,&status);
        printf("Contents are - %d, %c\n",b2.john,b2.fred);
        if (status != 0)
            fprintf(stderr, "Put/Get returned a status of %d\n",status);
    }
    return(status);
} 
\end{verbatim}


\section{The Arg Functions - A simple interface to SDS}

\subsection{Introduction}

The SDS functions to create and access structures have quite a large number of
parameters because of the large number of features they provide. In many cases
the complexity of using SDS calls directly will not be necessary because a
higher level package, layered on top of SDS is also available. This is the Arg
package, so called because it is used to access the arguments of actions in the
AAO 2dF software system. It is however nothing more than a simple interface to
SDS.

ARG differs from SDS in the following ways:

\begin{itemize}

\item In SDS items are referenced by means of identifiers. In ARG items are
referenced by means of the parent identifier and item name. This is slightly
less efficient, but means that it is not necessary to first get the identifier
by means of a \verb$SdsFind$ call.

\item In SDS an item must be seperately created and then written to. In ARG
an item will be created automatically, if necessary, in the same operation as
writing a value.

\item ARG performs type conversion if necessary between the actual type of an
item and the type of the value being written or read.

\item ARG currently only supports scalar items and character strings. More 
complex objects must be accessed by direct SDS calls.

\end{itemize}

ARG may be used on its own, or SDS calls may be interspersed with ARG calls.


\subsection{Arg Functions}

The Arg library provides three types of functions:

\begin{description}

\item{ArgNew} - This is used to create a new argument structure.

\item{ArgPutx} - These functions write items into a argument structure. If the 
item does not yet exist it is created.

\item{ArgGetx} - These functions read items from an argument structure.

\end{description}

The \verb$ArgPutx$ and \verb$ArgGetx$ functions have versions to read and write
scalar items of each of the possible ANSI C types, and there are additional
functions to read and write character strings.

The functions are as follows:

\begin{tabular}{|l|l|l|}   \hline
Type & Put Function & Get Function \\  \hline 
char & ArgPutc & ArgGetc \\
short & ArgPuts & ArgGets \\
unsigned short & ArgPutus & ArgGetus \\
long & ArgPuti & ArgGeti \\
unsigned long & ArgPutu & ArgGetu \\
float & ArgPutf & ArgGetf \\
double & ArgPutd & ArgGetd \\
char[] & ArgPutString & ArgGetString \\
\hline
\end{tabular}


The ArgPutx and ArgGetx function perform type conversion if required between
different arithmetic types (i.e. if the item in the structure has a different
type to that specified by the calling function). Conversion follows the ANSI C
rules for arithmetic type conversion. If the item is out of range of the
destination type the ARG\_\_CNVERR status will be returned, and the operation
will not be completed. The Arg functions will aslo perform conversion between character strings and numeric types. Full descriptions of these functions are given in
appendix~\ref{arg-functions}.  

\subsection{Arg Example}

\begin{verbatim}

#include "sds.h"
#include "arg.h"

main(void)

{

  SdsIdType id;    /* Sds identifier  */
  long status;     /* Inherited Status Variable  */

  status = SDS__OK;

/*  Create a structure  */

  ArgNew(&id,&status);

/*  Create an integer component  */

  ArgPuti(id, "Comp1", 123, &status);

/*  Create a float component  */

  ArgPutf(id, "Comp2", 3.141592, &status);

/*  Create a string component  */

  ArgPutString(id, "Comp3", "This is a string", &status);

}
\end{verbatim}



\section{The Fortran Interface}

A Fortran Interface to SDS has been supplied in addition to the standard C
interface already described. The Fortran interface differs from the C version
in the following ways:

\begin{itemize}

\item The Fortran subroutines have names similar to those of the corresponding
C functions but are all in upper case and use an underscore to separate words
(e.g. SDS\_PUT\_EXTRA for SdsPutExtra).

\item The Fortran versions use Starlink's error message system (EMS) to
report errors. The C version does not use EMS which would restrict its
portability.

\item The functions SdsGet and SdsPut can not easily be converted to
standard Fortran versions, since they handle data items of various different
types. Therefore a set of additional routines have been provided to get and put
the standard Fortran data types (SDS\_GETC, SDS\_GETD, SDS\_GETI etc.). In
addition SDS\_GET and SDS\_PUT which use the non-standard Fortran BYTE type and
can be used to return values of any the SDS types.

\end{itemize}

The Fortran interface has been created using Starlink's CNF package to handle
portable mixed language programming. This has so far been implemented on
VAX, SUN and DECstation, and is thus not as portable as the SDS kernel and
utilities which are in pure C.

The Fortran interface also includes the SDS utility functions and the ARG
functions. The Fortran equivalents of the ARG functions are a little different
to the C versions as they are based on Fortran rather than C types.

The SDS Fortran subroutines are described in
appendix~\ref{SDS-fortran-interface}.

\section{The Implementation}

The current implementation of SDS is written in portable C and should compile
on any machine with an ANSI compliant C compiler, and will in fact compile
with many compilers which are not fully ANSI compliant. It does require a
compiler which supports function prototypes.

The implementation makes the following assumptions about the storage
architecture. Chars must be 8 bits in length, short integers must be 16 bits in
length, long integers and floats must be 32 bits in length, doubles must be 64
bits in length. No assumptions are made about the length of ints and pointers.
An architecture that did not conform to these assumptions would require a
specialized implementation.

Conditional compilations are used to set the value of the array
\verb$local_format$ which contains the format codes for each data type to an
appropriate value for the machine. There
are basically three options used at present:

\begin{itemize}

\item Little endian integers and VAX floating point format (DEC VAX).

\item Little endian integers and byte swapped IEEE floating point format
(DECstation and Intel 80x86).

\item Big endian integers and IEEE floating point format (SUN Sparcstation and
Motorola 680x0)

\end{itemize} 

The alignment requirements for different machines are not specified in
conditional compilations, but are determined by tests built into the code.
The alignment requirements for each of the types, short, long, float, double
are determined by these tests. Three cases have been encountered in practice.

\begin{itemize}

\item No alignment. Any item can begin at any byte address (DEC
VAX).

\item Even alignment. All items larger than char are aligned to even addresses.
(Intel 80x86 and Motorola 680x0).

\item Full Alignment. Items are aligned to their full size, i.e. doubles to 8
byte multiples, longs and floats to 4 bytes, shorts to 2 bytes. (Sun
Sparcstation and DECstation).

\end{itemize}

SDS has been compiled and tested on the following machines:

\begin{itemize}

\item DEC VAX running VMS - Using the VAX C compiler.

\item DEC Alpha running OSF/1 - Using the Dec C compiler or the GNU C compiler.

\item DEC Alpha runing VMS.

\item SUN Sparcstation running SunOs 4 - Using the GNU C compiler.

\item SUN Sparcstation running Solaris 2 - Using the Ansi C SparcCompiler. 

\item DECstation - Using the DECstation C compiler.

\item Apple Macintosh (68020/30) - Using the MPW C compiler, Symantec Think C
compiler, or Symantec C++ compiler or Metroworks CodeWarrior.

\item 68020/30 VME system running VxWorks - Using a GNU C cross compiler running
on a Sparcstation.

\item IBM PC - Using the Microsoft C compiler.

\end{itemize}

SDS structure have been successfully moved between all these machines.

\section{SDS version 2.2 Release}

The SDS version 2.2 release includes the following:

\begin{itemize}

\item The SDS kernel (functions described in
appendix~\ref{SDS-kernel-functions})

\item The SDS utility functions (appendix~\ref{SDS-utility-functions})

\item The ARG functions (appendix~\ref{arg-functions})

\item The SDS compiler.

\item The \verb$sdstest$ test program. This performs an exhaustive test of all
SDS functions, and tests operations on scalars and arrays of all data types in
both internal and external cases.

\item The \verb$readtest$ test program. This tests the ability of SDS to read
`foreign' data files (i.e. SDS data files created on machines of different
architecture).

\item Three SDS data files created on VAX, SUN Sparcstation and DECstation for
use with \verb$readtest$ (These test both big and little endian cases, and
IEEE and VAX floating point formats).

\item The \verb$sdslist$ program which is used to list the contents of an SDS
file.

\item The \verb$sdstimes$ program which performs some timing tests on SDS
functions.

\end{itemize}

The VAX/VMS, SUN and DECstation releases includes in addition the SDS Fortran interface
(Appendix~\ref{SDS-fortran-interface}) and the HDS2SDS and SDS2HDS conversion programs. These should be
made available for the DECstation in a future release.


\subsection{Special Considerations when using SDS under VxWorks}

The VxWorks real time operating system differs from operating systems such as
Unix in providing a single address space shared by all processes. In such a
system there is thus a single SDS context shared by all processes, rather than
each process having its own context as on Unix. The SDS code has to be
reentrant, and this impacts on the operation of the facility for allocating
identifiers used by SDS. In VxWorks this becomes a shared resource and has to
be protected by means of a VxWorks semaphore. There is thus a possibility that 
an SDS function which allocates a new identifier will have to wait to gain
access. It is advisable not to call such functions from interrupt level code.

In VxWorks it is also possible for an SDS object to be accessed by more than
one task. Although this will work, SDS includes no checks to prevent objects
being corrupted by simultaneous access from more than one task. Programs using
SDS in this way should arrange their own access control mechanism for the shared
objects  (e.g. using semaphores).

\section{History}

\subsection{Changes in Version 2.2}

The following new functions were added; \verb$SdsExportDefined$,
\verb$SdsSizeDefined$, \verb$SdsIsExternal$, \verb$SdsExternInfo$.



\subsection{Changes in Version 2.1}

Support for safe operation in a POSIX multithreaded environment. POSIX
mutex semaphores are used to control access to the allocation of identifiers.
To get this behaviour SDS must be compiled with the macro POSIX\_THREADS
defined.

Fixed a bug in the semaphore protection of id allocation under VxWorks.


\subsection{Changes in Version 2.0}

Support for G floating point type (needed to support VMS on Alpha).

Several bug fixes to eliminate memory leaks.

\subsection{Changes in Version 1.4}

\begin{itemize}

\item This version supports Dec Alpha systems running OSF/1. A number of
changes have been made to aid portability to 64 bit architectures.

\item 64 bit integer and unsigned integer types have been added.

\item A bug has been fixed in SdsRead which resulted in the file not
being closed.

\end{itemize}

\subsection{Changes in Version 1.3}

\begin{itemize}

\item The arg package now supports conversion between character strings and
numeric types.

\item The SdsSize and SdsExport operations are now permitted on external
objects.

\item A bug has been fixed in SdsGet which could cause incorrect data to be
returned when 2, 4 or 8 bytes were being transferred and the destination
variable was not aligned on a corresponding boundary.

\item A bug has been fixed in HDS2SDS which caused character string items
to be transferred incorrectly on the VAX.

\end{itemize}

\subsection{Changes in Version 1.2}

\begin{itemize}

\item The SDS compiler (written by Tony Farrell) has been included. It is
available both as a standalone program and a callable function.

\item The Fortran interface and SDS to HDS conversion program have been added
to the DECstation release of SDS.

\item The ARG functions (and Fortran interface to ARG) have been added to
the SDS release.

\item Some function prototypes were missing from the include file in the
previous version. These have now been added.

\end{itemize}

\subsection{Changes in Version 1.1}

\begin{itemize}

\item The type names for identifiers and type codes are now, \verb$SdsIdType$
and \verb$SdsCodeType$.

\item The VxWorks release of SDS is now available.

\item The SUN 4 release now includes the Fortran interface and SDS to HDS
conversion programs.

\item Make files have been modified so that \verb$make$ alone will do a
complete rebuild.

\end{itemize}

\newpage
\appendix
\section{SDS Kernel Function Descriptions}
\label{SDS-kernel-functions}

\manroutine{SdsAccess}{Return an identifier to an external object}{SdsAccess}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Return an identifier to an external object

\manroutineitem{Description}{}
      Make an external object (one exported by SdsExport) accessible
      to {\mantt{SDS}} by returning an identifier to it.

      Any {\mantt{SDS}} operations which do not change the structure of the %
object
      may be performed on the external object. These include navigation
      operations (SdsFind, SdsIndex, SdsCell), data access operations
      (SdsGet, SdsPut, SdsPointer) and inquiry operations (SdsInfo).

      Operations which are not permitted on an external object are those
      which add or remove components (SdsNew, SdsDelete), or write
      operations (SdsPut or SdsPointer) to data items which are currently
      undefined.

      Unlike SdsImport, SdsAccess does not make a copy of the object. The
      object is accessed in place in the original buffer.

\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsAccess(void *data, SdsIdType *id, StatusType {\mantt{*}} {\mantt{%
SDSCONST}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{data}{void*} The buffer containing the object %
to be
                          accessed.
\manparameterentry{{\mantt{<}}}{id}{long*}  Identifier of the external object.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOTSDS}}}Not a valid {\mantt{SDS}} object.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory.
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{18-Oct-91}
\end{manroutinedescription}
\manroutine{SdsCell}{Find component of a structure array}{SdsCell}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Find component of a structure array

\manroutineitem{Description}{}
      Given the indices to a component of a structure array, return an
      identifier to the component.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsCell(SdsIdType array\_{}id, long nindices, unsigned long *indices,
               SdsIdType *id, StatusType {\mantt{*}} {\mantt{SDSCONST}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{array\_{}id}{SdsIdType} Identifier of the %
structure array.
\manparameterentry{{\mantt{>}}}{nindices}{long}  Number of indices supplied in %
the
                            array indices. This should be one or the same as
                            the number of dimensions of the array.
\manparameterentry{{\mantt{>}}}{indices}{unsigned long*}  An array of length %
nindices containing
                            the indices to the component of the structure
                            array. If nindicies is 1, then treat the
                            structure array as having only one dimension even
                            if it has more.
\manparameterentry{{\mantt{<}}}{id}{SdsIdType*} The identifier of the component.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOTARRAY}}}Not a structure array.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}INDEXERR}}}Indices invalid.
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{18-Oct-91}
\end{manroutinedescription}
\manroutine{SdsCopy}{Make a copy of an object}{SdsCopy}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Make a copy of an object

\manroutineitem{Description}{}
      Make a copy of an object and return an identifier to the copy.
      The copy is a new top level object, the original object is
      unchanged by the operation.

      The object being copied can be either external or internal.
      The copy is always an internal object.

\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsCopy(SdsIdType id, SdsIdType *copy\_{}id, StatusType {\mantt{*}} %
{\mantt{SDSCONST}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType}  Identifier of the object to be %
copied.
\manparameterentry{{\mantt{<}}}{copy\_{}id}{SdsIdType*} Identifier of the copy.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}The identifier is invalid.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insuficient memory.
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{23-Oct-91}
\end{manroutinedescription}
\manroutine{SdsDelete}{Delete an object}{SdsDelete}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Delete an object

\manroutineitem{Description}{}
      Delete an object, freeing any memory associated with it. Subsequent
      attempts to access the object through any identifier associated with
      it will return the {\mantt{SDS\_{}\_{}BADID}} status. A structure array %
element cannot
      be deleted. An attempt to do so will result in the {\mantt{SDS\_{}\_{}%
ILLDEL}} status.

     Deleting an object does not free the memory associated with the
     identifier referencing it. This memory can be freed with the
     SdsFreeId function.

 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsDelete(SdsIdType id, long *status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType}  Identifier of the object to be %
deleted.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}The identifier is invalid.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}EXTERN}}}Object is external.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}ILLDEL}}}Object cannot be deleted.
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{18-Oct-91}
\end{manroutinedescription}
\manroutine{SdsExport}{Export an object into an external buffer}{SdsExport}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Export an object into an external buffer

\manroutineitem{Description}{}
      Export an object into an external buffer.

      Once exported an object can be moved around in memory, written to
      a file etc., and subsequently returned to the {\mantt{SDS}} system %
either by using
      SdsImport to import it back into the system, or SdsAccess, to access it
      as an external object.

      The original internal version of the
      object continues to exist, in addition to the external copy. All
      identifiers to the object continue to refer to the original internal
      copy.
 
      With SdsExport, any undefined primitive data items occupy no
      space in the exported item, and cannot be written or read
      until the item is reimported. This enables the creation of
      compact templates for structures which may contain large arrays.
      If this behaviour is not wanted use SdsExportDefined, which allocates
      full space in the external structure for undefined primitive
      items.

      The length of the buffer required for SdsExport can be determined
      by a call to SdsSize.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsExport(SdsIdType id, unsigned long length,
                    void *data, StatusType {\mantt{*}} {\mantt{SDSCONST}} %
status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType}  Identifier of the structure to %
be exported.
\manparameterentry{{\mantt{>}}}{length}{unsigned long} Size in bytes of the %
buffer.
\manparameterentry{{\mantt{<}}}{data}{void*} The buffer into which the object %
will be
                          exported.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}The identifier is invalid.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}TOOLONG}}}The object is too large for %
the buffer
\mantwocolumnentry{{\mantt{SDS\_{}\_{}EXTERN}}}The object is external.
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{18-Oct-91}
\end{manroutinedescription}
\manroutine{SdsExportDefined}{Export an object into an external buffer}{%
SdsExportDefined}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Export an object into an external buffer

\manroutineitem{Description}{}
      Export an object into an external buffer.

      Once exported an object can be moved around in memory, written to
      a file etc., and subsequently returned to the {\mantt{SDS}} system %
either by using
      SdsImport to import it back into the system, or SdsAccess, to access it
      as an external object.

      The original internal version of the
      object continues to exist, in addition to the external copy. All
      identifiers to the object continue to refer to the original internal
      copy.
 
      SdsExportDefined allocates space in the external item for undefined
      data items, so that these can have their values filled in later
      by an SdsPut (or SdsPointer) to the external item.

      The length of the buffer required for SdsExportDefined can be determined
      by a call to SdsSizeDefined.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsExportDefined(SdsIdType id, unsigned long length,
                    void *data, StatusType {\mantt{*}} {\mantt{SDSCONST}} %
status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType}  Identifier of the structure to %
be exported.
\manparameterentry{{\mantt{>}}}{length}{unsigned long} Size in bytes of the %
buffer.
\manparameterentry{{\mantt{<}}}{data}{void*} The buffer into which the object %
will be
                          exported.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}The identifier is invalid.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}TOOLONG}}}The object is too large for %
the buffer
\mantwocolumnentry{{\mantt{SDS\_{}\_{}EXTERN}}}The object is external.
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{13-Jul-98}
\end{manroutinedescription}
\manroutine{SdsExternInfo}{Return the address of an external object}{%
SdsExternInfo}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Return the address of an external object

\manroutineitem{Description}{}
      Return the address of an external {\mantt{SDS}} object given its id.
      This is the address which was given to SdsAccess.

\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsExternInfo(SdsIdType id, void {\mantt{**}} address, StatusType {%
\mantt{*}} {\mantt{SDSCONST}} status)

\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier of the object
\manparameterentry{{\mantt{<}}}{address}{void {\mantt{**}}} Address of object
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}The identifier is invalid.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}EXTERN}}}Not an external object.
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{13-Jul-98}
\end{manroutinedescription}
\manroutine{SdsExtract}{Extract an object from a structure}{SdsExtract}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Extract an object from a structure

\manroutineitem{Description}{}
      Extract an object from a structure. The extracted object becomes a
      new independent top level object. The object is deleted from
      the original structure.

      The identifier must not be that of a structure array component.
 
      If the identifier is already that of a top level object, then the
      function does nothing.

\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsExtract(SdsIdType id, StatusType {\mantt{*}} {\mantt{SDSCONST}} %
status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType}  Identifier of the object to be %
extracted.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}The identifier is invalid.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}ILLDEL}}}Object cannot be extracted.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}EXTERN}}}The object is external.
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{23-Oct-91}
\end{manroutinedescription}


\manroutine{SdsFind}{Find a structure component by name}{SdsFind}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Find a structure component by name

\manroutineitem{Description}{}
      Given the name of a component in a structure, return an
      identifier to the component.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsFind(SdsIdType parent\_{}id, char *name, SdsIdType *id,
         StatusType {\mantt{*}} {\mantt{SDSCONST}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{parent\_{}id}{SdsIdType} Identifier of the %
structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be found.
\manparameterentry{{\mantt{<}}}{id}{SdsIdType*} Identifier to the component.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOTSTRUCT}}}parent\_{}id not a structure
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOITEM}}}No item with that name
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{18-Oct-91}
\end{manroutinedescription}



\manroutine{SdsFlush}{Flush data updated via a pointer}{SdsFlush}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Flush data updated via a pointer

\manroutineitem{Description}{}
      If a primitive data item is accessed via SdsPointer, and the data
      array updated via the returned pointer, then SdsFlush must be called
      to ensure that the data is updated in the original structure.

      This must be done since implementations on some machine architectures
      may have to use a copy of the data rather than the actual data when
      returning a pointer.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsFlush(SdsIdType id, StatusType {\mantt{*}} {\mantt{SDSCONST}} %
status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType}  Identifier of the primitive %
item.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Identifier invalid
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOTPRIM}}}Not a primitive item
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{7-Feb-92}
\end{manroutinedescription}
\manroutine{SdsFreeId}{Free an identifier, so that its associated memory may %
be reused.}{SdsFreeId}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Free an identifier, so that its associated memory may be reused.

\manroutineitem{Description}{}
      Each identifier allocated by {\mantt{SDS}} uses memory. To avoid excessive
      allocation of memory the SdsFreeId function can be used to free
      the memory associated with an identifer that is no longer needed.
      When this is done the memory will be reused by {\mantt{SDS}} for a %
subsequent
      identifier when needed.

\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsFreeId(SdsIdType id, StatusType {\mantt{*}} {\mantt{SDSCONST}} %
status)

\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType}  Identifier to be freed
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}The identifier is invalid.
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
 
\manroutineitem{Version date}{23-Jan-92}
\end{manroutinedescription}
\manroutine{SdsGet}{Read the data from an object}{SdsGet}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Read the data from an object

\manroutineitem{Description}{}
      The object may be a primitive item or a structure or structure array.
      Read the data from an item into a buffer. If the object is primitive
      data is transferred starting at the position in the item specified by
      offset, until the buffer if filled, or the end of the data array is
      reached.

      If the object is a structure or structure array, the data from all its
      primitive components are copied into the buffer in order of their
      position in the structure. Alignment adjustments are made as necessary
      to match the alignment of an C struct equivalent to the {\mantt{SDS}} %
structure.
      (Since these alignment requirements are machine dependent the actual
      sequence of bytes returned could be different on different machines).
      In the structure or structure array case the offset parameter is
      ignored.

      If necessary (e.g. if the data originated on a machine with different
      architecture) the data for the object is converted (in place) from the
      format stored in the data item to that required for the local machine.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsGet(SdsIdType id, unsigned long length, unsigned long offset,
             void *data, unsigned long *actlen, StatusType {\mantt{*}} {\mantt{%
SDSCONST}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier of the object.
\manparameterentry{{\mantt{>}}}{length}{unsigned long}  Length in bytes of the %
buffer supplied to receive
                            the data.
\manparameterentry{{\mantt{>}}}{offset}{unsigned long}  Offset into the data %
object at which to start
                            reading data. The offset is measured in units of
                            the size of each individual item in the array -
                            e.g. 4 bytes for an {\mantt{INT}} or 8 bytes for a %
{\mantt{DOUBLE}}.
                            The offset is zero to start at the beginning of the
                            array. This parameter is ignored if the object
                            is a structure or structure array.
\manparameterentry{{\mantt{<}}}{data}{void*} Buffer to receive the data.
\manparameterentry{{\mantt{<}}}{actlen}{unsigned long*} Actual number of bytes %
transferred.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid identifier
\mantwocolumnentry{{\mantt{SDS\_{}\_{}UNDEFINED}}}Data undefined
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{18-Oct-91}
\end{manroutinedescription}
\manroutine{SdsGetExtra}{Read from the extra information field of an object.}{%
SdsGetExtra}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Read from the extra information field of an object.

\manroutineitem{Description}{}
      Read bytes from the extra information field of an object. Bytes are
      copied until the supplied buffer is filled up or until all bytes
      in the field are copied.

\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsGetExtra(SdsIdType id, long length, char* extra,
          unsigned long* actlen, StatusType {\mantt{*}} {\mantt{SDSCONST}} %
status)

\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier of the object
\manparameterentry{{\mantt{>}}}{length}{long}  Length of buffer to receive data.
\manparameterentry{{\mantt{<}}}{extra}{char*} Buffer to receive the extra %
information
                            copied from the object.
\manparameterentry{{\mantt{<}}}{actlen}{unsigned long*} actual number of bytes %
copied.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}The identifier is invalid.
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{24-Oct-91}
\end{manroutinedescription}
\manroutine{SdsImport}{Import an object from an external buffer}{SdsImport}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Import an object from an external buffer

\manroutineitem{Description}{}
      Import an object from an external buffer and return an identifier
      to the internal copy created. The object must have
      been previously exported using SdsExport.

      The original external version of the
      structure continues to exist, in addition to the internal copy.

      A fully dynamic internal structure is created in which all {\mantt{SDS}}
      operations are valid. However, to merely access the data in an object
      SdsAccess can be used in place of SdsImport.

\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsImport(void *data, SdsIdType *id, StatusType {\mantt{*}} {\mantt{%
SDSCONST}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{data}{void*} The buffer from which the object %
will be
                          imported.
\manparameterentry{{\mantt{<}}}{id}{SdsIdType*}  Identifier of the new %
internal object.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOTSDS}}}Not a valid sds object.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory.
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{18-Oct-91}
\end{manroutinedescription}
\manroutine{SdsIndex}{Find a structure component by position}{SdsIndex}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Find a structure component by position

\manroutineitem{Description}{}
      Given the index number of a component in a structure, return an
      identifier to the component.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsIndex(SdsIdType parent\_{}id, long index, SdsIdType *id,
             StatusType {\mantt{*}} {\mantt{SDSCONST}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{parent\_{}id}{SdsIdType} Identifier of the %
structure.
\manparameterentry{{\mantt{>}}}{index}{long}  Index number of the component to %
be returned.
                            Items in a structure are numbered in order of
                            creation starting with one.
\manparameterentry{{\mantt{<}}}{id}{SdsIdType*} Identifier to the component.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOTSTRUCT}}}parent\_{}id not a structure
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOITEM}}}No item with that index number
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{18-Oct-91}
\end{manroutinedescription}
\manroutine{SdsInfo}{Return information about an object}{SdsInfo}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Return information about an object

\manroutineitem{Description}{}
      Given the identifier to an object, return the name, type code and
      dimensions of the object.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsInfo(SdsIdType id, char *name, SdsCodeType *code, long *ndims,
               unsigned long *dims, StatusType {\mantt{*}} {\mantt{SDSCONST}} %
status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} The identifier to the data %
object.
\manparameterentry{{\mantt{<}}}{name}{char*} The name of the data object. A %
pointer to a
                            character string with space for at least
                            16 characters should be used.
\manparameterentry{{\mantt{<}}}{code}{SdsCodeType*} The type code for the %
object. One of
                            the following values (defined in sds.h):
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}STRUCT}}}Structure
\mantwocolumnentry{{\mantt{SDS\_{}CHAR}}}Character
\mantwocolumnentry{{\mantt{SDS\_{}BYTE}}}Signed byte
\mantwocolumnentry{{\mantt{SDS\_{}UBYTE}}}Unsigned byte
\mantwocolumnentry{{\mantt{SDS\_{}SHORT}}}Signed short integer
\mantwocolumnentry{{\mantt{SDS\_{}USHORT}}}Unsigned short integer
\mantwocolumnentry{{\mantt{SDS\_{}INT}}}Signed long integer
\mantwocolumnentry{{\mantt{SDS\_{}UINT}}}Unsigned long integer
\mantwocolumnentry{{\mantt{SDS\_{}I64}}}Signed 64 bit integer
\mantwocolumnentry{{\mantt{SDS\_{}UI64}}}Unsigned 64 bit integer
\mantwocolumnentry{{\mantt{SDS\_{}FLOAT}}}Floating point
\mantwocolumnentry{{\mantt{SDS\_{}DOUBLE}}}Double precision floating point
\end{mantwocolumntable}
\begin{manparametertable}
\manparameterentry{{\mantt{<}}}{ndims}{long*} The number of dimensions if the %
object
                            is a primitive or structure array.
\manparameterentry{{\mantt{<}}}{dims}{unsigned long*} The dimensions of the %
data. An array of
                            size at least 7 should be allowed to receive this.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}The identifier is invalid
\end{mantwocolumntable}
\manroutineitem{Prior requirements}{}
      None.

\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{18-Oct-91}
\end{manroutinedescription}
\manroutine{SdsInsert}{Insert an existing object into a structure}{SdsInsert}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Insert an existing object into a structure

\manroutineitem{Description}{}
      An existing top level object is inserted into a structure.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsInsert(SdsIdType parent\_{}id, SdsIdType id, StatusType {\mantt{*%
}} {\mantt{SDSCONST}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{parent\_{}id}{SdsIdType}  The identifier of %
the structure to
                            which the component is to be added.
\manparameterentry{{\mantt{>}}}{id}{SdsIdType}  The identifier of the object %
to be inserted.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid identifier
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOTSTRUCT}}}Parent is not a structure
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOTTOP}}}Not a top level object
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory
\mantwocolumnentry{{\mantt{SDS\_{}\_{}EXTERN}}}Object is external
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{23-Oct-91}
\end{manroutinedescription}
\manroutine{SdsInsertCell}{Insert object into a structure array}{SdsInsertCell}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Insert object into a structure array

\manroutineitem{Description}{}
      Insert a top level object into a structure array at a position specified %
by its
      indices. Delete any object that is currently at that position.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsInsertCell(SdsIdType array\_{}id, long nindices, unsigned long *%
indices,
               SdsIdType id, StatusType {\mantt{*}} {\mantt{SDSCONST}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{array\_{}id}{SdsIdType} Identifier of the %
structure array.
\manparameterentry{{\mantt{>}}}{nindices}{long}  Number of indices supplied in %
the
                            array indices. This should be 1 or the same as
                            the number of dimensions of the array.
\manparameterentry{{\mantt{>}}}{indices}{unsigned long*}  An array of length %
nindices containing
                            the indices to the component of the structure
                            array.  If nindicies is 1, then treat the
			    structure array as having only one dimension even
			    if it has more.
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} The identifier of the component %
to be inserted.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}EXTERN}}}Structure array or object is %
external.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOTARRAY}}}Not a structure array.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}INDEXERR}}}Indices invalid.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOTTOP}}}Not a top level object.
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{24-Aug-96}
\end{manroutinedescription}
\manroutine{SdsIsExternal}{Enquire whether an object is external}{SdsIsExternal}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Enquire whether an object is external

\manroutineitem{Description}{}
      Enquire whether an object is external

\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsIsExternal(SdsIdType id, int *external, StatusType {\mantt{*}} {%
\mantt{SDSCONST}} status)

\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier of the object
\manparameterentry{{\mantt{<}}}{external}{int {\mantt{*}}} Non zero if the %
object is external
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}The identifier is invalid.
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{13-Jul-98}
\end{manroutinedescription}
\manroutine{SdsNew}{Create a new object}{SdsNew}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Create a new object

\manroutineitem{Description}{}
      Creates a new component in an existing internal structure or a
      new top level object. A top level object is created by specifying
      a parent\_{}id of zero. The new object can be a structure, a structure
      array, or a primitive. A structure array is specified by means of a
      type code of {\mantt{SDS\_{}STRUCT}} and a non-zero number for ndims. If %
the type
      code is {\mantt{SDS\_{}STRUCT}} and ndims is zero an ordinary structure %
is created.
      A primitive type is specified by the appropriate type code.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsNew(SdsIdType parent\_{}id, char *name, long nextra, char *extra,
         SdsCodeType code, long ndims, unsigned long *dims, SdsIdType *id,
         StatusType {\mantt{*}} {\mantt{SDSCONST}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{parent\_{}id}{SdsIdType} The identifier of the %
structure to
                            which the object is to be added. Use a
                            value of zero to create a new top level object.
\manparameterentry{{\mantt{>}}}{name}{char*} The name of the object to create.
                            The name should be of maximum length 16
                            characters including the terminating null.
\manparameterentry{{\mantt{>}}}{nextra}{long}  The number of bytes of extra %
information to
                            be included (maximum 128).
\manparameterentry{{\mantt{>}}}{extra}{char*} The extra information to be %
included with the item.
                            nextra bytes from here are copied into the
                            structure.
\manparameterentry{{\mantt{>}}}{code}{SdsCodeType} The type code for the item %
to be created. One of
                            the following values (defined in sds.h):
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}STRUCT}}}Structure
\mantwocolumnentry{{\mantt{SDS\_{}CHAR}}}Character
\mantwocolumnentry{{\mantt{SDS\_{}BYTE}}}Signed byte
\mantwocolumnentry{{\mantt{SDS\_{}UBYTE}}}Unsigned byte
\mantwocolumnentry{{\mantt{SDS\_{}SHORT}}}Signed short integer
\mantwocolumnentry{{\mantt{SDS\_{}USHORT}}}Unsigned short integer
\mantwocolumnentry{{\mantt{SDS\_{}INT}}}Signed long integer
\mantwocolumnentry{{\mantt{SDS\_{}UINT}}}Unsigned long integer
\mantwocolumnentry{{\mantt{SDS\_{}I64}}}Signed 64 bit integer
\mantwocolumnentry{{\mantt{SDS\_{}UI64}}}Unsigned 64 bit integer
\mantwocolumnentry{{\mantt{SDS\_{}FLOAT}}}Floating point
\mantwocolumnentry{{\mantt{SDS\_{}DOUBLE}}}Double precision floating point
 
\end{mantwocolumntable}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{ndims}{long}  Number of dimensions for the %
item. Zero
                            to create a scalar item.
\manparameterentry{{\mantt{>}}}{dims}{unsigned long*} Array of dimensions for %
the item. Should be of
                            size at least ndims. A {\mantt{NULL}} pointer may %
be used
                            if the item is a scalar.
\manparameterentry{{\mantt{<}}}{id}{SdsIdType*} Identifier to the created %
object.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid identifier
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}LONGNAME}}}name is too long
\mantwocolumnentry{{\mantt{SDS\_{}\_{}EXTRA}}}Too much extra data
\mantwocolumnentry{{\mantt{SDS\_{}\_{}INVCODE}}}Invalid type code
\mantwocolumnentry{{\mantt{SDS\_{}\_{}INVDIMS}}}Invalid dimensions
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOTSTRUCT}}}Parent is not a structure
\mantwocolumnentry{{\mantt{SDS\_{}\_{}EXTERN}}}Parent is external
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{18-Oct-91}
\end{manroutinedescription}
\manroutine{SdsPointer}{Get a pointer to the data of a primitive item}{%
SdsPointer}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Get a pointer to the data of a primitive item

\manroutineitem{Description}{}
      Return a pointer to the data of a primitive item. Also return the length
      of the item. If the data item is undefined and the object is internal
      storage for the data will be created.

      SdsPointer can only be used with primitive items, not with structures.

      If necessary (e.g. if the data originated on a machine with different
      architecture) the data for the object is converted (in place) from the
      format stored in the data item to that required for the local machine

      If the data pointed to by the pointer is updated by a calling program,
      the program should then call the function SdsFlush to ensure that the
      data is updated in the original structure. This is necessary because
      implementations on some machine architectures may have to use a copy
      of the data rather than the actual data when returning a pointer.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsPointer(SdsIdType id, void **data, unsigned long *length,
              StatusType {\mantt{*}} {\mantt{SDSCONST}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType}  Identifier of the primitive %
item.
\manparameterentry{{\mantt{<}}}{data}{void**} Address of a variable to hold %
the pointer.
\manparameterentry{{\mantt{<}}}{length}{unsigned long*} Length of the data.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOTPRIM}}}Not a primitive item
\mantwocolumnentry{{\mantt{SDS\_{}\_{}UNDEFINED}}}Data undefined, and object %
external
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{18-Oct-91}
\end{manroutinedescription}
\manroutine{SdsPut}{Write data to an object.}{SdsPut}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Write data to an object.

\manroutineitem{Description}{}
      Write data into an object. The object may be a primitive item or a
      structure or structure array.

      If the object is a structure or structure array, the data from the
      the buffer is copied into its primitive components in order of their
      position in the structure. Alignment adjustments are made as necessary
      to match the alignment of a C struct equivalent to the {\mantt{SDS}} %
structure.
      In the structure or structure array case the offset parameter is
      ignored.

      If the object is primitive data is transferred starting
      at the position in the item specified by offset.

      If the data was previously undefined memory for the data is allocated at
      this time.

      If the data is too long to fit into the object, it will be truncated.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsPut(SdsIdType id, unsigned long length, unsigned long offset,
             void *data, long *status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier of the primitive item.
\manparameterentry{{\mantt{>}}}{length}{unsigned long}  Length in bytes of the %
buffer containing
                            the data.
\manparameterentry{{\mantt{>}}}{offset}{unsigned long}  Offset into the data %
object at which to start
                            writing data. The offset is measured in units of
                            the size of each individual item in the array -
                            e.g. 4 bytes for an {\mantt{INT}} or 8 bytes for a %
{\mantt{DOUBLE}}.
                            The offset is zero to start at the beginning of the
                            array.
\manparameterentry{{\mantt{>}}}{data}{void*} Buffer containing the data.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOTPRIM}}}Not a primitive item
\mantwocolumnentry{{\mantt{SDS\_{}\_{}UNDEFINED}}}Data undefined, and object %
external
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{18-Oct-91}
\end{manroutinedescription}
\manroutine{SdsPutExtra}{Write to the extra information field of an object.}{%
SdsPutExtra}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Write to the extra information field of an object.

\manroutineitem{Description}{}
      Write a specified number of bytes to the extra information field
      of an object. A maximum of 128 bytes may be written to an internal
      object. It is permissible to write to the extra information field
      of an external object, but the number of bytes written must not
      exceed the number originally in the object.

\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsPutExtra(SdsIdType id, long nextra, char* extra,
                    StatusType {\mantt{*}} {\mantt{SDSCONST}} status)

\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier of the object
\manparameterentry{{\mantt{>}}}{nextra}{long}  Number of bytes of extra %
information.
\manparameterentry{{\mantt{>}}}{extra}{char*} The extra information to be %
included.
                            nextra bytes are copied into the object.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}The identifier is invalid.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}EXTRA}}}Too much extra data.
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{24-Oct-91}
\end{manroutinedescription}
\manroutine{SdsRename}{Change the name of an object.}{SdsRename}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Change the name of an object.

\manroutineitem{Description}{}
      Specify a new name for an object.

\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsRename(SdsIdType id, char* name, StatusType {\mantt{*}} {\mantt{%
SDSCONST}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType}  Identifier of the object to be %
renamed.
\manparameterentry{{\mantt{>}}}{name}{char*} New name for the object. This %
should
                            have a maximum length of 16 characters including
                            the terminating null.
\manparameterentry{{\mantt{!}}}{status}{long*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}The identifier is invalid.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}LONGNAME}}}The name is too long.
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{24-Oct-91}
\end{manroutinedescription}
\manroutine{SdsResize}{Change the dimensions of an array.}{SdsResize}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Change the dimensions of an array.

\manroutineitem{Description}{}
     Change the number and/or size of the dimensions of an array. This
     operation can be performed on primitive arrays or structure arrays.
     Note that {\mantt{SDS\_{}RESIZE}} does not move the data elements in the %
storage
     representing the array, so there is no guarantee that after resizing
     the array the same data will be found at the same array index
     positions as before resizing, though this will be the case for
     simple changes such as a change in the last dimension only.

     If the size of a primitive array is increased the contents of the
     extra locations is undefined. Decreasing the size causes the data
     beyond the new limit to be lost.

     If a structure array is extended the new elements created will be empty
     structures. If a structure array is decreased in size, the lost elements
     and all their components will be deleted.

\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsResize(SdsIdType id, long ndims, unsigned long *dims,
              StatusType {\mantt{*}} {\mantt{SDSCONST}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier of the object to be %
resized.
\manparameterentry{{\mantt{>}}}{ndims}{long}  New number of dimensions.
\manparameterentry{{\mantt{>}}}{dims}{unsigned long*} Array of dimensions.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}The identifier is invalid.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insuficient memory.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}EXTERN}}}Object is external.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOTARR}}}Object is not an array.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}INVDIMS}}}Dimensions invalid.
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{23-Oct-91}
\end{manroutinedescription}
\manroutine{SdsSize}{Find the buffer size needed to export an object}{SdsSize}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Find the buffer size needed to export an object

\manroutineitem{Description}{}
      Return the size which will be needed for a buffer into which the object
      can be exported using the SdsExport function.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsSize(SdsIdType id, unsigned long *bytes, StatusType {\mantt{*}} {%
\mantt{SDSCONST}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType}  Identifier of the object.
\manparameterentry{{\mantt{<}}}{bytes}{unsigned long*} Size in bytes of %
required buffer.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}The identifier is invalid.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}EXTERN}}}Object is external.
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{18-Oct-91}
\end{manroutinedescription}
\manroutine{SdsSizeDefined}{Find the buffer size needed to export using %
SdsExportDefined}{SdsSizeDefined}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Find the buffer size needed to export using SdsExportDefined

\manroutineitem{Description}{}
      Return the size which will be needed for a buffer into which the object
      can be exported using the SdsExportDefined function.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsSizeDefined(SdsIdType id, unsigned long *bytes, StatusType {%
\mantt{*}} {\mantt{SDSCONST}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType}  Identifier of the object.
\manparameterentry{{\mantt{<}}}{bytes}{unsigned long*} Size in bytes of %
required buffer.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}The identifier is invalid.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}EXTERN}}}Object is external.
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{13-Jul-98}
\end{manroutinedescription}



\newpage
\section{SDS Utility Function Descriptions}
\label{SDS-utility-functions}

\manroutine{SdsFillArray}{Fill out the contents of a structured array.}{%
SdsFillArray}
\begin{manroutinedescription}
\manroutineitem{Function}{}
 	Fill out the contents of a structured array.

\manroutineitem{Description}{}
 	This routine will fill out an array of structures item with
 	the copies of a specified struture.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsFillArray(SdsIdType array\_{}id, SdsIdType elem\_{}id, %
StatusType *status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{array\_{}id}{SdsIdType}  The identifier to the %
array of structures
      				object to be filled
\manparameterentry{{\mantt{>}}}{elem\_{}id}{SdsIdType}  The identifier to the %
object, copies
      				of which are to be put into the array
      				of structures.
\manparameterentry{{\mantt{!}}}{status}{long*} Modified status. SdsFillArray %
calls a large number
                             of {\mantt{SDS}} routines so will return error %
status
                             values if an error occurs in any of these
                             routines.
 

\end{manparametertable}
\manroutineitem{Bugs}{}
 	Due to a missing Sds routine, the resulting structure may have one
 	level too deep.

\manroutineitem{Prior requirements}{}
      None.

\manroutineitem{Support}{Tony Farrell, {AAO}}
\manroutineitem{Version date}{226-Sep-96}
\end{manroutinedescription}
\manroutine{SdsFindByPath}{Accesses a structued Sds item using a path name to %
the item.}{SdsFindByPath}
\begin{manroutinedescription}
\manroutineitem{Function}{}
        Accesses a structued Sds item using a path name to the item.
 
\manroutineitem{Description}{}
        This function is passed the id of an Sds structure and a
        name describing an element in that sturcture using a dot separated
        format.  It returns the id of the element.  For example, if we
        have a structure of the form

\begin{verbatim}
	  Version              		Float
	  FibreCentDist        		Float
    	  PlateArray           		Struct
          Bundle             		Struct
            Fibres           		Struct
                xposition            	Float
                yposition            	Float
                transmission         	Float
                bias                 	Float
                broken               	Short

\end{verbatim}
	Then the name ``PlateArray.BundleArray.Fibres.xposition
	is a valid name.  In addition, structure array elements can
	be specified using  a specifiction like
	
\begin{verbatim}
	item1[2]
	item2[2,3]
\end{verbatim}	
        Where item1 is a one dimensional array and item2 is a two 
        dimensional array.

	Note that the use of this routine requires that Sds names not use
	period or square brackets in their names.  This is not enforced any
	where so must be done by convention.
 
\manroutineitem{Language}{}
      C
 
\manroutinebreakitem{Call}{}
     (void) {\mantt{=}} SdsFindByPath (parent\_{}id,name,id,status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{parent\_{}id}{SdsIdType} Identified of the %
structure
\manparameterentry{{\mantt{>}}}{name}{char {\mantt{*}}} Structured name of the %
item to find
\manparameterentry{{\mantt{<}}}{id}{SdsIdType {\mantt{*}}} Identifier to the %
component
\manparameterentry{{\mantt{!}}}{status}{long*}	Modified status.  Possible %
failure
  				codes are:
 
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficent memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOTSTRUCT}}}Parent id or subsequent
  				non-terminating item is not a structure
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOITEM}}}No item with the specified name.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOTARRAY}}}Attempt to access structure %
array
  				element in an item which is not a structure
  				array.
 
\end{mantwocolumntable}
\manroutineitem{Include files}{sds.h}
 
 
\manroutineitem{Support}{Tony Farrell, {\mantt{AAO}}}
 
\end{manroutinedescription}
\manroutine{SdsList}{List contents of an {\mantt{SDS}} object}{SdsList}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      List contents of an {\mantt{SDS}} object

\manroutineitem{Description}{}
      A listing of the contents of an {\mantt{SDS}} object is generated on
      standard output. The listing consists of the name type, dimensions
      and value of each object in the structure. The hierarchical structure
      is indicated by indenting the listing for components at each level.
 
      For array objects only the values of the first few components are
      listed so that the listing for each object fits on a single line.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsList(SdsIdType id, StatusType *status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType}  The identifier to the object %
to be listed
\manparameterentry{{\mantt{!}}}{status}{long*} Modified status. SdsList calls %
a large number
                             of {\mantt{SDS}} routines so will return error %
status
                             values if an error occurs in any of these
                             routines.
 


\end{manparametertable}
\manroutineitem{Prior requirements}{}
      None.

\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{29-Apr-96}
\end{manroutinedescription}
\manroutine{SdsRead}{Read an {\mantt{SDS}} object from a file}{SdsRead}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Read an {\mantt{SDS}} object from a file

\manroutineitem{Description}{}
      Read an {\mantt{SDS}} object from a file previously written by SdsWrite.
      An identifier to an external object is returned. If an internal
      version of the object is required it can be created using SdsCopy.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsRead(char *filename, SdsIdType *id, StatusType *status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{filename}{char*} The name of the file from %
which the object
                              will be read.
\manparameterentry{{\mantt{<}}}{id}{SdsIdType*} The identifier to the external %
object.
\manparameterentry{{\mantt{!}}}{status}{long*} Modified status. Possible %
failure codes are:

\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOTSDS}}}Not a valid {\mantt{SDS}} object
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory
\mantwocolumnentry{{\mantt{SDS\_{}\_{}FOPEN}}}Error opening the file
\mantwocolumnentry{{\mantt{SDS\_{}\_{}FREAD}}}Error reading the file
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{4-Feb-92}
\end{manroutinedescription}
\manroutine{SdsReadFree}{Free Buffer allocated by SdsRead}{SdsReadFree}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Free Buffer allocated by SdsRead

\manroutineitem{Description}{}
      SdsRead allocates a block of memory to hold the external object read in.
      This memory can be released when the object is no longer required by %
calling
      SdsReadFree (note that it is not possible to SdsDelete an external %
object).

      If SdsReadFree is given an idientifier which was not produced by a call to
      SdsRead it will do nothing.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsReadFree(SdsIdType id, StatusType *status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{<}}}{id}{SdsIdType*} The identifier to the external %
object.
\manparameterentry{{\mantt{!}}}{status}{long*} Modified status. Possible %
failure codes are:

\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOTSDS}}}Not a valid {\mantt{SDS}} object
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{28-Aug-95}
\end{manroutinedescription}
\manroutine{SdsTypeToString}{Given an Sds Type Code, return a pointer to a %
string.}{SdsTypeToString}
\begin{manroutinedescription}
\manroutineitem{Function}{}
 	Given an Sds Type Code, return a pointer to a string.

\manroutineitem{Description}{}
 	Just simply looks up the code and returns a string pointer describing
 	the type referred to by the Sds Code.
 
 	If code is invalid, then will return ``{\mantt{SDS\_{}INVALID}}'' or
 	``invalid type'' depending on mode.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      const char *SdsTypeToStr(code,mode)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{SdsCodeType}{code} The Sds code.
\manparameterentry{{\mantt{>}}}{mode}{mode}  {\mantt{IF}} true,then return %
things like ``{\mantt{SDS\_{}STRUCT}}''.
      				If false, then return things link
      				``Int'', ``Struct'' etc.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status.

\end{manparametertable}
\manroutineitem{Support}{Tony Farrell, {AAO}}
\manroutineitem{Version date}{18-Apr-97}
\end{manroutinedescription}
\manroutine{SdsWrite}{Write an {\mantt{SDS}} object to a file}{SdsWrite}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Write an {\mantt{SDS}} object to a file

\manroutineitem{Description}{}
      Given an identifier to an internal {\mantt{SDS}} object, write it to
      a file. The file can be read back using SdsRead.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void SdsWrite(SdsIdType id, char *filename, StatusType *status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType}  The identifier to the object %
to be output
\manparameterentry{{\mantt{>}}}{filename}{char*} The name of the file into %
which the object
                              will be written
\manparameterentry{{\mantt{!}}}{status}{long*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}The identifier is invalid
\mantwocolumnentry{{\mantt{SDS\_{}\_{}EXTERN}}}The object is external
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for output %
buffer
\mantwocolumnentry{{\mantt{SDS\_{}\_{}FOPEN}}}Error opening the file
\mantwocolumnentry{{\mantt{SDS\_{}\_{}FWRITE}}}Error writing the file
\end{mantwocolumntable}
\manroutineitem{Prior requirements}{}
      None.

\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{31-Jan-92}
\end{manroutinedescription}


\manroutine{SdsCompiler}{Compile a C structure definition to create an {\mantt{%
SDS}} structure.}{SdsCompiler}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Compile a C structure definition to create an {\mantt{SDS}} structure.

\manroutineitem{Description}{}
      When given a string containing a valid C structure definition,
      this routine will create a Sds version of the structure and return
      its id.  This routine is just a run time hook into the ``sdsc'' program.

	Note, that this routines generated by lex and yacc and hence uses
	any external names in the code generated by those programs.


\manroutineitem{Declaration}{}
	void SdsCompiler(char *string, int messages, int intas32bit, SdsIdType *id, %
StatusType *status);

\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{string}{char {\mantt{*}}}  A string containing %
a C structure declaration
\manparameterentry{{\mantt{>}}}{messages}{int}	If true, then in addition to %
setting status,
			messages will be written to the stderr when
			parsing error occur.  This may help in debugging as
			only one status value can be returned.  There are
			two possible values
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}COMP\_{}MESS\_{}ERROR}}}Output messages when %
status
				would be set.
\mantwocolumnentry{{\mantt{SDS\_{}COMP\_{}MESS\_{}WARN}}}Inaddition to error %
messages,
				output warnings.
\end{mantwocolumntable}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{intas32bit}{int} Set true to treat ambiguous %
int declarations as
			32 bit ints.  Clear to treat them as short ints.
\manparameterentry{{\mantt{<}}}{id}{SdsIdType {\mantt{*}}} The id of the %
created structure.
\manparameterentry{{\mantt{!}}}{status}{StatusType {\mantt{*}}} Modified status.
\end{manparametertable}
\manroutineitem{Possible failure codes are}{}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}INVPRIMTYPE}}}Invalid primitive type code.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}INVSTRUCTDEF}}}Invalid structure %
definition.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}SYNTAX}}}Parser syntax error.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}INVSTRUCTURE}}}Invalid structure.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}INVTYPETYPE}}}Invalid typedef type.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}STRUCTMULTDEF}}}Multiply defined %
structure.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}INVINT}}}Invalid integer.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}INVTYPE}}}Invalid type.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}INVINPUT}}}Invalid input.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}STRUCTARRAY}}}Array of structures.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}MAXDIMS}}}Exceeded maximum number of %
dimensions.
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOINPUT}}}String was empty.
\end{mantwocolumntable}
\manroutineitem{Prior requirements}{}
	None

\manroutineitem{Support}{Tony Farrell, {\mantt{AAO}}}
\manroutineitem{Version date}{17-Jun-92}
\end{manroutinedescription}




\newpage
\section{ARG Function Descriptions}
\label{arg-functions}

\manroutine{ArgCvt}{Convert from one scaler {\mantt{SDS}} type to Another.}{%
ArgCvt}
\begin{manroutinedescription}
\manroutineitem{Function}{}
	Convert from one scaler {\mantt{SDS}} type to Another.

\manroutineitem{Description}{}
	This routine meets requirements for a general type conversion
	between Sds scaler types.  There are three classes of scalars

\begin{manenumerate}
\manenumerateitem{1.}Signed Integers
\manenumerateitem{2.}Unsigned Integers
\manenumerateitem{3.}Real (floating point) values

\end{manenumerate}
	Within each class, Sds can represent various types.  For example-
	Sds supports {\mantt{SDS\_{}BYTE}}, {\mantt{SDS\_{}SHORT}} {\mantt{SDS\_{}INT}%
} and {\mantt{SDS\_{}I64}} versions of
	the Signed integer class.  The difference is the number of bytes
	required for
	each one.
	
	This routine does a three part conversion-
\begin{manenumerate}
\manenumerateitem{1.}Convert the source type to the largest type of the same %
class
		    (char, short {\mantt{->}} long int)
		    (unsigned char, unsigned short {\mantt{->}} unsigned long int)
		    (float {\mantt{->}} double )
	
 
\manenumerateitem{2.}Convert the value above to the largest type of the %
destination
		class.

\manenumerateitem{3.}Convert the value in 2 to the actual destination type.

\end{manenumerate}
        Range errors are possible during the conversions.


	The source/destination for a conversion can be the address of
	a value of the appropiate type or it may be an Sds item.

	When specifing the address of the value, you must specify the
	type. ({\mantt{SDS\_{}CHAR}}, {\mantt{SDS\_{}INT}}, {\mantt{SDS\_{}UINT}} etc. %
 (Not {\mantt{SDS\_{}STRUCT}})).
	Additional type codes - {\mantt{ARG\_{}STRING}}/{\mantt{ARG\_{}STRING2}} - %
can be speicifed
	indicating the source or destination is a null terminated string while
	should/will contain a representation of the number.  (If both source
	and destination are strings, then a simple string copy is done.)
	A {\mantt{ARG\_{}STRING2}} type differs in only when the source is a {\mantt{%
FLOAT}} or
	{\mantt{DOUBLE}} value.  When {\mantt{ARG\_{}STRING}} is used, the maximum %
number of
	decimal digits is retrieved whilst when {\mantt{ARG\_{}STRING2}} is used, 6 %
is used
	for {\mantt{FLOAT}} and 10  for double.  (Note that a type of {\mantt{SDS\_{}%
CHAR}}
	represents a single character, not a string of characters)
	
	
	To specify an Sds item as the source/destination, supply the
	address of the Sds id of the item in the appropiate address argument.
	Suppy {\mantt{ARG\_{}SDS}} as the corresponding type code.  The Sds id must
	describe a Scaler item, expect if it is a one dimensional
	character array.  In this case, it is considered a character string.
	Source strings must be null terminated.

	Invalid conversions result in status being set to {\mantt{ARG\_{}\_{}CNVERR}} %
and
	an error being reported using ErsRep.

	The ranges of integer types are determined by the range acceptable to
	{\mantt{SDS}}.  The ranges of real types are determined by the archecture
	on which the machine is running.
 

	Types of {\mantt{SDS\_{}INT}} and {\mantt{SDS\_{}UINT}} indicate the relevant %
item is a long
	int (which may be 32 or 64 bits, depending upon the machine and
	compiler being used).  Note that if the machine does not support
	64 bits integers then 64bit values with the high 32bits set to
	non-zero values cannot be handled - an error is returned.

\manroutineitem{Language}{}
      C

\manroutinebreakitem{Call}{}
      (Void) {\mantt{=}} ArgCvt (SrcAddr, SrcType, DstType, DstAddr, DstLen, %
status)

\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{SrcAddr}{void {\mantt{*}}}     Address of the %
source data or of an
					Sds item id.
\manparameterentry{{\mantt{>}}}{SrcType}{SdsCodeType} Type of the source data.
\manparameterentry{{\mantt{>}}}{DstType}{SdsCodeType} Type of the destination %
data.
\manparameterentry{{\mantt{>}}}{DstAddr}{void {\mantt{*}}}     Address of the %
destination or of an
					Sds item id.
\manparameterentry{{\mantt{>}}}{DstLen}{int}	     Length of the destination in %
bytes.
			    If DstType  is {\mantt{ARG\_{}SDS}}, then this is ignored.
\manparameterentry{{\mantt{!}}}{status}{StatusType {\mantt{*}}} Modified status.

\end{manparametertable}
\manroutineitem{Include files}{Arg.h}
\manroutineitem{External functions used}{}
\begin{manfunctiontable}
\manfunctionentry{ErsRep}{Ers}   Report an error.
\manfunctionentry{ErsSPrintf}{Ers}   Format a string into a buffer.
\manfunctionentry{strtol}{{\mantt{CRTL}}}  Convert a decimal string to a long.
\manfunctionentry{strtoul}{{\mantt{CRTL}}}  Convert a decimal string to an %
unsigned long.
\manfunctionentry{strtod}{{\mantt{CRTL}}}  Convert a decimal string to a double.
\manfunctionentry{strncpy}{{\mantt{CRTL}}}  Copy one string to another
\manfunctionentry{strlen}{{\mantt{CRTL}}}  Get the length of a string.
\end{manfunctiontable}
\manroutineitem{External values used}{}
      none
\manroutineitem{Prior requirements}{}
      none

\manroutineitem{Support}{Tony Farrell, {\mantt{AAO}}}
\end{manroutinedescription}
\manroutine{ArgDelete}{Delete an argument structure}{ArgDelete}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Delete an argument structure

\manroutineitem{Description}{}
      Delete an argument structure and free its identifier
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgDelete(SdsIdType id, const StatusType {\mantt{*}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure to %
be deleted.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid Identifier
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{7-Apr-92}
\end{manroutinedescription}
\manroutine{ArgFind}{Call SdsFind, but report any error using ErsRep.}{ArgFind}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Call SdsFind, but report any error using ErsRep.

\manroutineitem{Description}{}
      This routine simply calls SdsFind, but if SdsFind returns a bad
      status, then this routine reports the name of the item
      SdsFind was trying to find.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
       void ArgFind(SdsIdType parent\_{}id, char *name, SdsIdType *id,
         StatusType {\mantt{*}}  status)

\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{parent\_{}id}{SdsIdType} Identifier of the %
structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be found.
\manparameterentry{{\mantt{<}}}{id}{SdsIdType*} Identifier to the component.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOTSTRUCT}}}parent\_{}id not a structure
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOITEM}}}No item with that name
\end{mantwocolumntable}
\manroutineitem{Support}{Tony Farrell, {AAO}}
\manroutineitem{See Also}{SdsFind().}
\manroutineitem{Version date}{14-Apr-98}
\end{manroutinedescription}
\manroutine{ArgGetString}{Get a character string item from an argument %
structure}{ArgGetString}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Get a character string item from an argument structure

\manroutineitem{Description}{}
      A character string item is read from a named component within the
      specified argument structure.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgGetString(SdsIdType id, const char *name, long len,char *value, %
const StatusType {\mantt{*}}  status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be read %
from.
\manparameterentry{{\mantt{>}}}{len}{long}  Length of buffer to receive string.
\manparameterentry{{\mantt{<}}}{value}{char*} Character string buffer to read %
into.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid Identifier
\mantwocolumnentry{{\mantt{ARG\_{}\_{}NOTSTRING}}}Item is not a string
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{28-Mar-92}
\end{manroutinedescription}
\manroutine{ArgGetc}{Get a character item from an argument structure}{ArgGetc}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Get a character item from an argument structure

\manroutineitem{Description}{}
      A character item is read from a named component within the
      specified argument structure. The item is converted to character
      type if necessary.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgGetc(SdsIdType id, const char *name, char *value, const %
StatusType {\mantt{*}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be read %
from.
\manparameterentry{{\mantt{>}}}{value}{char*}  Character variable to read into.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid Identifier
\mantwocolumnentry{{\mantt{ARG\_{}\_{}NOTSCALAR}}}Item is not a scalar
\mantwocolumnentry{{\mantt{ARG\_{}\_{}CNVERR}}}Type conversion error
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{27-Mar-92}
\end{manroutinedescription}
\manroutine{ArgGetd}{Get a double floating point item from an argument %
structure}{ArgGetd}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Get a double floating point item from an argument structure

\manroutineitem{Description}{}
      A double floating point item is read from a named component within the
      specified argument structure. The item is converted to double
      type if necessary.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgGetd(SdsIdType id, const char *name, double *value, const %
StatusType {\mantt{*}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be read %
from.
\manparameterentry{{\mantt{>}}}{value}{double*} Double variable to read into.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid Identifier
\mantwocolumnentry{{\mantt{ARG\_{}\_{}NOTSCALAR}}}Item is not a scalar
\mantwocolumnentry{{\mantt{ARG\_{}\_{}CNVERR}}}Type conversion error
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{27-Mar-92}
\end{manroutinedescription}
\manroutine{ArgGetf}{Get a floating point item from an argument structure}{%
ArgGetf}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Get a floating point item from an argument structure

\manroutineitem{Description}{}
      A floating point item is read from a named component within the
      specified argument structure. The item is converted to float
      type if necessary.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgGetf(SdsIdType id, const char *name, float *value, const %
StatusType {\mantt{*}}  status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be read %
from.
\manparameterentry{{\mantt{>}}}{value}{float*} Float variable to read into.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid Identifier
\mantwocolumnentry{{\mantt{ARG\_{}\_{}NOTSCALAR}}}Item is not a scalar
\mantwocolumnentry{{\mantt{ARG\_{}\_{}CNVERR}}}Type conversion error
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{27-Mar-92}
\end{manroutinedescription}
\manroutine{ArgGeti}{Get an integer item from an argument structure}{ArgGeti}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Get an integer item from an argument structure

\manroutineitem{Description}{}
      A long integer integer item is read from a named component within the
      specified argument structure. The item is converted to long integer
      type if necessary.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgGeti(SdsIdType id, const char *name, long *value, const %
StatusType {\mantt{*}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be read %
from.
\manparameterentry{{\mantt{>}}}{value}{long*} Long variable to read into.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid Identifier
\mantwocolumnentry{{\mantt{ARG\_{}\_{}NOTSCALAR}}}Item is not a scalar
\mantwocolumnentry{{\mantt{ARG\_{}\_{}CNVERR}}}Type conversion error
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{27-Mar-92}
\end{manroutinedescription}
\manroutine{ArgGeti64}{Get a 64 bit integer item from an argument structure}{%
ArgGeti64}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Get a 64 bit integer item from an argument structure

\manroutineitem{Description}{}
      A 64 bit integer integer item is read from a named component within the
      specified argument structure. The item is converted to 64 bit integer
      type if necessary.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgGeti64(SdsIdType id, const char *name, {\mantt{INT64}} *value, %
const StatusType {\mantt{*}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be read %
from.
\manparameterentry{{\mantt{>}}}{value}{{\mantt{INT64*}}} Long variable to read %
into.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid Identifier
\mantwocolumnentry{{\mantt{ARG\_{}\_{}NOTSCALAR}}}Item is not a scalar
\mantwocolumnentry{{\mantt{ARG\_{}\_{}CNVERR}}}Type conversion error
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{27-Mar-92}
\end{manroutinedescription}
\manroutine{ArgGets}{Get a short integer item from an argument structure}{%
ArgGets}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Get a short integer item from an argument structure

\manroutineitem{Description}{}
      A short integer item is read from a named component within the
      specified argument structure. The item is converted to short
      type if necessary.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgGets(SdsIdType id, const char *name, short *value, const %
StatusType {\mantt{*}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be read %
from.
\manparameterentry{{\mantt{>}}}{value}{short*}  Short variable to read into.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid Identifier
\mantwocolumnentry{{\mantt{ARG\_{}\_{}NOTSCALAR}}}Item is not a scalar
\mantwocolumnentry{{\mantt{ARG\_{}\_{}CNVERR}}}Type conversion error
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{27-Mar-92}
\end{manroutinedescription}
\manroutine{ArgGetu}{Get an unsigned integer item from an argument structure}{%
ArgGetu}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Get an unsigned integer item from an argument structure

\manroutineitem{Description}{}
      An unsigned long integer item is read from a named component within the
      specified argument structure. The item is converted to unsigned long
      type if necessary.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgGetu(SdsIdType id, const char *name, unsigned long *value, const %
StatusType {\mantt{*}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be read %
from.
\manparameterentry{{\mantt{>}}}{value}{unsigned long*} Unsigned long variable %
to read into.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid Identifier
\mantwocolumnentry{{\mantt{ARG\_{}\_{}NOTSCALAR}}}Item is not a scalar
\mantwocolumnentry{{\mantt{ARG\_{}\_{}CNVERR}}}Type conversion error
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{27-Mar-92}
\end{manroutinedescription}
\manroutine{ArgGetu64}{Get an unsigned 64bit integer item from an argument %
structure}{ArgGetu64}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Get an unsigned 64bit integer item from an argument structure

\manroutineitem{Description}{}
      An unsigned 64bit integer item is read from a named component within the
      specified argument structure. The item is converted to unsigned 64bit
      type if necessary.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgGetu64(SdsIdType id, const char *name, {\mantt{UINT64}} *value, %
const StatusType {\mantt{*}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be read %
from.
\manparameterentry{{\mantt{>}}}{value}{{\mantt{UINT64*}}} Unsigned 64bit %
variable to read into.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid Identifier
\mantwocolumnentry{{\mantt{ARG\_{}\_{}NOTSCALAR}}}Item is not a scalar
\mantwocolumnentry{{\mantt{ARG\_{}\_{}CNVERR}}}Type conversion error
\end{mantwocolumntable}
\manroutineitem{Support}{Tony Farrell, {AAO}}
\manroutineitem{Version date}{10-Aug-1995}
\end{manroutinedescription}
\manroutine{ArgGetus}{Get an unsigned short integer item from an argument %
structure}{ArgGetus}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Get an unsigned short integer item from an argument structure

\manroutineitem{Description}{}
      An unsigned short integer item is read from a named component within the
      specified argument structure. The item is converted to unsigned short
      type if necessary.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgGetus(SdsIdType id, const char *name, unsigned short *value, %
const StatusType {\mantt{*}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be read %
from.
\manparameterentry{{\mantt{>}}}{value}{unsigned short*}  Short variable to %
read into.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid Identifier
\mantwocolumnentry{{\mantt{ARG\_{}\_{}NOTSCALAR}}}Item is not a scalar
\mantwocolumnentry{{\mantt{ARG\_{}\_{}CNVERR}}}Type conversion error
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{27-Mar-92}
\end{manroutinedescription}
\manroutine{ArgLook}{Look at the contents of a string}{ArgLook}
\begin{manroutinedescription}
\manroutineitem{Function}{}
	Look at the contents of a string
	and determined if it can be represented as a number.

\manroutineitem{Description}{}
	A common requirement in user interfaces is to convert a
	string containing a number to the machine representation of
	that number.  This routine determines if this is possible and
	if so, what type the string can be converted to.

\begin{manenumerate}
\manenumerateitem{1.}If the string has the format - [+{\mantt{-}}]nnn, where %
nnn means any
	number of decimal digits, this routine beleives it can be
	be represented as an integer.
\end{manenumerate}

\begin{manenumerate}
\manenumerateitem{2.}If the string has the format -  [+{\mantt{-}}]nnn[.nnn][{%
e|E}[+/-]nnn],
	where nnn means nay number of decimal digites, this routine
	beleives it can be represented as a real.
\end{manenumerate}

	The actual ability to represent the number in a given machine type
	is dependent on the size of the number.

	If MinFlag is flase and the string has the format of 1, then DstType
	is set to  {\mantt{SDS\_{}INT}}, except if USFlag is set true, In which
	case DstType is set to {\mantt{SDS\_{}UINT}} (unless the number is negative).

	If MinFlag is false and the string has the format of 2, then
	DstType is set to {\mantt{SDS\_{}DOUBLE}}.

	If MinFlag is true, then the routine attempts to determine the
	smallest size of the required type which can be used to represent
	the number.  If base type ({\mantt{INT}} or {\mantt{REAL}}) is determined as %
per
	when MinFlag is false.  The system then tries to convert the
	value to a number of that type using ArgCvt.  If this is successfull,
	then it looks at the resulting values and determines the smallest
	type which can be used to represet the number.

	If the string is not a valid number (or when MinFlag is true, cannot be
	represented in the largest type) then DstType is set to {\mantt{ARG\_{}STRING}%
}.

	Any precedding white space in the string is ignored, but
	trailing white space is not allowed.

\manroutineitem{Language}{}
      C

\manroutinebreakitem{Call}{}
      (Void) {\mantt{=}} ArgLook (SrcAddr, USFlag, MinFlag, DstType , status)

\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{SrcAddr}{char {\mantt{*}}}     Address of the %
source data.
\manparameterentry{{\mantt{>}}}{USFlag}{int}	If true, integers are unsigned %
unless
				they include a minus sign.  If false,
				integers are always signed.
\manparameterentry{{\mantt{>}}}{MinFlag}{int}   If true, then find the %
smallest type of the
				appropiate class which can represent this
				time.  E.g., use float instead of double
				if possible.  This is a more expensive operation
				as ArgLook must invoke ArgCvt to do a conversion
				in order to determine this.
\manparameterentry{{\mantt{<}}}{DstType}{SdsCodeType {\mantt{*}}}	     Type of %
the destination.
\manparameterentry{{\mantt{!}}}{status}{Long int {\mantt{*}}} Modified status.

\end{manparametertable}
\manroutineitem{Include files}{Arg.h}
\manroutineitem{External functions used}{}
\begin{manfunctiontable}
\manfunctionentry{ErsPush}{Ers}   Increment error context.
\manfunctionentry{ErsPop}{Ers}   Decrement error context.
\manfunctionentry{ErsAnnul}{Ers}   Annull error messages.
\manfunctionblank
\manfunctionentry{ArgCvt}{Arg}   Convert a value from one type to another.
\manfunctionblank
\manfunctionentry{isspace}{{\mantt{CRTL}}}  Is a character a which space %
character.
\manfunctionentry{isdigit}{{\mantt{CRTL}}}  Is a character a digit.
\end{manfunctiontable}
\manroutineitem{External values used}{}
      none
\manroutineitem{Prior requirements}{}
      none

\manroutineitem{Support}{Tony Farrell, {\mantt{AAO}}}
\end{manroutinedescription}
\manroutine{ArgNew}{Create a new argument structure}{ArgNew}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Create a new argument structure

\manroutineitem{Description}{}
      Creates a new structure to hold arguments and return an
      identifier to it
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgNew(SdsIdType *id, long *status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{<}}}{id}{SdsIdType*} Identifier to the created %
structure
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{26-Mar-92}
\end{manroutinedescription}
\manroutine{ArgPutString}{Put a character string item into an argument %
structure}{ArgPutString}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Put a character string item into an argument structure

\manroutineitem{Description}{}
      A character string item is written into a named component within the
      specified argument structure. The component is created if it
      does not currently exist.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgPutString(SdsIdType id, char *name, char *value, const %
StatusType {\mantt{*}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be %
written to.
\manparameterentry{{\mantt{>}}}{value}{char*} Null terminated string to be %
written.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid Identifier
\mantwocolumnentry{{\mantt{ARG\_{}\_{}NOTSTRING}}}Item is not a string
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{28-Mar-92}
\end{manroutinedescription}
\manroutine{ArgPutc}{Put a character item into an argument structure}{ArgPutc}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Put a character item into an argument structure

\manroutineitem{Description}{}
      A character item is written into a named component within the
      specified argument structure. The component is created if it
      does not currently exist.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgPutc(SdsIdType id, const char *name, char value, const %
StatusType {\mantt{*}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be %
written to.
\manparameterentry{{\mantt{>}}}{value}{char}  Character value to be written.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid Identifier
\mantwocolumnentry{{\mantt{ARG\_{}\_{}NOTSCALAR}}}Item is not a scalar
\mantwocolumnentry{{\mantt{ARG\_{}\_{}CNVERR}}}Type conversion error
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{26-Mar-92}
\end{manroutinedescription}
\manroutine{ArgPutd}{Put a double floating point item into an argument %
structure}{ArgPutd}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Put a double floating point item into an argument structure

\manroutineitem{Description}{}
      A double item is written into a named component within the
      specified argument structure. The component is created if it
      does not currently exist.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgPutd(SdsIdType id, const char *name, double value, const %
StatusType {\mantt{*}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be %
written to.
\manparameterentry{{\mantt{>}}}{value}{double} Floating point value to be %
written.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid Identifier
\mantwocolumnentry{{\mantt{ARG\_{}\_{}NOTSCALAR}}}Item is not a scalar
\mantwocolumnentry{{\mantt{ARG\_{}\_{}CNVERR}}}Type conversion error
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{27-Mar-92}
\end{manroutinedescription}
\manroutine{ArgPutf}{Put a floating point item into an argument structure}{%
ArgPutf}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Put a floating point item into an argument structure

\manroutineitem{Description}{}
      A floating point item is written into a named component within the
      specified argument structure. The component is created if it
      does not currently exist.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgPutf(SdsIdType id, const char *name, float value, const %
StatusType {\mantt{*}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be %
written to.
\manparameterentry{{\mantt{>}}}{value}{float} Floating point value to be %
written.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid Identifier
\mantwocolumnentry{{\mantt{ARG\_{}\_{}NOTSCALAR}}}Item is not a scalar
\mantwocolumnentry{{\mantt{ARG\_{}\_{}CNVERR}}}Type conversion error
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{27-Mar-92}
\end{manroutinedescription}
\manroutine{ArgPuti}{Put a integer item into an argument structure}{ArgPuti}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Put a integer item into an argument structure

\manroutineitem{Description}{}
      An integer item is written into a named component within the
      specified argument structure. The component is created if it
      does not currently exist.
 
      Note, when this call has to create the item, it always creates
      32bit integer {\mantt{SDS}} items, regardless of the size of long int on
      the machine.  Use ArgPuti64 to create 64bit integer items.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgPuti(SdsIdType id, const char *name, long value, const %
StatusType {\mantt{*}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be %
written to.
\manparameterentry{{\mantt{>}}}{value}{long} Integer value to be written.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid Identifier
\mantwocolumnentry{{\mantt{ARG\_{}\_{}NOTSCALAR}}}Item is not a scalar
\mantwocolumnentry{{\mantt{ARG\_{}\_{}CNVERR}}}Type conversion error
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{27-Mar-92}
\end{manroutinedescription}
\manroutine{ArgPuti64}{Put a 64 bit integer item into an argument structure}{%
ArgPuti64}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Put a 64 bit integer item into an argument structure

\manroutineitem{Description}{}
      A 64 bit integer item is written into a named component within the
      specified argument structure. The component is created if it
      does not currently exist.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgPuti64(SdsIdType id, const char *name, {\mantt{INT64}} value, %
const StatusType {\mantt{*}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be %
written to.
\manparameterentry{{\mantt{>}}}{value}{{\mantt{INT64}}} 64 bit integer value %
to be written.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid Identifier
\mantwocolumnentry{{\mantt{ARG\_{}\_{}NOTSCALAR}}}Item is not a scalar
\mantwocolumnentry{{\mantt{ARG\_{}\_{}CNVERR}}}Type conversion error
\end{mantwocolumntable}
\manroutineitem{Support}{Tony Farrell, {AAO}}
\manroutineitem{Version date}{10-Aug-95}
\end{manroutinedescription}
\manroutine{ArgPuts}{Put a short integer item into an argument structure}{%
ArgPuts}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Put a short integer item into an argument structure

\manroutineitem{Description}{}
      A short integer item is written into a named component within the
      specified argument structure. The component is created if it
      does not currently exist.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgPuts(SdsIdType id, const char *name, short value, const %
StatusType {\mantt{*}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be %
written to.
\manparameterentry{{\mantt{>}}}{value}{short} Short integer value to be written.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid Identifier
\mantwocolumnentry{{\mantt{ARG\_{}\_{}NOTSCALAR}}}Item is not a scalar
\mantwocolumnentry{{\mantt{ARG\_{}\_{}CNVERR}}}Type conversion error
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{27-Mar-92}
\end{manroutinedescription}
\manroutine{ArgPutu}{Put an unsigned integer item into an argument structure}{%
ArgPutu}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Put an unsigned integer item into an argument structure

\manroutineitem{Description}{}
      An unsigned integer item is written into a named component within the
      specified argument structure. The component is created if it
      does not currently exist.

      Note, when this call has to create the item, it always creates
      32bit unsigned integer {\mantt{SDS}} items, regardless of the size of %
long int on
      the machine.  Use ArgPutui64 to create 64bit unsigned integer items.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgPutu(SdsIdType id, const char *name, unsigned long value, const %
StatusType {\mantt{*}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be %
written to.
\manparameterentry{{\mantt{>}}}{value}{unsigned long} Unsigned integer value %
to be written.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid Identifier
\mantwocolumnentry{{\mantt{ARG\_{}\_{}NOTSCALAR}}}Item is not a scalar
\mantwocolumnentry{{\mantt{ARG\_{}\_{}CNVERR}}}Type conversion error
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{27-Mar-92}
\end{manroutinedescription}
\manroutine{ArgPutu64}{Put an unsigned 64 bit integer item into an argument %
structure}{ArgPutu64}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Put an unsigned 64 bit integer item into an argument structure

\manroutineitem{Description}{}
      An unsigned 64 bit integer item is written into a named component
      within the specified argument structure. The component is created if it
      does not currently exist.

\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgPutu64(SdsIdType id, const char *name, unsigned long value, %
const StatusType {\mantt{*}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be %
written to.
\manparameterentry{{\mantt{>}}}{value}{{\mantt{UINT64}}} Unsigned integer %
value to be written.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid Identifier
\mantwocolumnentry{{\mantt{ARG\_{}\_{}NOTSCALAR}}}Item is not a scalar
\mantwocolumnentry{{\mantt{ARG\_{}\_{}CNVERR}}}Type conversion error
\end{mantwocolumntable}
\manroutineitem{Support}{Tony Farrell, {AAO}}
\manroutineitem{Version date}{10-Aug-95}
\end{manroutinedescription}
\manroutine{ArgPutus}{Put an unsigned short integer item into an argument %
structure}{ArgPutus}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Put an unsigned short integer item into an argument structure

\manroutineitem{Description}{}
      An unsigned short item is written into a named component within the
      specified argument structure. The component is created if it
      does not currently exist.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgPutus(SdsIdType id, const char *name, unsigned short value, %
const StatusType {\mantt{*}} status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure.
\manparameterentry{{\mantt{>}}}{name}{char*} Name of the component to be %
written to.
\manparameterentry{{\mantt{>}}}{value}{unsigned short} Unsigned short value to %
be written.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status. Possible %
failure codes are:
\end{manparametertable}
\begin{mantwocolumntable}
\mantwocolumnentry{{\mantt{SDS\_{}\_{}NOMEM}}}Insufficient memory for creation
\mantwocolumnentry{{\mantt{SDS\_{}\_{}BADID}}}Invalid Identifier
\mantwocolumnentry{{\mantt{ARG\_{}\_{}NOTSCALAR}}}Item is not a scalar
\mantwocolumnentry{{\mantt{ARG\_{}\_{}CNVERR}}}Type conversion error
\end{mantwocolumntable}
\manroutineitem{Support}{Jeremy Bailey, {AAO}}
\manroutineitem{Version date}{27-Mar-92}
\end{manroutinedescription}
\manroutine{ArgSdsList}{List an Sds structure calling a user supplied callback.%
}{ArgSdsList}
\begin{manroutinedescription}
\manroutineitem{Function}{}
  	List an Sds structure calling a user supplied callback.

\manroutineitem{Description}{}
 	This routine does basically the same job as SdsList, but invokes
 	a user supplied callback routine to do the actual output.  This
 	allows the output to be directed anywhere required by the user,
 	not just to stdout as in SdsList.
 
 	The output routine is called for each line to be output.  Note that
 	although close to the output of SdsList, this output of this routine
 	is not exactly the same.
 
\manroutineitem{Language}{}
      C

\manroutineitem{Declaration}{}
      void ArgSdsList(id, buflen, buffer, func, client\_{}data, status)
 
\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure.
\manparameterentry{{\mantt{>}}}{buflen}{unsigned int} Length of buffer.  If %
zero, then malloc
      				a buffer of 400 bytes.  If lines exceed this
      				length, then they are truncated correctly
      				before calling the output routine.
\manparameterentry{{\mantt{>}}}{buffer}{char {\mantt{*}}}	A buffer to be used %
by this routine to print
      				the output into.  It is passed directly to
      				the output function.   Since the length of
      				each line can be quite long (particularly
      				with arrays) we allow the user to specify
      				how much of a line he is interested in.  For
      				example, if outputing to a terminal, you might
      				only specify an 80 byte buffer.  If not
      				supplied, we will malloc buflen bytes.
\manparameterentry{{\mantt{>}}}{func}{ArgListFunctType} A function to called %
to output each
      				line.  It is passed the client data item,
      				the address of the buffer and a modified
      				status item.
 
\manparameterentry{{\mantt{>}}}{client\_{}data}{void {\mantt{*}}} Passed %
directly to func.
\manparameterentry{{\mantt{!}}}{status}{StatusType*} Modified status.

\end{manparametertable}
\manroutineitem{Support}{Tony Farrell, {\mantt{AAO}}}
\manroutineitem{Version date}{17-Apr-97}
\end{manroutinedescription}
\manroutine{ArgToString}{Take an Sds structure and write it to a string.}{%
ArgToString}
\begin{manroutinedescription}
\manroutineitem{Function}{}
	Take an Sds structure and write it to a string.

\manroutineitem{Description}{}
	The structure is examined recursively.  It scraler or string
	item found is written to the output string, with a space
	separating each item.  No structure is maintined to the data.

	The normal use of the function is to convert what is expected to
	be simple structures in to something suitable for output to the
	user.
 

\manroutineitem{Language}{}
      C

\manroutinebreakitem{Call}{}
      (Void) {\mantt{=}} ArgToString (id,maxlen,length,string,status)

\manroutineitem{Parameters}{(``{\mantt{>}}'' input, ``{\mantt{!}}'' modified, `%
`W'' workspace, ``{\mantt{<}}'' output)}
\begin{manparametertable}
\manparameterentry{{\mantt{>}}}{id}{SdsIdType} Identifier to the structure to %
be deleted.
\manparameterentry{{\mantt{>}}}{maxlen}{Int}   Length of buffer to receive %
string.
\manparameterentry{{\mantt{!}}}{length}{Int {\mantt{*}}}	Set to zero on entry.  %
On exit, will
			    contain the actual length of the string.
\manparameterentry{{\mantt{<}}}{string}{Char {\mantt{*}}} Character strin g %
buffer to write to.
\manparameterentry{{\mantt{!}}}{status}{Long int {\mantt{*}}} Modified status.

\end{manparametertable}
\manroutineitem{Include files}{Arg.h}
\manroutineitem{External functions used}{}
\manroutineitem{External values used}{}
      none
\manroutineitem{Prior requirements}{}
      none

\manroutineitem{Support}{Tony Farrell, {\mantt{AAO}}}
\end{manroutinedescription}




\newpage
\section{SDS Fortran Subroutine Interface}
\label{SDS-fortran-interface}

\subsection{SDS subroutines}

%+
%  Name:
%     LAYOUT.TEX

%  Purpose:
%     Define Latex commands for laying out documentation produced by PROLAT.

%  Language:
%     Latex

%  Type of Module:
%     Data file for use by the PROLAT application.

%  Description:
%     This file defines Latex commands which allow routine documentation
%     produced by the SST application PROLAT to be processed by Latex. The
%     contents of this file should be included in the source presented to
%     Latex in front of any output from PROLAT. By default, this is done
%     automatically by PROLAT.

%  Notes:
%     The definitions in this file should be included explicitly in any file
%     which requires them. The \include directive should not be used, as it
%     may not then be possible to process the resulting document with Latex
%     at a later date if changes to this definitions file become necessary.

%  Authors:
%     RFWS: R.F. Warren-Smith (STARLINK)

%  History:
%     10-SEP-1990 (RFWS):
%        Original version.
%     10-SEP-1990 (RFWS):
%        Added the implementation status section.
%     12-SEP-1990 (RFWS):
%        Added support for the usage section and adjusted various spacings.
%     {enter_further_changes_here}

%  Bugs:
%     {note_any_bugs_here}

%-

%  Define length variables.
\newlength{\sstbannerlength}
\newlength{\sstcaptionlength}

%  Define a \tt font of the required size.
\newfont{\ssttt}{cmtt10 scaled 1095}

%  Define a command to produce a routine header, including its name,
%  a purpose description and the rest of the routine's documentation.
\newcommand{\sstroutine}[3]{
   \goodbreak
   \rule{\textwidth}{0.5mm}
   \vspace{-7ex}
   \newline
   \settowidth{\sstbannerlength}{{\Large {\bf #1}}}
   \setlength{\sstcaptionlength}{\textwidth}
   \addtolength{\sstbannerlength}{0.5em} 
   \addtolength{\sstcaptionlength}{-2.0\sstbannerlength}
   \addtolength{\sstcaptionlength}{-4.45pt}
   \parbox[t]{\sstbannerlength}{\flushleft{\Large {\bf #1}}}
   \parbox[t]{\sstcaptionlength}{\center{\Large #2}}
   \parbox[t]{\sstbannerlength}{\flushright{\Large {\bf #1}}}
   \begin{description}
      #3
   \end{description}
}

%  Format the description section.
\newcommand{\sstdescription}[1]{\item[Description:] #1}

%  Format the usage section.
\newcommand{\sstusage}[1]{\item[Usage:] \mbox{} \\[1.3ex] {\ssttt #1}}

%  Format the invocation section.
\newcommand{\sstinvocation}[1]{\item[Invocation:]\hspace{0.4em}{\tt #1}}

%  Format the arguments section.
\newcommand{\sstarguments}[1]{
   \item[Arguments:] \mbox{} \\
   \vspace{-3.5ex}
   \begin{description}
      #1
   \end{description}
}

%  Format the returned value section (for a function).
\newcommand{\sstreturnedvalue}[1]{
   \item[Returned Value:] \mbox{} \\
   \vspace{-3.5ex}
   \begin{description}
      #1
   \end{description}
}

%  Format the parameters section (for an application).
\newcommand{\sstparameters}[1]{
   \item[Parameters:] \mbox{} \\
   \vspace{-3.5ex}
   \begin{description}
      #1
   \end{description}
}

%  Format the examples section.
\newcommand{\sstexamples}[1]{
   \item[Examples:] \mbox{} \\
   \vspace{-3.5ex}
   \begin{description}
      #1
   \end{description}
}

%  Define the format of a subsection in a normal section.
\newcommand{\sstsubsection}[1]{\item[{#1}] \mbox{} \\}

%  Define the format of a subsection in the examples section.
\newcommand{\sstexamplesubsection}[1]{\item[{\ssttt #1}] \mbox{} \\}

%  Format the notes section.
\newcommand{\sstnotes}[1]{\item[Notes:] \mbox{} \\[1.3ex] #1}

%  Provide a general-purpose format for additional (DIY) sections.
\newcommand{\sstdiytopic}[2]{\item[{\hspace{-0.35em}#1\hspace{-0.35em}:}] \mbox{} \\[1.3ex] #2}

%  Format the implementation status section.
\newcommand{\sstimplementationstatus}[1]{
   \item[{Implementation Status:}] \mbox{} \\[1.3ex] #1}

%  Format the bugs section.
\newcommand{\sstbugs}[1]{\item[Bugs:] #1}

%  Format a list of items while in paragraph mode.
\newcommand{\sstitemlist}[1]{
  \mbox{} \\
  \vspace{-3.5ex}
  \begin{itemize}
     #1
  \end{itemize}
}

%  Define the format of an item.
\newcommand{\sstitem}{\item}

%  End of LAYOUT.TEX layout definitions.
%.

\sstroutine{
   SDS\_ACCESS
}{
   Return an identifier to an external object
}{
   \sstdescription{
      Make an external object (one exported by SDS\_EXPORT) accessible
      to SDS by returning an identifier to it.

      Any SDS operations which do not change the structure of the
      object may be performed on an external object. These include
      navigation operations (SDS\_FIND, SDS\_INDEX, SDS\_CELL), data
      access operations (SDS\_GET, SDS\_PUT, SDS\_POINTER) and
      inquiry operations (SDS\_INFO).

      Operations which are not permitted on an external object
      are those which add or remove components (SDS\_NEW, SDS\_DELETE),
      or write operations (SDS\_PUT or SDS\_POINTER) to data items which
      are currently undefined.

      Unlike SDS\_IMPORT, SDS\_ACCESS does not make a copy of the object.
      The object is accessed in place in the original buffer.
   }
   \sstinvocation{
      CALL SDS\_ACCESS( DATA, ID, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         DATA( $*$ ) = BYTE (Given)
      }{
         The buffer containing the object to be accessed.
      }
      \sstsubsection{
         ID = INTEGER (Returned)
      }{
         The identifier of the external object.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_NOTSDS    Not a valid SDS object.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory.
         }
      }
   }
}
\sstroutine{
   SDS\_CELL
}{
   Find component of a structure array
}{
   \sstdescription{
      Given the indices to a component of a structure array, return
      an identifier to it.
   }
   \sstinvocation{
      CALL SDS\_CELL( ARRAY\_ID, NINDICES, INDICES, ID, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ARRAY\_ID = INTEGER (Given)
      }{
         The identifier of the structure array
      }
      \sstsubsection{
         NINDICES = INTEGER (Given)
      }{
         Number if indices supplied in the array INDICES. This
         should be the same as the number of dimensions of the array
      }
      \sstsubsection{
         INDICES (NINDICES) = INTEGER (Given)
      }{
         An array of length NINDICES containing the indices to
         the component of the structure array
      }
      \sstsubsection{
         ID = INTEGER (Returned)
      }{
         The identifier of the new internal structure.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
              SDS\_\_BADID     The identifier is invalid.

            \sstitem
              SDS\_\_NOMEM     Insufficient memory.

            \sstitem
              SDS\_\_NOTARRAY  Not a strcture array.

            \sstitem
              SDS\_\_INDEXERR  Indices invalid.
         }
      }
   }
}
\sstroutine{
   SDS\_COPY
}{
   Make a copy of an object
}{
   \sstdescription{
      Make a copy of an object and return an identifier to the copy.
      The copy is a new top level object, the original object is
      unchanged by the operation.

      The object being copied can be either external or internal.
      The copy is always an internal object.
   }
   \sstinvocation{
      CALL SDS\_COPY( ID, COPY\_ID, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object to be copied.
      }
      \sstsubsection{
         COPY\_ID = INTEGER (Returned)
      }{
         The identifier of the new internal structure.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
              SDS\_\_BADID     The identifier is invalid.

            \sstitem
              SDS\_\_NOMEM     Insufficient memory.
         }
      }
   }
}
\sstroutine{
   SDS\_DELETE
}{
   Delete an object
}{
   \sstdescription{
       Delete an object, freeing any memory associated with it. Subsequent
       attempts to access the object through any identifier associated with
       it will return the SDS\_\_BADID status. A structure array element cannot
       be deleted. An attempt to do so will result in the SDS\_\_ILLDEL status.

      Deleting an object does not free the memory associated with the
      identifier referencing it. This memory can be freed with the
      SDS\_FREE\_ID function.
   }
   \sstinvocation{
      CALL SDS\_DELETE( ID, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object to be deleted.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     The identifier is invalid.

            \sstitem
             SDS\_\_EXTERN    Object is external.

            \sstitem
             SDS\_\_ILLDEL    Object cannot be deleted.
         }
      }
   }
}
\sstroutine{
   SDS\_EXPORT
}{
   Export an object
}{
   \sstdescription{
      Export an object into an external buffer.

      Once exported an object can be moved around in memory, written to
      a file etc., and subsequently returned to the SDS system either by using
      SDS\_IMPORT to import it back into the system, or SDS\_ACCESS, to access it
      as an external object.

      The original internal version of the
      object continues to exist, in addition to the external copy. All
      identifiers to the object continue to refer to the original internal
      copy.

      The length of the buffer required for SDS\_EXPORT can be determined
      by a call to SDS\_SIZE.
   }
   \sstinvocation{
      CALL SDS\_EXPORT( ID, LENGTH, DATA, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object to be exported.
      }
      \sstsubsection{
         LENGTH = INTEGER (Given)
      }{
         Size in bytes of the buffer.
      }
      \sstsubsection{
         DATA (LENGTH) = BYTE (Returned)
      }{
         The buffer into which the object will be exported
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     The identifier is invalid.

            \sstitem
             SDS\_\_TOOLONG   The object is too large for the buffer.

            \sstitem
             SDS\_\_EXTERN    Object is external.
         }
      }
   }
}
\sstroutine{
   SDS\_EXTRACT
}{
   Extract an object from a structure
}{
   \sstdescription{
      Extract an object from a structure. The extracted object becomes a
      new independent top level object. The object is deleted from
      the original structure.

      The identifier must not be that of a structure array component.

      If the identifier is already that of a top level object, then the
      function does nothing.
   }
   \sstinvocation{
      CALL SDS\_EXTRACT( ID, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object to be extracted
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     The identifier is invalid.

            \sstitem
             SDS\_\_EXTERN    Object is external.

            \sstitem
             SDS\_\_ILLDEL    Object cannot be extracted.
         }
      }
   }
}

\sstroutine{
   SDS\_FIND
}{
   Find a structure component by name
}{
   \sstdescription{
      Given the name of a component in a structure, return an identifier
      to the component.
   }
   \sstinvocation{
      CALL SDS\_FIND( PARENT\_ID, NAME, ID, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         PARENT\_ID = INTEGER (Given)
      }{
         Identifier of the structure
      }
      \sstsubsection{
         NAME = CHAR (Given)
      }{
         Name of the component to be found
      }
      \sstsubsection{
         ID = INTEGER (Returned)
      }{
         Identifier to the component
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_NOMEM     Insufficient memory.

            \sstitem
             SDS\_\_NOTSTRUCT PARENT\_ID not a structure.

            \sstitem
             SDS\_\_NOITEM    No item with that name.
         }
      }
   }
}


\sstroutine{
   SDS\_FIND\_BY\_PATH
}{
   Accesses a structued Sds item using a path name to the item.
}{
   \sstdescription{
        This function is passed the id of an Sds structure and a
        name describing an element in that sturcture using a dot separated
        format.  It returns the id of the element.  See the C routine
        SdsFindByPath for details of the naming format.

   }
   \sstinvocation{
      CALL SDS\_FIND\_BY\_PATH( PARENT\_ID, NAME, ID, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         PARENT\_ID = INTEGER (Given)
      }{
         Identifier of the structure
      }
      \sstsubsection{
         NAME = CHAR (Given)
      }{
         Name of the component to be found
      }
      \sstsubsection{
         ID = INTEGER (Returned)
      }{
         Identifier to the component
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_NOMEM     Insufficient memory.

            \sstitem
             SDS\_\_NOTSTRUCT PARENT\_ID not a structure.

            \sstitem
             SDS\_\_NOITEM    No item with that name.
         }
      }
   }
}


\sstroutine{
   SDS\_FLUSH
}{
   Flush data updated via a pointer
}{
   \sstdescription{
      If a primitive data item is accessed via SDS\_POINTER, and the data
      array updated via the returned pointer, then SDS\_FLUSH must be called
      to ensure that the data is updated in the original structure.

      This must be done since implementations on some machine architectures
      may have to use a copy of the data rather than the actual data when
      returning a pointer.
   }
   \sstinvocation{
      CALL SDS\_FLUSH( ID, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     Invalid Identifier.

            \sstitem
             SDS\_\_NOTPRIM   Not a primitive item.
         }
      }
   }
}

\sstroutine{
   SDS\_FREE\_ID
}{
    Free an identifer, so that its associated memory may be reused.
}{
   \sstdescription{
      Each identifier allocated by SDS uses memory.  To avoid excessive
      allocation of memory the SDS\_FREE\_ID function can be used to free
      the memory assocaited with an identifier that is no longer needed.
      When this is done, the memory will be re-used by SDS for a subsequent
      identifer when needed.  

      Note that if the identifer refers to a top-level structure, you
      should call SDS\_DELETE (for structures created using SDS\_NEW.)
      or SDS\_READ\_FREE (for structures created using SDS\_READ()) before
      calling SDS\_FREE\_ID to ensure all memory is recovered.  
   }
   \sstinvocation{
      CALL SDS\_FREE\_ID( ID, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier to be freeed
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     The identifier is invalid.

         }
      }
   }
}




\sstroutine{
   SDS\_GET
}{
   Read the data from an object
}{
   \sstdescription{
      The object may be a primitive item or a structure or structure array.
      Read the data from an item into a buffer. If the object is primitive
      data is transferred starting at the position in the item specified by
      offset, until the buffer if filled, or the end of the data array is
      reached.

      If the object is a structure or structure array, the data from all its
      primitive components are copied into the buffer in order of their
      position in the structure. Alignment adjustments are made as necessary
      to match the alignment of an C struct equivalent to the SDS structure.
      (Since these alignment requirements are machine dependent the actual
      sequence of bytes returned could be different on different machines).
      In the structure or structure array case the offset parameter is
      ignored.

      Note that the structures returned from SDS are designed to be
      used from C, and are not guaranteed to correctly match Fortran
      structures, in those implementations of Fortran which support a
      non-standard structure extension.

      If necessary (e.g. if the data originated on a machine with different
      architecture) the data for the object is converted (in place) from the
      format stored in the data item to that required for the local machine.
   }
   \sstinvocation{
      CALL SDS\_GET( ID, LENGTH, OFFSET, DATA, ACTLEN, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object
      }
      \sstsubsection{
         LENGTH = INTEGER (Given)
      }{
         Length in bytes of the buffer supplied to receive the data.
      }
      \sstsubsection{
         OFFSET = INTEGER (Given)
      }{
         Offset into the data at which to start
                    reading data. The offset is measured in units of
                    the size of each individual item in the array -
                    e.g. 4 bytes for an INT or 8 bytes for a DOUBLE.
                    The offset is zero to start at the beginning of the
                    array. This parameter is ignored if the object
                    is a structure or structure array.
      }
      \sstsubsection{
         DATA (LENGTH) = BYTE (Returned)
      }{
         Buffer to receive the data.
      }
      \sstsubsection{
         ACTLEN = INTEGER (Returned)
      }{
         Actual number of bytes transferred.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     Invalid Identifier.

            \sstitem
             SDS\_\_UNDEFINED Data undefined.
         }
      }
   }
}
\sstroutine{
   SDS\_GETC
}{
   Read character data from an object
}{
   \sstdescription{
      Read data from a primitive character object.
      Data is transferred starting at the position in the item specified by
      offset, until the buffer if filled, or the end of the data array is
      reached.

      An error will be returned if the item is not a primitive integer
      object.

      If necessary (e.g. if the data originated on a machine with different
      architecture) the data for the object is converted (in place) from the
      format stored in the data item to that required for the local machine.
   }
   \sstinvocation{
      CALL SDS\_GETC( ID, LENGTH, OFFSET, DATA, ACTLEN, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object
      }
      \sstsubsection{
         LENGTH = INTEGER (Given)
      }{
         Length of the buffer supplied to receive the data.
      }
      \sstsubsection{
         OFFSET = INTEGER (Given)
      }{
         Offset into the data at which to start
                    reading data.
                    The offset is zero to start at the beginning of the
                    array.
      }
      \sstsubsection{
         DATA (LENGTH) = CHARACTER (Returned)
      }{
         Buffer to receive the data.
      }
      \sstsubsection{
         ACTLEN = INTEGER (Returned)
      }{
         Actual number of elements transferred.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     Invalid Identifier.

            \sstitem
             SDS\_\_TYPE      Object not of character type.

            \sstitem
             SDS\_\_UNDEFINED Data undefined.
         }
      }
   }
}
\sstroutine{
   SDS\_GETD
}{
   Read double precision data from an object
}{
   \sstdescription{
      Read data from a primitive double precision object.
      Data is transferred starting at the position in the item specified by
      offset, until the buffer if filled, or the end of the data array is
      reached.

      An error will be returned if the item is not a primitive double
      precision object.

      If necessary (e.g. if the data originated on a machine with different
      architecture) the data for the object is converted (in place) from the
      format stored in the data item to that required for the local machine.
   }
   \sstinvocation{
      CALL SDS\_GETD( ID, LENGTH, OFFSET, DATA, ACTLEN, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object
      }
      \sstsubsection{
         LENGTH = INTEGER (Given)
      }{
         Length of the buffer supplied to receive the data.
      }
      \sstsubsection{
         OFFSET = INTEGER (Given)
      }{
         Offset into the data at which to start
                    reading data.
                    The offset is zero to start at the beginning of the
                    array.
      }
      \sstsubsection{
         DATA (LENGTH) = DOUBLE (Returned)
      }{
         Buffer to receive the data.
      }
      \sstsubsection{
         ACTLEN = INTEGER (Returned)
      }{
         Actual number of elements transferred.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     Invalid Identifier.

            \sstitem
             SDS\_\_TYPE      Object not of double type.

            \sstitem
             SDS\_\_UNDEFINED Data undefined.
         }
      }
   }
}
\sstroutine{
   SDS\_GETI
}{
   Read integer data from an object
}{
   \sstdescription{
      Read data from a primitive integer object.
      Data is transferred starting at the position in the item specified by
      offset, until the buffer if filled, or the end of the data array is
      reached.

      An error will be returned if the item is not a primitive integer
      object.

      If necessary (e.g. if the data originated on a machine with different
      architecture) the data for the object is converted (in place) from the
      format stored in the data item to that required for the local machine.
   }
   \sstinvocation{
      CALL SDS\_GETI( ID, LENGTH, OFFSET, DATA, ACTLEN, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object
      }
      \sstsubsection{
         LENGTH = INTEGER (Given)
      }{
         Length of the buffer supplied to receive the data.
      }
      \sstsubsection{
         OFFSET = INTEGER (Given)
      }{
         Offset into the data at which to start
                    reading data.
                    The offset is zero to start at the beginning of the
                    array.
      }
      \sstsubsection{
         DATA (LENGTH) = INTEGER (Returned)
      }{
         Buffer to receive the data.
      }
      \sstsubsection{
         ACTLEN = INTEGER (Returned)
      }{
         Actual number of elements transferred.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     Invalid Identifier.

            \sstitem
             SDS\_\_TYPE      Object not of integer type.

            \sstitem
             SDS\_\_UNDEFINED Data undefined.
         }
      }
   }
}
\sstroutine{
   SDS\_GETL
}{
   Read logical data from an object
}{
   \sstdescription{
      Read data from a primitive logical object.
      Data is transferred starting at the position in the item specified by
      offset, until the buffer if filled, or the end of the data array is
      reached.

      Since the SDS kernel does not support a logical type an integer
      item is used to represent Fortran logical values.
      An error will be returned if the item is not a primitive integer
      object.

      If necessary (e.g. if the data originated on a machine with different
      architecture) the data for the object is converted (in place) from the
      format stored in the data item to that required for the local machine.
   }
   \sstinvocation{
      CALL SDS\_GETL( ID, LENGTH, OFFSET, DATA, ACTLEN, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object
      }
      \sstsubsection{
         LENGTH = INTEGER (Given)
      }{
         Length of the buffer supplied to receive the data.
      }
      \sstsubsection{
         OFFSET = INTEGER (Given)
      }{
         Offset into the data at which to start
                    reading data.
                    The offset is zero to start at the beginning of the
                    array.
      }
      \sstsubsection{
         DATA (LENGTH) = LOGICAL (Returned)
      }{
         Buffer to receive the data.
      }
      \sstsubsection{
         ACTLEN = INTEGER (Returned)
      }{
         Actual number of elements transferred.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     Invalid Identifier.

            \sstitem
             SDS\_\_TYPE      Object not of logical type.

            \sstitem
             SDS\_\_UNDEFINED Data undefined.
         }
      }
   }
}
\sstroutine{
   SDS\_GETR
}{
   Read real data from an object
}{
   \sstdescription{
      Read data from a primitive real object.
      Data is transferred starting at the position in the item specified by
      offset, until the buffer if filled, or the end of the data array is
      reached.

      An error will be returned if the item is not a primitive real
      object.

      If necessary (e.g. if the data originated on a machine with different
      architecture) the data for the object is converted (in place) from the
      format stored in the data item to that required for the local machine.
   }
   \sstinvocation{
      CALL SDS\_GETR( ID, LENGTH, OFFSET, DATA, ACTLEN, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object
      }
      \sstsubsection{
         LENGTH = INTEGER (Given)
      }{
         Length of the buffer supplied to receive the data.
      }
      \sstsubsection{
         OFFSET = INTEGER (Given)
      }{
         Offset into the data at which to start
                    reading data.
                    The offset is zero to start at the beginning of the
                    array.
      }
      \sstsubsection{
         DATA (LENGTH) = REAL (Returned)
      }{
         Buffer to receive the data.
      }
      \sstsubsection{
         ACTLEN = INTEGER (Returned)
      }{
         Actual number of elements transferred.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     Invalid Identifier.

            \sstitem
             SDS\_\_TYPE      Object not of real type.

            \sstitem
             SDS\_\_UNDEFINED Data undefined.
         }
      }
   }
}
\sstroutine{
   SDS\_GET\_EXTRA
}{
   Read from the extra information field of an object
}{
   \sstdescription{
      Read bytes from the extra information field of an object. Bytes are
      copied until the supplied buffer is filled up or until all bytes
      in the field are copied.
   }
   \sstinvocation{
      CALL SDS\_GET\_EXTRA( ID, LENGTH, EXTRA, ACTLEN, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object
      }
      \sstsubsection{
         LENGTH = INTEGER (Given)
      }{
         Length of the buffer supplied to receive the data.
      }
      \sstsubsection{
         EXTRA = CHAR (Returned)
      }{
         Buffer to receive the data.
      }
      \sstsubsection{
         ACTLEN = INTEGER (Returned)
      }{
         Actual number of bytes transferred.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     Invalid Identifier.
         }
      }
   }
}
\sstroutine{
   SDS\_IMPORT
}{
   Import an object from an external buffer
}{
   \sstdescription{
      Import an object from an external buffer and return an identifier
      to the internal copy created. The object must have
      been previously exported using SDS\_EXPORT.

      The original external version of the
      structure continues to exist, in addition to the internal copy.

      A fully dynamic internal structure is created in which all SDS
      operations are valid. However, to merely access the data in an object
      SDS\_ACCESS can be used in place of SDS\_IMPORT.
   }
   \sstinvocation{
      CALL SDS\_IMPORT( DATA, ID, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         DATA( $*$ ) = BYTE (Given)
      }{
         The buffer from which the object will be imported
      }
      \sstsubsection{
         ID = INTEGER (Returned)
      }{
         The identifier of the new internal structure.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_NOTSDS    Not a valid SDS object.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory.
         }
      }
   }
}
\sstroutine{
   SDS\_INDEX
}{
   Find a structure component by position
}{
   \sstdescription{
      Given the name of a component in a structure, return an identifier
      to the component.
   }
   \sstinvocation{
      CALL SDS\_INDEX( PARENT\_ID, INDEX, ID, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         PARENT\_ID = INTEGER (Given)
      }{
         Identifier of the structure
      }
      \sstsubsection{
         NAME = CHAR (Given)
      }{
         Name of the component to be found
      }
      \sstsubsection{
         ID = INTEGER (Returned)
      }{
         Identifier to the component
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_NOMEM     Insufficient memory.

            \sstitem
             SDS\_\_NOTSTRUCT PARENT\_ID not a structure.

            \sstitem
             SDS\_\_NOITEM    No item with that name.
         }
      }
   }
}
\sstroutine{
   SDS\_INFO
}{
   Return information about an object
}{
   \sstdescription{
      Given the identifier to an object, return the name, type code and
      dimensions of the object.
   }
   \sstinvocation{
      CALL SDS\_INFO( ID, NAME, CODE, NDIMS, DIMS, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object
      }
      \sstsubsection{
         NAME = CHAR (Returned)
      }{
         The name of the data object.
      }
      \sstsubsection{
         CODE = INTEGER (Returned)
      }{
         The type code for the object.
      }
      \sstsubsection{
         NDIMS = INTEGER (Returned)
      }{
         The number of dimensions (if the object is a primitive
         or structure array)
      }
      \sstsubsection{
         DIMS (7) = INTEGER (Returned)
      }{
         The dimensions of the data. An array of size at least 7
         should be provided to receive this.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     The identifier is invalid.
         }
      }
   }
}
\sstroutine{
   SDS\_INSERT
}{
   Insert an existing object into a structure
}{
   \sstdescription{
      An existing top level object is inserted into a structure.
   }
   \sstinvocation{
      CALL SDS\_INSERT( PARENT\_ID, ID, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         PARENT\_ID = INTEGER (Given)
      }{
         Identifier of the structure
      }
      \sstsubsection{
         ID = INTEGER (Returned)
      }{
         Identifier to the component
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     Invalid identifier.

            \sstitem
             SDS\_\_NOTSTRUCT PARENT\_ID not a structure.

            \sstitem
             SDS\_\_NOTTOP    Not a top level object.

            \sstitem
             SDS\_\_NOMEM     Insufficent memory.

            \sstitem
             SDS\_\_EXTERN    Object is external.
         }
      }
   }
}
\sstroutine{
   SDS\_NEW
}{
   Create a new component in a structure
}{
   \sstdescription{
      Creates a new component in an existing internal structure. The new
      component can be a structure, a structure array, or a primitive.
      A structure array is specified by means of a type code of SDS\_STRUCT and
      a non-zero number for NDIMS. If the type code is SDS\_STRUCT and NDIMS is
      zero an ordinary structure is created, A primitive type is specified
      by the appropriate type code.
   }
   \sstinvocation{
      CALL SDS\_NEW( PARENT\_ID, NAME, NEXTRA, EXTRA, CODE, NDIMS, DIMS,
                ID, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         PARENT\_ID = INTEGER (Given)
      }{
         The identifier of the structure to which the component is to be added.
      }
      \sstsubsection{
         NAME = CHAR (Given)
      }{
         The name of the structure to create. The name should be
         of maximum length 16 characters including the terminating null.
      }
      \sstsubsection{
         NEXTRA = INTEGER (Given)
      }{
         The number of bytes of extra information to be included
         (maximum 128).
      }
      \sstsubsection{
         EXTRA = CHAR (Given)
      }{
         The extra information to be included with the item. NEXTRA
         characters from here are copied into the structure
      }
      \sstsubsection{
         CODE = INTEGER (Given)
      }{
         The type code for the item to be created. If CODE = SDS\_STRUCT
         a structured item will be created. Other codes result in primitive
         items.
      }
      \sstsubsection{
         NDIMS = INTEGER (Given)
      }{
         Number of dimensions for the item. Zero to create a scalar item.
      }
      \sstsubsection{
         DIMS (NDIMS) = INTEGER (Given)
      }{
         Array of dimensions for the item. Should be of size at least NDIMS.
      }
      \sstsubsection{
         ID = INTEGER (Returned)
      }{
         Identifier of the object to be created.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     Invalid Identifier.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory.

            \sstitem
             SDS\_\_LONGNAME  Name it too long.

            \sstitem
             SDS\_\_EXTRA     Too much extra data.

            \sstitem
             SDS\_\_INVCODE   Invalid type code.

            \sstitem
             SDS\_\_INVDIMS   Invalid dimensions.

            \sstitem
             SDS\_\_NOTSTRUCT Parent is not a structure.

            \sstitem
             SDS\_\_EXTERN    Parent is external.
         }
      }
   }
}
\sstroutine{
   SDS\_POINTER
}{
   Get a pointer to the data of a primitive item
}{
   \sstdescription{
      Return a pointer to the data of a primitive item. Also return the length
      of the item. If the data item is undefined and the object is internal
      storage for the data will be created.

      If necessary (e.g. if the data originated on a machine with different
      architecture) the data for the object is converted (in place) from the
      format stored in the data item to that required for the local machine
   }
   \sstinvocation{
      CALL SDS\_POINTER( ID, PNTR, LENGTH, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object
      }
      \sstsubsection{
         PNTR = INTEGER (Returned)
      }{
         Pointer to the data.
      }
      \sstsubsection{
         LENGTH = INTEGER (Returned)
      }{
         Actual number of bytes transferred.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     Invalid Identifier.

            \sstitem
             SDS\_\_NOTPRIM   Not a primitive item.

            \sstitem
             SDS\_\_UNDEFINED Data undefined.
         }
      }
   }
}
\sstroutine{
   SDS\_PUT
}{
   Write data to an object
}{
   \sstdescription{
      Write data into an object. The object may be a primitive item or a
      structure or structure array.

      If the object is a structure or structure array, the data from the
      the buffer is copied into its primitive components in order of their
      position in the structure. Alignment adjustments are made as necessary
      to match the alignment of a C struct equivalent to the SDS structure.
      In the structure or structure array case the offset parameter is
      ignored.

      If the object is primitive data is transferred starting
      at the position in the item specified by offset.

      If the data was previously undefined memory for the data is allocated at
      this time.
   }
   \sstinvocation{
      CALL SDS\_PUT( ID, LENGTH, OFFSET, DATA, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object
      }
      \sstsubsection{
         LENGTH = INTEGER (Given)
      }{
         Length in bytes of the buffer containing the data.
      }
      \sstsubsection{
         OFFSET = INTEGER (Given)
      }{
         Offset into the data object at which to start writing data.
         The offset is measured in units of the size of each indivdual
         item in the array - e.g. 4 bytes for an INT or 8 bytes for a
         DOUBLE. The offset is zero to start at the beginning of the array.
      }
      \sstsubsection{
         DATA ($*$) = BYTE (Given)
      }{
         Buffer containing the data
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     Invalid Identifier.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory for creation

            \sstitem
             SDS\_\_NOTPRIM   Not a primitive item.

            \sstitem
             SDS\_\_UNDEFINED Data undefined.
         }
      }
   }
}
\sstroutine{
   SDS\_PUTC
}{
   Write data to a character object
}{
   \sstdescription{
      Write data into a character object. The object must be a primitive
      character item.

      Data is transferred starting
      at the position in the item specified by offset.

      If the data was previously undefined memory for the data is allocated at
      this time.
   }
   \sstinvocation{
      CALL SDS\_PUTC( ID, LENGTH, OFFSET, DATA, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object
      }
      \sstsubsection{
         LENGTH = INTEGER (Given)
      }{
         Length of the buffer containing the data.
      }
      \sstsubsection{
         OFFSET = INTEGER (Given)
      }{
         Offset into the data object at which to start writing data.
         The offset is zero to start at the beginning of the array.
      }
      \sstsubsection{
         DATA ($*$) = CHARACTER (Given)
      }{
         Buffer containing the data
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     Invalid Identifier.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory for creation

            \sstitem
             SDS\_\_NOTPRIM   Not a primitive item.

            \sstitem
             SDS\_\_UNDEFINED Data undefined.

            \sstitem
             SDS\_\_TYPE      Object has incorrect type.
         }
      }
   }
}
\sstroutine{
   SDS\_PUTD
}{
   Write data to a double precision object
}{
   \sstdescription{
      Write data into a double precision object. The object must be a
      primitive double precision item.

      Data is transferred starting
      at the position in the item specified by offset.

      If the data was previously undefined memory for the data is allocated at
      this time.
   }
   \sstinvocation{
      CALL SDS\_PUTD( ID, LENGTH, OFFSET, DATA, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object
      }
      \sstsubsection{
         LENGTH = INTEGER (Given)
      }{
         Length of the buffer containing the data.
      }
      \sstsubsection{
         OFFSET = INTEGER (Given)
      }{
         Offset into the data object at which to start writing data.
         The offset is zero to start at the beginning of the array.
      }
      \sstsubsection{
         DATA ($*$) = DOUBLE (Given)
      }{
         Buffer containing the data
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     Invalid Identifier.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory for creation

            \sstitem
             SDS\_\_NOTPRIM   Not a primitive item.

            \sstitem
             SDS\_\_UNDEFINED Data undefined.

            \sstitem
             SDS\_\_TYPE      Object has incorrect type.
         }
      }
   }
}
\sstroutine{
   SDS\_PUTI
}{
   Write data to an integer object
}{
   \sstdescription{
      Write data into an integer object. The object must be a primitive
      integer item.

      Data is transferred starting
      at the position in the item specified by offset.

      If the data was previously undefined memory for the data is allocated at
      this time.
   }
   \sstinvocation{
      CALL SDS\_PUTI( ID, LENGTH, OFFSET, DATA, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object
      }
      \sstsubsection{
         LENGTH = INTEGER (Given)
      }{
         Length of the buffer containing the data.
      }
      \sstsubsection{
         OFFSET = INTEGER (Given)
      }{
         Offset into the data object at which to start writing data.
         The offset is zero to start at the beginning of the array.
      }
      \sstsubsection{
         DATA ($*$) = INTEGER (Given)
      }{
         Buffer containing the data
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     Invalid Identifier.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory for creation

            \sstitem
             SDS\_\_NOTPRIM   Not a primitive item.

            \sstitem
             SDS\_\_UNDEFINED Data undefined.

            \sstitem
             SDS\_\_TYPE      Object has incorrect type.
         }
      }
   }
}
\sstroutine{
   SDS\_PUTL
}{
   Write data to a logical object
}{
   \sstdescription{
      Write data into a logical object. The object must be a primitive
      integer item (The SDS kernel does not have a logical type so uses
      integer items to represent logical values).

      Data is transferred starting
      at the position in the item specified by offset.

      If the data was previously undefined memory for the data is allocated at
      this time.
   }
   \sstinvocation{
      CALL SDS\_PUTL( ID, LENGTH, OFFSET, DATA, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object
      }
      \sstsubsection{
         LENGTH = INTEGER (Given)
      }{
         Length of the buffer containing the data.
      }
      \sstsubsection{
         OFFSET = INTEGER (Given)
      }{
         Offset into the data object at which to start writing data.
         The offset is zero to start at the beginning of the array.
      }
      \sstsubsection{
         DATA ($*$) = LOGICAL (Given)
      }{
         Buffer containing the data
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     Invalid Identifier.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory for creation

            \sstitem
             SDS\_\_NOTPRIM   Not a primitive item.

            \sstitem
             SDS\_\_UNDEFINED Data undefined.

            \sstitem
             SDS\_\_TYPE      Object has incorrect type.
         }
      }
   }
}
\sstroutine{
   SDS\_PUTR
}{
   Write data to a real object
}{
   \sstdescription{
      Write data into a real object. The object must be a primitive
      real item.

      Data is transferred starting
      at the position in the item specified by offset.

      If the data was previously undefined memory for the data is allocated at
      this time.
   }
   \sstinvocation{
      CALL SDS\_PUTR( ID, LENGTH, OFFSET, DATA, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object
      }
      \sstsubsection{
         LENGTH = INTEGER (Given)
      }{
         Length of the buffer containing the data.
      }
      \sstsubsection{
         OFFSET = INTEGER (Given)
      }{
         Offset into the data object at which to start writing data.
         The offset is zero to start at the beginning of the array.
      }
      \sstsubsection{
         DATA ($*$) = REAL (Given)
      }{
         Buffer containing the data
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     Invalid Identifier.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory for creation

            \sstitem
             SDS\_\_NOTPRIM   Not a primitive item.

            \sstitem
             SDS\_\_UNDEFINED Data undefined.

            \sstitem
             SDS\_\_TYPE      Object has incorrect type.
         }
      }
   }
}
\sstroutine{
   SDS\_PUT\_EXTRA
}{
   Write to the extra information field of an object
}{
   \sstdescription{
      Write a specified number of bytes to the extra information field
      of an object. A maximum of 128 bytes may be written to an internal
      object. It is permissible to write to the extra information field
      of an external object, but the number of bytes written must not
      exceed the number originally in the object.
   }
   \sstinvocation{
      CALL SDS\_GET\_EXTRA( ID, NEXTRA, EXTRA, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object
      }
      \sstsubsection{
         NEXTRA = INTEGER (Given)
      }{
         Number of bytes of extra information.
      }
      \sstsubsection{
         EXTRA = CHAR (Returned)
      }{
         Buffer to receive the data.
      }
      \sstsubsection{
         ACTLEN = INTEGER (Returned)
      }{
         Actual number of bytes transferred.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     Invalid Identifier.

            \sstitem
             SDS\_\_EXTRA     Too much extra data.
         }
      }
   }
}
\sstroutine{
   SDS\_RENAME
}{
   Change the name of an object
}{
   \sstdescription{
      Specify a new name for an object.
   }
   \sstinvocation{
      CALL SDS\_RENAME( ID, NAME, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object
      }
      \sstsubsection{
         NAME = CHAR (Given)
      }{
         New name for the object. This should have a maximum length
         of 15 characters.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     Invalid Identifier.

            \sstitem
             SDS\_\_LONGNAME  The name is too long.
         }
      }
   }
}
\sstroutine{
   SDS\_RESIZE
}{
   Change the dimensions of an array
}{
   \sstdescription{
      Change the number and/or size of the dimensions of an array. This
      operation can be performed on primitive arrays or structure arrays.
      Note that SDS\_RESIZE does not move the data elements in the storage
      representing the array, so there is no guarantee that after resizing
      the array the same data will be found at the same array index
      positions as before resizing, though this will be the case for
      simple changes such as a change in the last dimension only.
   }
   \sstinvocation{
      CALL SDS\_RESIZE( ID, NDIMS, DIMS, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object.
      }
      \sstsubsection{
         NDIMS = INTEGER (Given)
      }{
         New number of dimensions.
      }
      \sstsubsection{
         DIMS (NDIMS) = INTEGER (Given)
      }{
         Array of dimensions.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     Invalid Identifier.

            \sstitem
             SDS\_\_NOMEM     Insuficient memory.

            \sstitem
             SDS\_\_EXTERN    Object is external.

            \sstitem
             SDS\_\_NOTARR    Object is not an array.

            \sstitem
             SDS\_\_INVDIMS   Dimensions invalid.
         }
      }
   }
}
\sstroutine{
   SDS\_SIZE
}{
   Find the buffer size needed to export an object
}{
   \sstdescription{
      Return the size which will be needed for a buffer into which the
      object can be exported using the SDS\_EXPORT routine.
   }
   \sstinvocation{
      CALL SDS\_SIZE( ID, BYTES, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object.
      }
      \sstsubsection{
         BYTES = INTEGER (Returned)
      }{
         Size in bytes of required buffer.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     Invalid Identifier.

            \sstitem
             SDS\_\_EXTERN    Object is external.
         }
      }
   }
}
\sstroutine{
   SDS\_LIST
}{
   List contents of an SDS object
}{
   \sstdescription{
      A listing of the contents of an SDS object is generated on
      standard output. The listing consists of the name type, dimensions
      and value of each object in the structure. The hierarchical structure
      is indicated by indenting the listing for components at each level.

      For array objects only the values of the first few components are
      listed so that the listing for each item fits on a single line.
   }
   \sstinvocation{
      CALL SDS\_LIST( ID, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object to be listed.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. SDS\_LIST calls a large number of SDS routines
         so will return error status values if an error occurs in any
         of these routines.
      }
   }
}
\sstroutine{
   SDS\_READ
}{
   Read an SDS object from a file
}{
   \sstdescription{
      Read an SDS object from a file previously written by SdsWrite.
      An identifier to an external object is returned. If an internal
      version of the object is required it can be created using SdsCopy.

      SDS\_READ must allocate a buffer to read the object into.  This
      should be freeed when you are finished using the object by calling
      SDS\_READ\_FREE.
   }
   \sstinvocation{
      CALL SDS\_READ( FILENAME, ID, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         FILENAME = CHAR (Given)
      }{
         The name of the file from which the object will be read.
      }
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the external object.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status.

         \sstitemlist{

            \sstitem
              SDS\_\_NOTSDS    Not a valid SDS object.

            \sstitem
              SDS\_\_NOMEM     Insufficient memory for output buffer.

            \sstitem
              SDS\_\_FOPEN     Error opening the file.

            \sstitem
              SDS\_\_FREAD     Error reading the file.
         }
      }
   }
}
\sstroutine{
   SDS\_READ\_FREE
}{
      Free a buffer allocated by SDS\_READ
}{
   \sstdescription{
      SDS\_READ allocates a block of memory to hold the external object read 
      in.  This memory can be released when the object is no longer required 
      by calling SDS\_READ\_FREE (note that it is not possible to SDS\_DELETE 
      an external object).

     If SDS\_READ\_FREE is given an idientifier which was not produced by a 
     call to SDS\_READ/SdsRead it will do nothing.

     Deleting the buffer does not free the memory associated with the
     identifier referencing it. This memory can be freed with the 
     SDS\_FREE\_ID function.
   }
   \sstinvocation{
      CALL SDS\_READ\_FREE( ID, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier to the external object.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     The identifier is invalid.

         }
      }
   }
}



\sstroutine{
   SDS\_WRITE
}{
   Write an SDS object to a file
}{
   \sstdescription{
      Given an identifier to an internal SDS object, write it to
      a file. The file can be read back using SDS\_READ.
   }
   \sstinvocation{
      CALL SDS\_WRITE( ID, FILENAME, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the object.
      }
      \sstsubsection{
         FILENAME = CHAR (Given)
      }{
         The name of the file into which the object will be written.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status.

         \sstitemlist{

            \sstitem
              SDS\_\_BADID     The identifier is invalid

            \sstitem
              SDS\_\_EXTERN    The object is external

            \sstitem
              SDS\_\_NOMEM     Insufficient memory for output buffer

            \sstitem
              SDS\_\_FOPEN     Error opening the file

            \sstitem
              SDS\_\_FWRITE    Error writing the file
         }
      }
   }
}


\subsection{ARG subroutines}

\sstroutine{
   ARG\_NEW
}{
   Create a new argument structure
}{
   \sstdescription{
      Creates a new structure to hold arguments and return an
      identifier to it
   }
   \sstinvocation{
      CALL ARG\_NEW( ID, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Returned)
      }{
         The identifier to the created structure
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_NOMEM  -   Insufficient memory.
         }
      }
   }
}
\sstroutine{
   ARG\_PUT0C
}{
   Put a character string item into an argument structure
}{
   \sstdescription{
      A character string item is written into a named component within the
      specified argument structure. The component is created if it
      does not currently exist.
   }
   \sstinvocation{
      CALL ARG\_PUT0C( ID, NAME, VALUE, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the argument structure.
      }
      \sstsubsection{
         NAME = CHARACTER (Given)
      }{
         The name of the component to be written into.
      }
      \sstsubsection{
         VALUE = CHARACTER (Given)
      }{
         The string to be written.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
            SDS\_\_BADID     The identifier is invalid.

            \sstitem
            SDS\_\_NOMEM     Insufficient memory.

            \sstitem
            ARG\_\_NOTSTRING Item is not a string.
         }
      }
   }
}
\sstroutine{
   ARG\_PUT0D
}{
   Put a double precision item into an argument structure
}{
   \sstdescription{
      A double precision item is written into a named component within the
      specified argument structure. The component is created if it
      does not currently exist.
   }
   \sstinvocation{
      CALL ARG\_PUT0D( ID, NAME, VALUE, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the argument structure.
      }
      \sstsubsection{
         NAME = CHARACTER (Given)
      }{
         The name of the component to be written into.
      }
      \sstsubsection{
         VALUE = DOUBLE (Given)
      }{
         The number to be written.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
            SDS\_\_BADID     The identifier is invalid.

            \sstitem
            SDS\_\_NOMEM     Insufficient memory.

            \sstitem
            ARG\_\_NOTSCALAR Item is not a scalar.

            \sstitem
            ARG\_\_CNVERR    Type conversion error.
         }
      }
   }
}
\sstroutine{
   ARG\_PUT0I
}{
   Put an integer item into an argument structure
}{
   \sstdescription{
      An integer item is written into a named component within the
      specified argument structure. The component is created if it
      does not currently exist.
   }
   \sstinvocation{
      CALL ARG\_PUT0I( ID, NAME, VALUE, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the argument structure.
      }
      \sstsubsection{
         NAME = CHARACTER (Given)
      }{
         The name of the component to be written into.
      }
      \sstsubsection{
         VALUE = INTEGER (Given)
      }{
         The number to be written.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     The identifier is invalid.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory.

            \sstitem
             ARG\_\_NOTSCALAR Item is not a scalar.

            \sstitem
             ARG\_\_CNVERR    Type conversion error.
         }
      }
   }
}
\sstroutine{
   ARG\_PUT0L
}{
   Put a logical item into an argument structure
}{
   \sstdescription{
      A logical item is written into a named component within the
      specified argument structure. The component is created if it
      does not currently exist.
   }
   \sstinvocation{
      CALL ARG\_PUT0L( ID, NAME, VALUE, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the argument structure.
      }
      \sstsubsection{
         NAME = CHARACTER (Given)
      }{
         The name of the component to be written into.
      }
      \sstsubsection{
         VALUE = LOGICAL (Given)
      }{
         The number to be written.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     The identifier is invalid.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory.

            \sstitem
             ARG\_\_NOTSCALAR Item is not a scalar.

            \sstitem
             ARG\_\_CNVERR    Type conversion error.
         }
      }
   }
}
\sstroutine{
   ARG\_PUT0R
}{
   Put a real item into an argument structure
}{
   \sstdescription{
      A real item is written into a named component within the
      specified argument structure. The component is created if it
      does not currently exist.
   }
   \sstinvocation{
      CALL ARG\_PUT0R( ID, NAME, VALUE, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the argument structure.
      }
      \sstsubsection{
         NAME = CHARACTER (Given)
      }{
         The name of the component to be written into.
      }
      \sstsubsection{
         VALUE = REAL (Given)
      }{
         The number to be written.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     The identifier is invalid.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory.

            \sstitem
             ARG\_\_NOTSCALAR Item is not a scalar.

            \sstitem
             ARG\_\_CNVERR    Type conversion error.
         }
      }
   }
}
\sstroutine{
   ARG\_GET0C
}{
   Get a character item from an argument structure
}{
   \sstdescription{
      A character string item is read from a named component within the
      specified argument structure.
   }
   \sstinvocation{
      CALL ARG\_GET0C( ID, NAME, VALUE, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the argument structure.
      }
      \sstsubsection{
         NAME = CHARACTER (Given)
      }{
         The name of the component to be read.
      }
      \sstsubsection{
         VALUE = CHARACTER (Returned)
      }{
         Character string value.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     The identifier is invalid.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory.

            \sstitem
             ARG\_\_NOTSTRING Item is not a string.
         }
      }
   }
}
\sstroutine{
   ARG\_GET0D
}{
   Get a double precision item from an argument structure
}{
   \sstdescription{
      A double floating point item is read from a named component within the
      specified argument structure. The item is converted to double
      type if necessary.
   }
   \sstinvocation{
      CALL ARG\_GET0D( ID, NAME, VALUE, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the argument structure.
      }
      \sstsubsection{
         NAME = CHARACTER (Given)
      }{
         The name of the component to be read.
      }
      \sstsubsection{
         VALUE = DOUBLE (Returned)
      }{
         Double precision value.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     The identifier is invalid.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory.

            \sstitem
             ARG\_\_NOTSCALAR Item is not a scalar.

            \sstitem
             ARG\_\_CNVERR    Type conversion error.
         }
      }
   }
}
\sstroutine{
   ARG\_GET0I
}{
   Get an integer item from an argument structure
}{
   \sstdescription{
      An integer item is read from a named component within the
      specified argument structure. The item is converted to integer
      type if necessary.
   }
   \sstinvocation{
      CALL ARG\_GET0I( ID, NAME, VALUE, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the argument structure.
      }
      \sstsubsection{
         NAME = CHARACTER (Given)
      }{
         The name of the component to be read.
      }
      \sstsubsection{
         VALUE = INTEGER (Returned)
      }{
         Integer value.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     The identifier is invalid.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory.

            \sstitem
             ARG\_\_NOTSCALAR Item is not a scalar.

            \sstitem
             ARG\_\_CNVERR    Type conversion error.
         }
      }
   }
}
\sstroutine{
   ARG\_GET0L
}{
   Get a logical item from an argument structure
}{
   \sstdescription{
      A logical item is read from a named component within the
      specified argument structure. The item is converted to logical
      type if necessary.
   }
   \sstinvocation{
      CALL ARG\_GET0L( ID, NAME, VALUE, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the argument structure.
      }
      \sstsubsection{
         NAME = CHARACTER (Given)
      }{
         The name of the component to be read.
      }
      \sstsubsection{
         VALUE = LOGICAL (Returned)
      }{
         Logical value.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     The identifier is invalid.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory.

            \sstitem
             ARG\_\_NOTSCALAR Item is not a scalar.

            \sstitem
             ARG\_\_CNVERR    Type conversion error.
         }
      }
   }
}
\sstroutine{
   ARG\_GET0R
}{
   Get a real item from an argument structure
}{
   \sstdescription{
      A real item is read from a named component within the
      specified argument structure. The item is converted to real
      type if necessary.
   }
   \sstinvocation{
      CALL ARG\_GET0R( ID, NAME, VALUE, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the argument structure.
      }
      \sstsubsection{
         NAME = CHARACTER (Given)
      }{
         The name of the component to be read.
      }
      \sstsubsection{
         VALUE = REAL (Returned)
      }{
         Real value.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     The identifier is invalid.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory.

            \sstitem
             ARG\_\_NOTSCALAR Item is not a scalar.

            \sstitem
             ARG\_\_CNVERR    Type conversion error.
         }
      }
   }
}
\sstroutine{
   ARG\_GETDC
}{
   Get a character item with defaulting
}{
   \sstdescription{
      A character string item is read from a named component within the
      specified argument structure. If the item is not present in the
      structure the default value is returned.
   }
   \sstinvocation{
      CALL ARG\_GETDC( ID, NAME, DEF, VALUE, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the argument structure.
      }
      \sstsubsection{
         NAME = CHARACTER (Given)
      }{
         The name of the component to be read.
      }
      \sstsubsection{
         DEF = CHARACTER (Given)
      }{
         Default value for argument.
      }
      \sstsubsection{
         VALUE = CHARACTER (Returned)
      }{
         Character string value.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     The identifier is invalid.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory.

            \sstitem
             ARG\_\_NOTSTRING Item is not a string.
         }
      }
   }
}
\sstroutine{
   ARG\_GETDD
}{
   Get a double precision item with defaulting
}{
   \sstdescription{
      A double floating point item is read from a named component within the
      specified argument structure. The item is converted to double
      type if necessary. If the item is not present in the structure the
      default value is returned.
   }
   \sstinvocation{
      CALL ARG\_GETDD( ID, NAME, DEF, VALUE, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the argument structure.
      }
      \sstsubsection{
         NAME = CHARACTER (Given)
      }{
         The name of the component to be read.
      }
      \sstsubsection{
         DEF = DOUBLE (Given)
      }{
         The default value.
      }
      \sstsubsection{
         VALUE = DOUBLE (Returned)
      }{
         Double precision value.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     The identifier is invalid.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory.

            \sstitem
             ARG\_\_NOTSCALAR Item is not a scalar.

            \sstitem
             ARG\_\_CNVERR    Type conversion error.
         }
      }
   }
}
\sstroutine{
   ARG\_GETDI
}{
   Get an integer item with defaulting
}{
   \sstdescription{
      An integer item is read from a named component within the
      specified argument structure. The item is converted to integer
      type if necessary. If the item is not present in the structure
      the default value is returned.
   }
   \sstinvocation{
      CALL ARG\_GETDI( ID, NAME, DEF, VALUE, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the argument structure.
      }
      \sstsubsection{
         NAME = CHARACTER (Given)
      }{
         The name of the component to be read.
      }
      \sstsubsection{
         DEF = INTEGER (Given)
      }{
         The default value.
      }
      \sstsubsection{
         VALUE = INTEGER (Returned)
      }{
         Integer value.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     The identifier is invalid.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory.

            \sstitem
             ARG\_\_NOTSCALAR Item is not a scalar.

            \sstitem
             ARG\_\_CNVERR    Type conversion error.
         }
      }
   }
}
\sstroutine{
   ARG\_GETDL
}{
   Get a logical item with defaulting
}{
   \sstdescription{
      A logical item is read from a named component within the
      specified argument structure. The item is converted to logical
      type if necessary. If the item is not present in the structure the
      default value is returned.
   }
   \sstinvocation{
      CALL ARG\_GETDL( ID, NAME, DEF, VALUE, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the argument structure.
      }
      \sstsubsection{
         NAME = CHARACTER (Given)
      }{
         The name of the component to be read.
      }
      \sstsubsection{
         DEF = LOGICAL (Given)
      }{
         The default value.
      }
      \sstsubsection{
         VALUE = LOGICAL (Returned)
      }{
         Logical value.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     The identifier is invalid.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory.

            \sstitem
             ARG\_\_NOTSCALAR Item is not a scalar.

            \sstitem
             ARG\_\_CNVERR    Type conversion error.
         }
      }
   }
}
\sstroutine{
   ARG\_GETDR
}{
   Get a real item with defaulting
}{
   \sstdescription{
      A real item is read from a named component within the
      specified argument structure. The item is converted to real
      type if necessary. If the item is not present in the structure
      the default value is returned.
   }
   \sstinvocation{
      CALL ARG\_GETDR( ID, NAME, DEF, VALUE, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the argument structure.
      }
      \sstsubsection{
         NAME = CHARACTER (Given)
      }{
         The name of the component to be read.
      }
      \sstsubsection{
         DEF = REAL (Given)
      }{
         The default value.
      }
      \sstsubsection{
         VALUE = REAL (Returned)
      }{
         Real value.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     The identifier is invalid.

            \sstitem
             SDS\_\_NOMEM     Insufficient memory.

            \sstitem
             ARG\_\_NOTSCALAR Item is not a scalar.

            \sstitem
             ARG\_\_CNVERR    Type conversion error.
         }
      }
   }
}
\sstroutine{
   ARG\_DELET
}{
   Delete an argument structure
}{
   \sstdescription{
      Delete an argument structure and free its identifier.
   }
   \sstinvocation{
      CALL ARG\_DELET( ID, STATUS )
   }
   \sstarguments{
      \sstsubsection{
         ID = INTEGER (Given)
      }{
         Identifier of the argument structure.
      }
      \sstsubsection{
         STATUS = INTEGER (Given and Returned)
      }{
         Modified Status. Possible failure codes are:

         \sstitemlist{

            \sstitem
             SDS\_\_BADID     The identifier is invalid.
         }
      }
   }
}



\newpage

\section{sdsc Command description}

% This bit of tex is a fudge.  Part of it was generated using MAn and
% the rest put in by hand.  

\manroutine{sdsc}{Compiles C structure definitions into {\mantt{SDS}} Calls.}{%
sdsc}
\begin{manroutinedescription}
\manroutineitem{Function}{}
      Compiles C structure definitions into {\mantt{SDS}} Calls.

\manroutineitem{Synopsis}{}
\begin{verbatim}
    sdsc [ -nvlswT] [ -Dname ] [ -Dname=def ] [ -Uname ]
         \[ -ffunction ]  [ -ttype ] [ -Nname ]
         \[ -Idirectory ] [ -Pcpp ] [ input-file ] [ output-file]
\end{verbatim}
\manroutineitem{Description}{}
 	A C structure can be put and retrived from a similar {\mantt{SDS}}
	structure using SdsPut and SdsGet.  This makes it desirable to be
	able to automatically generate {\mantt{SDS}} calls to produce an {\mantt{SDS}}
	structure equivalent to the C structure.  sdsc does this job.

	The input to sdsc is frist run through a C preprocessor.  During
	this the macros '{\mantt{SDS}}' and '{\mantt{\_{}\_{}\_{}SDS\_{}\_{}\_{}}}' %
will be defined (in addition)
	to any macros defined by default).   The result should be a series
	of C definitions followed by one and only one structure declaration.

      sdsc optionally accepts two filenames as arguments.  input-file and
	output-file are, respectively, the input and output files.  They
	default to the standard input and standard output (except under {\mantt{VMS}},
	when you must specifiy the input file (due to problems with the C
	run time library under the current version of {\mantt{VMS}})).

\manroutineitem{Options}{}
\begin{mandescription}
\mandescriptionitem{-n}Do not run the input through the C preprocessor.
\mandescriptionitem{-v}Output the command used to run the  C preprocessor to %
stderr.
\mandescriptionitem{-l}Treat ambiguous int declarations as 32bit ints.
\mandescriptionitem{-s}Treat ambiguous int declarations as short ints.
\mandescriptionitem{-w}Instead of outputing declarations, use the SdsWrite
		utility function to write the Sds structure to a file .
		In this case, an output file must be supplied.
\mandescriptionitem{{\mantt{-W}}}Output warning messages as well as error %
messages.
\mandescriptionitem{{\mantt{-T}}}Output Tcl code instead of C code.  This %
requires the Sds
              commands in {\mantt{DRAMA}}'s Dtcl package ({\mantt{DRAMA}} {%
\mantt{V1}}.2 and later only)
\mandescriptionitem{-Dname}Define name as 1 (one).  This is the same as if a -%
Dname=1
		option appeared on the command line, or as if a
\begin{verbatim}
                #define name 1
\end{verbatim}		appeared in the source file.

\mandescriptionitem{-ffunction}Specify a function name.  When specified, %
instead of
             outputing just the body of the function, then entire
             function is output, this is the name for the function.
\mandescriptionitem{-ttype}Specify a type, a declaration of which is to be %
assumed
             at the end of reading the input file if the input fie
             does not declare a variable.  It should be a simple type
             or a typedef name.
\mandescriptionitem{-Nname}If -t is used, then this name is given to the %
variable
             created and hence to the top level structure.  If not supplied,
             then the variable type is used as the variable name.
\mandescriptionitem{-Dname=def}Define name as if by a {\mantt{\#{}}}define %
directive.
\mandescriptionitem{-Uname}Remove any initial definition of name where name is a
		symbol predefined by the C preprocessor.
\mandescriptionitem{-Idirectory}Insert directory into the search path for {%
\mantt{\#{}}}include files.
\mandescriptionitem{-Pcpp}Use cpp as the C preprocessor.  By default /usr/lib/%
cpp
		is used (utask\_{}Dir:gnu\_{}cpp on a vms machine)

\end{mandescription}
      Note that the {\mantt{-D}}, {\mantt{-U}} and {\mantt{-I}} options are %
passed directly to the C
	preprocessor.  If -n is set, none of the other options have any
	effect (and C preprocessor statements may call errors)	.


\manroutineitem{See Also}{}
	cpp(1), Sds manual.

\manroutineitem{Support}{Tony Farrell, {\mantt{AAO}}}
\end{manroutinedescription}




\newpage
\section{SDS Data Format}
\label{SDS-format}

\subsection{Overall Structure}

An SDS structure consists of an array of longwords (one longword = 4 bytes).
Each longword can be considered as having a longword address within the block,
with the first longword having address 0. The array is organized into three
sections as follows:

\begin{enumerate}

\item A header, occupying the first four longwords.

\item The definition part.

\item The data part.

\end{enumerate}

The definition part is always present. The data part can be absent if the
structure has no defined primitive data items.

\subsection{The Header}

The header consists of four longwords as follows:

\begin{enumerate}

\item The first longword has the value zero if integer items within the
header and definition have big endian byte order (i.e. the most significant
byte at the lowest address), and has the hex value FFFFFFFF if the integer
items have little endian byte order. Any other value is illegal.

Note that this flag applies to the integer items (pointers, item counts etc)
within the header and definition, not to the data in the structure. Each
primitive data item has its own format flag in the definition part of the
structure.

\item The second longword is the total length in bytes of the structure
(including header plus definition plus data).

\item The third longword contains the  current SDS version code. The current
value for this is the constant SDS\_\_VERSION in the sds.h include file.

\item The fourth longword is the length in bytes of the header plus definition
(but not including the data). It is thus the address of the start of the data
section. 

\end{enumerate}

\subsection{The Definition Part}

The definition part consists of a sequence of blocks, each corresponding to an
object in the data structure. The blocks are laid out according to the
following rules:

\begin{enumerate}

\item The block describing the top level object must be located immediately
following the definition, i.e. starting at longword address 4.

\item The blocks describing the components of a structure or structure array
must immediately follow the block describing the parent structure or structure
array. They should be in order of position in the structure.

\end{enumerate}

The following example illustrates the sequence of blocks:

\begin{verbatim}
     1 2A 3A 3B 2B 3C 3D 3E 2C
\end{verbatim}

In this case the top level object (1) is a structure with three components (2A,
2B, 2C). Component 2A is a structure with two components (3A, 3B) and 2B is a
structure with three components (3C, 3D, 3E). 2C is a primitive.

\subsubsection{Blocks}

The usage of the first five longwords is common to all three block types:

Longword zero is divided up as follows:

\begin{itemize}

\item Byte 0 contains the type code for the object with possible values as
follows:

\begin{tabular}{|l|l|}
\hline
Type & Value \\
\hline
STRUCT & 0 \\
CHAR & 1 \\
BYTE & 2 \\
UBYTE & 3 \\
SHORT & 4 \\
USHORT & 5 \\
INT & 6 \\
UINT & 7 \\
FLOAT & 8 \\
DOUBLE & 9 \\
SARRAY & 10 \\
INT64 & 11 \\
UINT64 & 12 \\
\hline
\end{tabular}

Where SARRAY is the code for a structure array.

\item Byte 1 contains the format code for the object.

Formats for integer items are as follows:

\begin{tabular}{|l|l|}
\hline
Format & Value \\
\hline
Big endian & 0 \\
Little endian & 1 \\
\hline
\end{tabular}

Formats for floating point items are as follows:

\begin{tabular}{|l|l|}
\hline
Format & Value \\
\hline
IEEE & 0 \\
VAX & 1 \\
IEEE reversed & 2 \\
VAXG & 3 \\
\hline
\end{tabular}

Where IEEE refers to IEEE-754 32 bit format for float and 64-bit format for
double type. VAX refers to VAX F-floating format for float, and VAX D-floating
format for doubles. VAXG is VAX G format for doubles. IEEE reversed is
the IEEE format as implemented on machines with little endian byte order.

\item Bytes 2 and 3 constitute a 16 bit integer which is the number of items
for a structure, or the number of dimensions for a primitive or structure
array.

\end{itemize}

Longwords 1 to 4 contain the name of the item as a null terminated C string.
Since the null must be included the maximimum length of the name is 15
characters.

\subsubsection{Structure Blocks}

Starting at longword 5 is an array of pointers (i.e. longword addresses
relative to the start of the structure) of the components of the structure.

Following this (i.e. starting at longword 5+n where n is the number of
components) is the extra information field. This consists of a 16 bit integer
specifying the number (nextra) of extra bytes, followed by nextra bytes of
information.

The total length (in bytes) of a structure block is:

\begin{displaymath}
      22 + 4*nitems + nextra  
\end{displaymath}

though it will always be padded to a whole number of longwords so that the next
block begins on a longword boundary.

\subsubsection{Primitive Blocks}

Longword 5 of a primitive block is the longword address of the data (i.e. a
pointer into the data part. If the data is undefined this longword will be
zero.

Starting at longword 6 is an array of longwords containing the dimensions
of the array.

Following this (i.e. starting at longword 6+n where n is the number of
dimensions) is the extra information field. This consists of a 16 bit integer
specifying the number (nextra) of extra bytes, followed by nextra bytes of
information.

The total length (in bytes) of a primitive block is:

\begin{displaymath}
      26 + 4*ndims + nextra
\end{displaymath}

though it will always be padded to a whole number of longwords so that the next
block begins on a longword boundary.

\subsubsection{Structure Array Blocks}

Starting at longword 5 is an array of longwords containing the dimensions
of the array.

Following this (i.e. starting at longword 5+ndims) is an array of pointers
(longword addresses) to the elements of the structure array, each of which has
its own structure block. These pointers are the longword addresses of the
start of the corresponding structure block.

Following this (i.e. starting at longword 5+ndims+n where n is the number of
elements) is the extra information field. This consists of a 16 bit integer
specifying the number (nextra) of extra bytes, followed by nextra bytes of
information.

The total length (in bytes) of a structure array block is:

\begin{displaymath}
      22 + 4*ndims + 4*nelements + nextra 
\end{displaymath}

though it will always be padded to a whole number of longwords so that the next
block begins on a longword boundary.

\subsection{The Data Part}

The Data Part contains the data for each primitive object in the same order in
which the definition blocks are stored. Each item starts on a longword boundary
and its size is the size of the primitive type multiplied by the number of
array elements. Note that undefined objects do not have any associated data.

Each object of type double has an additional longword allocated to it, which is
used as padding to ensure that the data for the object begins on an eight byte
boundary. This padding longword is positioned either before or after the data
for the object to give the correct alignment. Thus the size of a double item is
four bytes larger than actually required to store the data.

\end{document}

