Operation [ Micro Focus COBOL System Reference, Volume 1 ] MPE/iX 5.0 Documentation
Micro Focus COBOL System Reference, Volume 1
Operation
The COBOL syntaxdefining a file, consisting of a SELECT statement and an
FD statement, causes the Compiler to create a number of data areas to
define the file and to hold the file records. The principal item is the
File Control Description (FCD) which defines the essential properties of
the file. For indexed files, an additional area, the Key Definition
Block, is allocated to define the key structure. An area is allocated to
hold the file-name, and an area to hold the record being processed.
Under DOS, Windows and OS/2, each COBOL I/O statement is compiled into a
call to the run-time system; for indexed files, the run-time system then
simply calls the file handler. All other file organizations are handled
by routines in the run-time system. (DOS, Windows and OS/2)
COBOL I/O statementsfor files with the EXTERNAL attribute (FD name IS
EXTERNAL) are compiled into calls directly to the file handler for all
organizations.
Finally, if the CALLFH Compiler directive is used, all COBOL I/O
statements are compiled into calls to the file handler, or to a file
handler of your own, if specified.
Under UNIX, each COBOL I/O statement is compiled into a call to the file
hander.(UNIX)
To use the file handler directly, you can create your own data areas to
define the file, and write calls to the file handler instead of using
COBOL syntax. Alternatively, you can use COBOL syntax to define the file
and perform some of the I/O operations, and use the FCDREG Compiler
directive to gain access to the Compiler-generated file definitions,
allowing you to alter the file definition, or handle some of the I/O
operations by calls to the file handler.
CALLFH Directive (DOS, Windows and OS/2 only)
Programs compiled with the CALLFH directive on DOS, Windows and OS/2
systems use the file handler for all I/O operations on files of all
organizations.
Your Own File Handler
You can produce your own file handler using the call interface defined in
this chapter.
You can make programs use your file handler by using the CALLFH directive
when compiling your programs. For example, if you have a file handler
called USERFH, compile your programs with the directive: (DOS, Windows
and OS/2)
callfh"userfh"
This will cause all COBOL I/O operations to be compiled into calls to
USERFH using the call interface defined in the section Callable File
Handler Call Interface later in this chapter.
To link your own file handler(s) to the run-time system on UNIX systems,
you must include the -m option on the cob command line. See the chapter
COBOL System Interface (cob) later in this manual for further details of
this option.(UNIX)
Calling the File Handler from Other Languages
Extfh can be called from other languages to operate on COBOL-format
files. If you want to share COBOL-format files between languages, you
need to be aware that different languages use different data types. You
should, therefore, avoid using a data type when creating the file that
cannot be processed by teh reading language.
Opening a File more than Once
With the file handler you can assign several COBOL files to the same
physical file (by specifying it in the ASSIGN clauses of their SELECT
statements) and have them all open at the same time. The operating
system will count it as just one open file.
The physical file will not be closed until every COBOL file assigned to
it has been closed.
You can change this behavior in UNIX systems by setting the
same_proc_excl_detection run-time tunable to TRUE. See the chapter
Run-time Configuration later in this manual for details of this and other
run-time tunables.(UNIX)
Accessing the FCD from a Program
Each FCD created from the COBOL syntax can be accessed from within your
program. If you compile your program with the FCDREG directive, you can
access the FCD and key areas for each file. FCDs of files using the file
handler can be read or changed by the program, using the definitions
supplied in this chapter, or can be used in calls to the file handler.
To access the FCD, set up a definition of the FCD in the Linkage Section.
This definition (which takes up no physical memory) can then be mapped
onto the FCD you wish to read or alter using the following SET statement
in your program:
set address of fcd to address of fh--fcd of indexfile
where:
fcd is the Linkage Section definition of the FCD
fh--fcd of (note the double hyphen) is the pointer special register
indexfile allocated to the file with FD name indexfile.
Following this SET operation, the data items defined in the Linkage
Section group item fcd will be the fields of the FCD of the file
referenced in the SET statement.
An example FCD definition is supplied with this COBOL system in a file
called XFHFCD.CPY. This file is located in $COBDIR/source for DOS,
Windows and OS/2 systems and in $COBDIR/cpylib for UNIX systems.
Similarly, you can access the Key Definition Block by:
set address of kdb to address of fh--keydef of indexfile
where:
kdb is the Linkage Section definition of the Key Definition
Block
fh--keydef is the pointer special register allocated to the file with
of indexfile FD name indexfile to point to its Key Definition Block.
Example.
The following program turns on key compression in a file by setting bits
in the file's Key Definition Block.
$set fcdreg
select masterfile
assign to .....
organization is indexed
record key is rec-key
alternate key is m-alt-key-1 with duplicates
alternate key is m-alt-key-2
alternate key is m-alt-key-3 with duplicates.
select indexfile
assign to .....
organization is indexed
record key is rec-key
alternate key is t-alt-key-1 with duplicates. . . .
. . .
working-storage section.
. . .
linkage section.
01 key-def-block.
03 filler pic x(6).
03 key-count pic 9(4) comp-x.
03 filler pic x(6).
03 key-def occurs 1 to 4 times
depending on key-count.
05 filler pic x(5).
05 key-compression pic 9(2) comp-x.
05 filler pic x(10).
. . .
procedure division.
* set appropriate key compressions:
*
* +-- trailing space compression
* |+-- leading character compression
* ||+-- duplicate key compression
* |||
* 7 = 00000111 - all compressions
* 6 = 00000110 - leading character & trailing space
* 2 = 00000010 - leading character compression
* 1 = 00000001 - duplicate key compression
set address of key-def-block
to address of fh--keydef of masterfile
move 4 to key-count
move 6 to key-compression (1)
move 7 to key-compression (2)
move 6 to key-compression (3)
move 7 to key-compression (4)
open I/O masterfile
. . .
set address of key-def-block
to address of fh--keydef of indexfile
move 2 to key-count
move 4 to key-compression (1)
move 1 to key-compression (2)
open input indexfile
. . .
Sparse Keys
A Sparse keyis a key for which no index entry is stored for the given key
value. For example, if a key is defined as sparse when it contains all
spaces, index entries for the key will not be included when the key part
of the record contains only space characters.
Normally, when the file handler stores an indexed record, the key value
is stored in the index file for each key defined. If an alternate key is
defined as a sparse key and the key value is the specified sparse value,
the key value is not stored. However, enough information is stored for
the record to be read via the normal primary key path. Only alternate
keys that allow duplicates can be sparse.
Using this feature results in smaller index files. The larger your
key(s) and the more records you have for which the alternate key has the
given value, the larger your disk savings.
Sparse keys are defined using the SUPPRESS phrase in the WITH DUPLICATES
phrase of the ALTERNATE KEY clause in the SELECT statement (see your
Language Reference for the syntax).
On UNIX systems, sparse keys are not supported for the C-ISAM file
format.(UNIX)
Example.
input-output section.
file-control.
select out-file
assign to "outfile"
organization is indexed
access mode is dynamic
record key is out-key
alternate record key is alt-key
with duplicates
suppress when all "A"
*
* Hence, if we write a record whose alternate key has value all
* "A", the actual key value will not be stored in the index file
*
file status is file-status.
data division.
file section.
fd out-file.
01 out-rec.
03 out-key pic 9(10).
03 alt-key pic x(20).
working-storage section.
01 file-status pic xx.
procedure division.
open output out-file
if file-status not = "00"
* < code to abort >
end-if
perform varying out-key from 1 by 1 until out-key > 10
move all "A" to alt-key
write out-rec
invalid key
* < code to abort >
end-write
end-perform
close out-file
stop run.
If you examine the index file created, you will not see the alternate key
information because the file handler was instructed, by the SUPPRESS
clause, to suppress storage of those alternate keys containing all "A".
However, a COBOL program reading the file sequentially using the prime
key will read each record correctly.
Duplicate Keys
For a file with many duplicate keys you can specify a special file format
for faster processing.
You specify this format when you create the file. You either use the
IDXFORMAT"4" Compiler directive (see the appendix Directives for
Compiler) or set the file-format field of the FCD to 4. In this format,
the duplicate occurrences field in the Key-Value block is 4 instead of 2
bytes long; this removes the limit of 64K occurrences of the same
duplicate key. Also, each record in the data file is followed by a
system record holding the number of duplicate keys for that record. This
makes a REWRITE or DELETE operation on a record with many duplicates much
faster.
Creating a New Index
A set of operationsis provided that enable you to recreate an index file
using only the information in the data file.
To recreate an index file, your program must:
1. open the file using the open-new-index operation.
2. read records from the file using the get-next-rec operation.
3. create an index from each separate record, using the add-index
operation.
Example.
78 close-file value x"fa80".
78 open-new-index value x"0007".
78 get-next-rec value x"0008".
78 add-key-value value x"0009". . . .
. . .
move open-new-index to fh-opcode
perform extfh-op
move get-next-rec to fh-opcode
perform extfh-op
perform until fcd-status (1:1) not = "0"
perform varying fcd-key-id from 0 by 1
until fcd-key-id = key-count
or until fcd-status (1:1) not = "0"
move add-key-value to fh-opcode perform extfh-op
end-perform
move get-next-rec to fh-opcode
perform extfh-op
end-perform
move close-file to fh-opcode
perform extfh-op
. . .
. . .
extfh-op.
call "extfh" using fh-opcode, fcd
end-call
if fcd-status of fcd (1:1) "1"
move 1 to return-code
end-if.
File Status Conversion
On DOS, Windows and OS/2 systems, you can supply a COBOL routine that is
called automatically by the Callable File Handler to convert file status
codes before they are returned to your program. (DOS, Windows and OS/2)
On UNIX systems, you can convert all implementor defined file status
codes (that is, those commencing with a "9") in your program before they
are returned to your program.(UNIX)
Enabling File Status Conversion under DOS, Windows and OS/2.
You enable the conversion routine by setting the COBFSTATCONVenvironment
variable. Before setting COBFSTATCONV you must compile your program with
the CALLFH and COBFSTATCONV directives set.
The file handler will call the program specified by the COBFSTATCONV
environment variable before returning to the calling program on every
operation.
The programs RMSTAT and HOSTSTAT are supplied to provide RM/COBOL and IBM
mainframe status codes.
Example.
set cobfstatconv=rmstat
set cobfstatconv=usrstat
Form of the Conversion Routine.
The file status conversion routine must be a normal COBOL routine
expecting a single parameter, the FCD (the first two bytes of this are
the file status). The Callable File Handler passes the FCD the file
status in this parameter. Using COBOL syntax this is an ANSI'85 file
status, or whatever setting you have for bit 7 in the File Status type
field (offset 33) in the FCD. See the section File Control Description
for further information of this field. The routine should do whatever
conversion is wanted and then return the converted file status in the
same parameter.
Example Conversion Routine.
An example of a file status conversion routine is supplied. It is shown
below and can be used as the basis for your conversion.
*****************MODULE XFHCONV.CBL****************
* This module is used to convert file statuses to
* different values from those supplied by the
* Callable File Handler EXTFH. The code below can
* be used as a basis for customized conversion
* routines.
***************************************************
linkage section.
01 fcd-parameter.
copy XFHFCD.CPY.
procedure division using fcd-parameter.
* Example of status conversion; converting status
* 9/90 to 8/9.
evaluate fcd-status-key1
when 9
evaluate fcd-binary
when 90
move 8 to status-key-1
move 9 to status-key-2
end evaluate
end evaluate
exit program.
Enabling File Status Conversion under UNIX.
You can convert all file status "9" codes in your program before they are
returned to your program by setting the "Q" File Status Errorswitch.
By setting the file status error switch on, all status "9" file errors
reported in your code are mapped, by means of an internal run-time system
table, to a status which conforms to the statuses returned in the COBOL
dialect of your choice. You can configure the COBOL dialect you want to
use. See the appendix File Status for details of how to do this. Any
undefined or unrecognized status values are mapped onto status "30",
permanent I/O error. See the appendix File Status later in this manual
for full details of file status errors.
By default, this switch is set off as follows:
COBSW=-Q
export COBSW
You can set it on as follows:
COBSW=+Q
export COBSW
You can define your own status value by providing your own altstat[ ]
table in the filestat.c module provided in $COBDIR/src.
Data Compression
The chapter File Handling in your COBOL System Reference shows you how to
enable data compression in your program using a $SET statement. You can
also enable data compression using the Callable File Handler to call
compression routines from your program. The following sections describe
the data compression routines, how you make the routines available to
this COBOL system and the call you use to enable them.
The routine that the Callable File Handler uses to compress data is a
stand-alone module. This means that you can use it in your own
applications, or alternatively make the Callable File Handler use your
own data compression routine.
There can be up to 127 Micro Focus compression routines, and up to 127
user-supplied compression routines.
Micro Focus routines are stored in modules called CBLDCnnn, where nnn can
be 001 through 127. To use Micro Focus compression routines, you specify
the DATACOMPRESSCompiler directive with an integer value from 001 through
127, inclusive. This tells the Callable File Handler to look for a
module with the name CBLDCnnn. See the section Micro Focus Compression
Routine CBLDC001 for details of calling the 001 data compression routine.
On DOS, Windows and OS/2 systems, user supplied compression routines must
be stored in modules called CBLDCnnn, where nnn can be 128 through 255.
When you use the DATACOMPRESS Compiler directive DATACOMPRESS, you
specify the number 128 through 255 of the routine you want to use, and
the Compiler knows to look for a module of the name CBLDCnnn. (DOS,
Windows and OS/2)
On UNIX systems, user-supplied compression routines must be stored in
modules called USRDCnnn, where nnn can be 128 through 255. When you use
the DATACOMPRESS Compiler directive, you specify the number 128 through
255 of the routine you want to use, and the Compiler knows to look for a
module of the name USRDCnnn.(UNIX)
To make your compression routine available to this COBOL system, you must
dynamically call or link the relevant data compression routine with your
application. See the chapter Linking and Library Management in your
COBOL System Reference for details of how to do this under DOS, Windows
and OS/2.
Under UNIX, you dynamically call a data compression routine by compiling
the routine and then rebuilding your run-time system using the
command:(UNIX)
cob -xvo rts32 -e "" -d routine-name
where:
routine-name is the name of your compression routine.
Under UNIX, you link the relevant data compression routine by creating an
object module from the source of your compression routine and linking
this to the run-time system using the command:
cob -xvo rts32 -e "" routine-name.o
where:
routine-name.o is the name of the object module produced from the
source of your compression routine.
Notes for all operating systems
* Your compression routines must not make any calls to the Callable
File Handler, as this would result in a loop. If you need file
access, use byte-stream file I/O.
* Once you have enabled data compression for a file, you must always
subsequently specify the same type of compression for that file.
If you do not, you will receive a run-time status error at open
time.
* Data compression has no effect on files other than those in
indexed or record sequential format and is ignored at compile time
for files that do not support it.
* If you want to read a fixed length sequential file that has had
its data compressed, you must specify that the file is
compressed in your program. You can do this by specifying the
DATACOMPRESS"1" directive.
You can call any of the data compression routines from a program other
than the Callable File Handler.
Calling a Data Compression Routine.
The following sections show you how to call a Micro Focus compression
routine and a user-supplied compression routine.
Micro Focus Compression Routine.
To call a Micro Focus data compression routine use:
call "CBLDCnnn" using input-buffer, input-buffer-size, output-buffer,
output-buffer-size, compression-type
where:
nnn is a data compression routine in the range 001 to 127
input-buffer is a PIC X (size) data-item and is the input to the
routine; maximum size is 65535.
input-buffer-size is a PIC XX COMP-5 data-item and outputs the length
of data in the input-buffer.
output-buffer is a PIC X (size) data-item and is the buffer to
contain the resulting data.
output-buffer-size is a PIC XX COMP-5 data-item. On entry to the
routine this field must contain the size of the
output buffer available; on exit this field will
contain the length of the data in the buffer.
compression-type is a PIC X COMP-X data-item. This specifies if the
input data is to be compressed or decompressed.
0 - compress
1 - decompress
The RETURN-CODE special register indicates whether the operation
succeeded or not. Compression or decompression fails only if the output
buffer is too small to accept the results.
0 - success
1 - failure.
User-supplied Compression Routine.
To call a user-supplied routine, use the same statement as for calling a
Micro Focus routine, but use the file-name USRDCnnn instead of CBLDCnnn
where, for user-supplied routines, nnn must be a value in the range 128
through 255.
You can map calls to data compression routines in programs from previous
UNIX COBOL systems to the new calls using the cob option:(UNIX)
-m CBL_DATA_COMPRESS_nnn=CBLDCnnn
Micro Focus Compression Routine CBLDC001.
The compression routine used by this COBOL system CBLDC001 uses a form of
run length encoding. This is a method of compression that detects
strings (runs) of the same character and reduces them to an identifier, a
count and one occurrence of the character.
NOTE This routine is not suitable for use with files that contain
significant occurrences of Double Byte characters, including Double
Byte spaces, as these will be expanded.
CBLDC001 places special emphasis on runs of spaces, binary zeros and
character zeros (which can be reduced to a single character) and
printable characters (which are reduced to two characters consisting of a
count followed by the repeated character). Runs of other characters can
also be reduced.
In the compressed file, bytes have the following meaning:
* 20-7F (most printable characters) have their normal ASCII meaning.
* 80-9F indicate 1-32 spaces respectively.
* A0-BF indicate 1-32 binary zeros respectively.
* C0-DF indicate 1-32 character zeros respectively.
* E0-FF indicate 1-32 occurrences of the character following.
* 00-1F indicate 1-32 occurrences of the character following, and
that it should be interpreted literally, not as a compression
code. This is used when characters in the range 00-1F, 80-9F,
A0-BF, C0-DF or E0-FF occur in the original data. (Thus one such
character will be expanded to two bytes; otherwise, no penalty is
incurred by the compression.)
Relative Byte Addressing
Relative byte addressing is available for fixed and variable record
length files when using the call interface to Extfh. See the section
Callable File Handler Call Interface later in this chapter for details.
When you read or write a record in an indexed, relative or sequential
file, you obtain its relative byte address. Using this address, you can
reread, rewrite or delete it without using keys and indexes. This is a
fast method of accessing records, but has limitations of which you should
be aware:
* A normal relative byte address operation will not change the
current record pointer in the file. Therefore, a READ NEXT after
a relative byte addressing operation returns the record after the
last one accessed using normal access methods. It does not return
the record after the one you accessed using relative byte
addressing.
It is possible, however, to update the current record pointer so
that it points to the record you accessed using relative byte
addressing. A subsequent READ NEXT returns you to the record
after the one you accessed using the relative byte address
operation.
To update the current record pointer, you should set Bit 5 of the
configuration-flags (offset 93) in the FCD before calling Extfh to
perform the relative byte address operation.
* Relative byte operations update the index when a record is
rewritten or deleted.
* If the record has been deleted since the relative byte address was
obtained, then the read or write using relative byte addressing
will usually fail. However, it is possible for it to have been
replaced by a different record, which will not be detected.
Record locking is supported with this mode of operation.
Obtaining the Relative Address.
The relative record address is returned on all operations on the files
that involve specific records. If the operation is unsuccessful, the
value in the relative record address is undefined.
Using the Relative Address.
Once you have obtained the relative address of one or more records, there
are a number of operations you can perform on specific records in the
file. These are outlined in the following sections.
Using the Relative Address to Read a Record.
There are two ways to read a specific record from a file using the
relative address:
1. Put the relative address in the Relative Address field of the FCD
(offset 72) and set bit 6 of the configuration flags in the FCD
(offset 93).
If you want to update the current record pointer to this record,
set bit 5 of the configuration flags (offset 93).
Perform a READ (random) WITH NO LOCK, READ (random) WITH LOCK,
READ (random) WITH KEPT LOCK or READ (random) operation on the
file.
2. The READ (direct) operations work in the same way as described in
1. above but do not require certain Bits in the FCD to be set.
The READ (direct) operations always return the record at the
address given in the relative address field of the FCD and update
the current record pointer to this record.
Both of the above methods provide a way of switching the current key of
reference to a different key. Thus if READ NEXT operations are performed
via the prime key, you can start reading via the first alternate key from
the current record using the following operations:
1. Read the next record in the file (the address of this record is in
the FCD relative address field).
2. Put the new key-of-reference in the Key-Of-Reference field in the
FCD (offset 52).
3. Perform a READ (direct) operation to return the record at this
address and changes the key-of-reference to the new one.
4. Read the next record in the file, which will be obtaining from the
new key-of-reference.
Using the Relative Address to Rewrite a Record.
You can REWRITE a record to a specific address by putting the relative
address of the place where the record is to be rewritten in the Relative
Address field of the FCD and setting bit 6 of the configuration flags in
the FCD (offset 72).
If you want to update the current record pointer to this record, set bit
5 of the configuration flags in the FCD (offset 93).
You then perform a REWRITE operation.
Using the Relative Address to Delete a Record.
You can delete a record at a specific address by putting the address of
the record to be deleted in the Relative Address field of the FCD (offset
72) and setting bit 6 of the configuration flags in the FCD (offset 93).
You then perform a DELETE operation.
File-name Mapping (DOS, Windows and OS/2 only).
When using the Callable File Handler on DOS, Windows and OS/2 systems,
you can map files to different file-names, as well as to different file
organizations. You do this using environment variables.
The syntax of this feature is:
set physical-name-1=physical-name-2 [option]
where:
physical-name-1 is the file-name used in the programs SELECT
statement; for example:
select test-file assign to physical-name-1
physical-name-2 is the actual name of the file to be used
option is an optional parameter which can be one of:
PRINTER this causes the
file to be treated
as a line
sequential file
suitable for a
printer.
MULTI-REEL the file is
treated as a
MULTI-REEL file
BTRIEVEA the file is to be
a Btrieve file
with ANSI
emulation
BTRIEVEN the file is to be
a Btrieve file
without ANSI
emulation
All of the above options can be used with the External File Mapper. See
your COBOL System Reference for details of this utility.
Consider the following examples:
You have a program called XYZ, which writes to a file named test.dat. If
you want test.dat to be a multi-reel file, you enter:
set test.dat=test.dat[multi-reel]
or alternatively, you can put a SELECT clause in the File-Control section
of XYZ, assigning test.dat to test.dat [multi-reel]. If you want this
file to be mapped to test1.dat, enter:
set test.dat=test1.dat
NOTE
* If your program has been compiled using the CHARSET"EBCDIC"
directive and you are using the PRINTER option, you must
ensure that _CODESET is available in your $COBDIR directory.
If you are creating linked applications, you must include
the module _CODESET.OBJ, which is supplied with the system
software.
* File-name mapping using Extfh overrides any syntax
definition for the file within the program.
* This method of file-name mapping is specific to the DOS and
OS/2 operating systems when using the Callable File Handler.
You can also map file-names under DOS, Windows and OS/2
without using the Callable File Handler. For details of how
to do this, see the chapter External File Mapper in your
COBOL System Reference.
* File-name mapping is available under UNIX using the dd_
mechanism. See the chapter External File-name Mapping later
in this manual for details of this mechanism.(UNIX)
MPE/iX 5.0 Documentation