4.1 Preliminaries

Table of Contents

4.1 Preliminaries

Contents
      4.1 Preliminaries
            4.1.1 IBIS Routine Nomenclature
            4.1.2 IBIS Calling Conventions
            4.1.3 IBIS File Descriptors
            4.1.4 IBIS Error Status
            4.1.5 IBIS Keywords
            4.1.6 IBIS Include files
            4.1.7 IBIS Format Translation, and Data Alignment

4.1.1 IBIS Routine Nomenclature

For the VICAR runtime library a naming convention was adopted, whereby the FORTRAN routine xNNNN would have a C-language equivalent called zNNNN (e.g., xvopen/zvopen). For IBIS routines, a slightly different nomenclature will be adopted:

C-Language: All IBIS routines will start with "IBIS", and will be CapitalLetterDelimited.

FORTRAN: All routines will start with "IBIS", and will be underscore_delimited. It is assumed that FORTRAN routine-names are case-insensitive.

In the routines documented in this section, the C-language calling sequence is listed first, followed by the FORTRAN calling sequence. The routines are referenced by their C-language entry points, so that ibis_file_open will be found under the section titled IBISFileOpen.

All routine names referred to in the text will be in boldface, the parameters names will be underlined, and keywords will be in single 'quotes'.

4.1.2 IBIS Calling Conventions

With several exceptions, each C-routine is a function, returning a status value, while the FORTRAN bridge routine will have identical calling sequence, except that the status value will returned as an extra parameter at the end of the routine's argument list.

For example, the calling routine for IBISFileOpen is listed as:

status = IBISFileOpen( unit, ibis, mode, ncol, nrow, format, org);
call   ibis_file_open(unit, ibis, mode, ncol, nrow, format, org,status)

When in doubt, the calling sequence ending in a semi-colon is the C-language declaration. The only exceptions to the calling syntax above are several routines which search or retrieve values. In this case both the C and the FORTRAN routines are functions, which return either a count of the total number of values retrieved (which may be zero), or else a negative error status. If the arguments returned are arrays of strings, the C-interface includes a "length" argument which is absent from the FORTRAN (as the string length may be determined directly).

For example, the calling routine for IBISFileGet is listed as:

count = IBISFileGet( ibis, name, value, sval, maxvals, length );
count = ibis_file_get(  ibis, name, value, sval, maxvals)

4.1.3 IBIS File Descriptors

The parameter unit in the IBISSignalU, IBISFileOpen and the IBISFileUnit routines is the unit number obtained using the VICAR runtime library's xvunit/zvunit subroutine. The ibis parameters below are special file descriptors which are assumed to have been acquired through the IBISFileOpen or IBISFileUnit routines beforehand.

All other routines in the IBIS2 library access the file through the ibis file descriptor, or the "record" mechanism, described later. The IBIS routines do, however, use the VICAR runtime library to create and manipulate the files, and so if for some reason you need to directly access the VICAR label you may use the unit you passed into IBISFileOpen. Alternatively, the VICAR unit may be retrieved from the ibis file handle via the IBISFileGet routine.

4.1.4 IBIS Error Status

The status parameter returned below adopts the VICAR standard of identifying the value 1 with success; if the value is not 1 it is either an error returned from the VICAR runtime library or else an error generated by the IBIS library itself. In case the error is not found to be 1, the status should be passed to the IBISSignal routines documented below, which will determine what type of error it is, and what to do about it.

For more information on error status codes, see Appendix C.

4.1.5 IBIS Keywords

Whenever a string-valued parameter of a calling sequence documented in the next section is specified as a keyword, the range of valid values in each case is specified using the form:

keyname = {  validname1  |  validname2  .... | validnameN }, default=default_name.

The key is recognized by the IBIS library in a case-insensitive manner. However, the spelling must be exact -- there are no abbreviations permitted. In order to assist the C-programmer in insuring correct spelling of keywords, preprocessor macros may be used in place of literal strings.

In any of the IBISxxxGet routines below, if the attribute requested is a keyword (e.g. formats, organizations, versions, etc), they will be returned in ALL_UPPERCASE. This is merely to save having to check both upper and lower cases in the code.

All of the macros have the same naming system: they all begin with "I", followed by a suggestive tagname in caps, an under_score, and the string value. For example, the org keyword may take on the string values indicated by IORG_ROW and IORG_COLUMN.

If a keyword has a default value, it may be specified by passing a null pointer (in C) or a single quoted space (in FORTRAN).

For brevity, the list of default format types will be represented by the symbol FORMAT_LIST, defined as:

FORMAT_LIST = { BYTE | HALF | FULL | REAL | DOUB | COMP | A1 | ... | A256 }.

4.1.6 IBIS Include files

C Interface

The file "ibisfile.h" is a C-syle #include file which defines all of the preprocessor macros referred to in this document. It is not required for use of the subroutines, but is supplied as a useful set of alternatives to the string-literals required for some of the keywords.

In addition, the file defines the current value of IFMT_SIZE , which indicates the inner size of the format string array to be supplied to the IBISFileOpen and IBISFileUnit routines. This size, which happens to be 6 bytes in length, is not needed by the FORTRAN interface, as the conversion is done on the fly by the FORTRAN bridge routines.

The file "ibisfile.h" does not currently have any dependencies on other #include files, but for the sake of forward compatibility it is strongly suggested that the file be included after the file "vicmain_c" for programs, and "xvmaininc.h" for subroutines.

There is also an "ibiserrs.h" file which defines the symbolic names of the returned error status values from the IBIS subroutines.

In order to use these files from the portable P1SUB library, place them in quotes:

#include "ibisfile.h"
#include "ibiserrs.h"

If you are accessing the version of the IBIS-2 library that has been installed in the old unportable S2 sublib (and ONLY then), you must use the include module name only, i.e:

#include ibisfile
#include ibiserrs

FORTRAN Interface

There is now also an equivalent FORTRAN include file set, called "ibisfile.fin" and "ibiserrs.fin". To use them you must add the statement:

  #define FTNINC_LIST ibisfile,ibiserrs

to your imake file (assuming you wish to use both; typically only ibisfile.fin is required). The files may then invoked with the calling subroutine variable declaration as follows:

    subroutine my_sub
    integer whatever
    ! usual declarations...
    include 'ibisfile'
    include 'ibiserrs'
    
    
    ...

The symbols used are identical to the ones defined in the C interface, such as IMODE_READ, etc. Unlike the C interface, however, you must include the files in each subroutine that use the symbols, owing the the different symbol-definition mechanism used in FORTRAN.

The examples in the Appendix demonstrate the use of these definition files in FORTRAN.

4.1.7 IBIS Format Translation, and Data Alignment

The IBISColumnRead/Write and IBISRecordRead/Write routines automatically convert each column value into the equivalent native host format. Unless data conversion is disabled or changed (via the u_format='none' setting), the programmer needs to be very careful about the declared format of the data buffer passed into the File I/O routines.

For example, if a routine needs to do a "blind-copy" of several columns from one file to another, where the files may have different HOST's and the columns may have varying formats, the following code might be attempted:

char   buffer[1024];   /* <--- Dangerous !!! */
...
for (col=1; col<number_of_columns; col++)
{
	status = IBISColumnRead(ibis_in,buffer,col,1,num_rows);
	status = IBISColumnWrite( ibis_out, buffer,col,1,num_rows);
}

However -- This Is Not Portable!

The reason is that on some platforms the compiler will take advantage of the declaration "char buffer[1000]" (or its FORTRAN equivalent, BYTE BUFFER(1000) ) to assume that the memory allocated for the buffer does not have to be word-aligned. When the translation routines attempt to convert a column of floating point data into the buffer, the program may catastrophically fail with a segmentation error.

So, a safe version of the code segment above would be:

double aligned_buffer[1024];          /* aligned memory */
char *buffer=(char *)aligned_buffer;  /* generic buffer */
...

This is actually a general feature of any ported program performing host-independent data translations, and is not limited to IBIS subroutine calls.

There are two safe approaches to handling generic column buffers. One which works for "C" routines is to dynamically allocate the memory using malloc or calloc, both of which always return fully-aligned data buffers. The other, which works for both C and FORTRAN, is to declare the buffer to be the strictest data type that is expected to be translated by the subroutine call. In the most general case, that would be "double" (in C) or REAL*8 (in FORTRAN). Then to save memory (and ONLY to save memory), the use of a cast or EQUIVALENCE statement may be used to work with the translated values in the buffer.