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
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'.
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)
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.
For more information on error status codes, see Appendix C.
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 }.
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
#define FTNINC_LIST ibisfile,ibiserrsto 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.
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.