 |
OpenVMS Utility Routines Manual
This routine also returns any condition values returned by
user-supplied routines.
FILEIO
The user-supplied FILEIO routine performs file I/O functions. Call it
by specifying it as an argument in the EDT$EDIT routine. It cannot be
called independently.
Format
FILEIO code ,stream ,record ,rhb
RETURNS
OpenVMS usage: |
cond_value |
type: |
longword (unsigned) |
access: |
write only |
mechanism: |
by value |
A status code that your FILEIO routine returns to EDT$EDIT. The
fileio argument is a longword containing the status
code. The only failure code that is normally returned is RMS$_EOF from
a GET call. All other OpenVMS RMS errors are signaled, not returned.
The RMS signal should include the file name and both longwords of the
RMS status. Any errors detected with the FILEIO routine can be
indicated by setting status to an error code. That special error code
will be returned to the program by the EDT$EDIT routine. There is a
special status value EDT$_NONSTDFIL for nonstandard file opening.
Condition values are returned in R0.
Arguments
code
OpenVMS usage: |
longword_unsigned |
type: |
longword (unsigned) |
access: |
read only |
mechanism: |
by reference |
A code from EDT that specifies what function the FILEIO routine is to
perform. The code argument is the address of a
longword integer containing this code. Following are the valid function
codes:
Function Code |
Description |
EDT$K_OPEN_INPUT
|
The
record argument names a file to be opened for input.
The
rhb argument is the default file name.
|
EDT$K_OPEN_OUTPUT_SEQ
|
The
record argument names a file to be opened for output
as a sequenced file. The
rhb argument is the default file name.
|
EDT$K_OPEN_OUTPUT_NOSEQ
|
The
record argument names a file to be opened for output.
The
rhb argument is the default file name.
|
EDT$K_OPEN_IN_OUT
|
The
record argument names a file to be opened for both
input and output. The
rhb argument is the default file name.
|
EDT$K_GET
|
The
record argument is to be filled with data from the
next record of the file. If the file has record prefixes,
rhb is filled with the record prefix. If the file has
no record prefixes,
rhb is not written. When you attempt to read past the
end of file,
status is set to RMS$_EOF.
|
EDT$K_PUT
|
The data in the
record argument is to be written to the file as its
next record. If the file has record prefixes, the record prefix is
taken from the
rhb argument. For a file opened for both input and
output, EDT$K_PUT is valid only at the end of the file, indicating that
the
record is to be appended to the file.
|
EDT$K_CLOSE_DEL
|
The file is to be closed and then deleted. The
record and
rhb arguments are not used in the call.
|
EDT$K_CLOSE
|
The file is to be closed. The
record and
rhb arguments are not used in the call.
|
stream
OpenVMS usage: |
longword_unsigned |
type: |
longword (unsigned) |
access: |
read only |
mechanism: |
by reference |
A code from EDT that indicates which file is being used. The
stream argument is the address of a longword integer
containing the code. Following are the valid codes:
Function Code |
Description |
EDT$K_COMMAND_FILE
|
The command file.
|
EDT$K_INPUT_FILE
|
The primary input file.
|
EDT$K_INCLUDE_FILE
|
The secondary input file. Such a file is opened in response to an
INCLUDE command. It is closed when the INCLUDE command is complete and
will be reused for subsequent INCLUDE commands.
|
EDT$K_JOURNAL_FILE
|
The journal file. If bit 0 of the options is set, it is opened for both
input and output and is read completely. Otherwise, it is opened for
output only. After it is read or opened for output only, it is used for
writing. On a successful termination of the editing session, the
journal file is closed and deleted. EXIT/SAVE and QUIT/SAVE close the
journal file without deleting it.
|
EDT$K_OUTPUT_FILE
|
The primary output file. It is not opened until you enter the EXIT
command.
|
EDT$K_WRITE_FILE
|
The secondary output file. Such a file is opened in response to a WRITE
or PRINT command. It is closed when the command is complete and will be
reused for subsequent WRITE or PRINT commands.
|
record
OpenVMS usage: |
char_string |
type: |
character-coded text string |
access: |
modify |
mechanism: |
by descriptor |
Text record passed by descriptor from EDT to the user-supplied FILEIO
routine; the code argument determines how the
record argument is used. The record
argument is the address of a descriptor pointing to this argument. When
the code argument starts with EDT$K_OPEN, the
record is a file name. When the code
argument is EDT$K_GET, the record is a place to store
the record that was read from the file. For code
argument EDT$K_PUT, the record is a place to find the
record to be written to the file. This argument is not used if the
code argument starts with EDT$K_CLOSE.
Note that for EDT$K_GET, EDT uses a dynamic or varying string
descriptor; otherwise, EDT has no way of knowing the length of the
record being read. EDT uses only string descriptors that can be handled
by the Run-Time Library routine STR$COPY_DX.
rhb
OpenVMS usage: |
char_string |
type: |
character-coded text string |
access: |
modify |
mechanism: |
by descriptor |
Text record passed by descriptor from EDT to the user-supplied FILEIO
routine; the code argument determines how the
rhb argument is used. When the code
argument starts with EDT$K_OPEN, the rhb argument is
the default file name. When the code is EDT$K_GET and
the file has record prefixes, the prefixes are put in this argument.
When the code is EDT$K_PUT and the file has record
prefixes, the prefixes are taken from this argument. Like the
record argument, EDT uses a dynamic or varying string
descriptor for EDT$K_GET and uses only string descriptors that can be
handled by the Run-Time Library routine STR$COPY_DX.
Description
If you do not need to intercept any file I/O, you can use the entry
point EDT$FILEIO for this argument or you can omit it. If you need to
intercept only some file I/O, call the EDT$FILEIO routine for the other
cases.
When you use EDT$FILEIO as a value for the fileio
argument, files are opened as follows:
- The record argument is always the RMS file name.
- The rhb argument is always the RMS default file
name.
- There is no related name for the input file.
- The related name for the output file is the input file with OFP
(output file parse). EDT passes the input file name, the output file
name, or the name from the EXIT command in the record
argument.
- The related name for the journal file is the input file name with
the OFP RMS bit set.
- The related name for the INCLUDE file is the input file name with
the OFP set. This is unusual because the file is being opened for input.
EDT contains support for VFC files. Normally, EDT will zero the length
of the RHB field if the file is not a VFC file. However, when the user
supplies the FILEIO routines, they are responsible for performing this
operation.
EDT checks for a VFC file with the following algorithm:
IF FAB$B_RFM = FAB$C_VFC
AND FAB$B_RAT <> FAB$M_PRN
THEN
VFC file
ELSE
not VFC file, zero out RHB descriptor length field.
|
Condition Values Returned
SS$_NORMAL
|
Normal successful completion.
|
EDT$_NONSTDFIL
|
File is not in standard text format.
|
RMS$_EOF
|
End of file on a GET.
|
WORKIO
The user-supplied WORKIO routine is called by EDT when it needs
temporary storage for the file being edited. Call it by specifying it
as an argument in the EDT$EDIT routine. It cannot be called
independently.
Format
WORKIO code ,recordno ,record
RETURNS
OpenVMS usage: |
cond_value |
type: |
longword (unsigned) |
access: |
write only |
mechanism: |
by immediate value |
Longword value returned as a status code. It is generally a success
code, because all OpenVMS RMS errors should be signaled. The signal
should include the file name and both longwords of the RMS status. Any
errors detected within work I/O can be indicated by setting status to
an error code, which will be returned by the EDT$EDIT routine.
The condition value is returned in R0.
Arguments
code
OpenVMS usage: |
longword_unsigned |
type: |
longword (unsigned) |
access: |
read only |
mechanism: |
by reference |
A code from EDT that specifies the operation to be performed. The
code argument is the address of a longword integer
containing this argument. The valid function codes are as follows:
Function Code |
Description |
EDT$K_OPEN_IN_OUT
|
Open the work file for both input and output. Neither the
record nor
recordno argument is used.
|
EDT$K_GET
|
Read a record. The
recordno argument is the number of the record to be
read. The
record argument gives the location where the record is
to be stored.
|
EDT$K_PUT
|
Write a record. The
recordno argument is the number of the record to be
written. The
record argument tells the location of the record to be
written.
|
EDT$K_CLOSE_DEL
|
Close the work file. After a successful close, the file is deleted.
Neither the
record nor
recordno argument is used.
|
recordno
OpenVMS usage: |
longword_signed |
type: |
longword integer (signed) |
access: |
read only |
mechanism: |
by reference |
Number of the record to be read or written. The
recordno argument is the address of a longword integer
containing this argument. EDT always writes a record before reading
that record. This argument is not used for open or close calls.
record
OpenVMS usage: |
char_string |
type: |
character string |
access: |
modify |
mechanism: |
by descriptor |
Location of the record to be read or written. This argument always
refers to a 512-byte string during GET and PUT calls. This argument is
not used for open or close calls.
Description
Work file records are addressed only by number and are always 512 bytes
long. If you do not need to intercept work file I/O, you can use the
entry point EDT$WORKIO for this argument or you can omit it.
Condition Value Returned
SS$_NORMAL
|
Normal successful completion.
|
XLATE
The user-supplied XLATE routine is called by EDT when it encounters the
nokeypad command XLATE. You cause it to be called by specifying it as
an argument in the EDT$EDIT routine. It cannot be called independently.
Format
XLATE string
RETURNS
OpenVMS usage: |
cond_value |
type: |
longword (unsigned) |
access: |
write only |
mechanism: |
by value |
Longword value returned as a status code. It is generally a success
code. If the XLATE routine cannot process the passed string for some
reason, it sets status to an error code. Returning an error code from
the XLATE routine aborts the current key execution and displays the
appropriate error message.
The condition value is returned in R0.
Argument
string
OpenVMS usage: |
char_string |
type: |
character-coded text string |
access: |
modify |
mechanism: |
by descriptor |
Text string passed to the nokeypad command XLATE. You can use the
nokeypad command XLATE by defining a key to include the following
command in its definition:
The text is passed by the string argument. The
string argument can be handled by the Run-Time Library
routine STR$COPY_DX.
This argument is also a text string returned to EDT. The string is made
up of nokeypad commands that EDT is to execute.
Description
The nokeypad command XLATE allows you to gain control of the EDT
session. (See the OpenVMS EDT Reference Manual1 for more information about
the XLATE command.) If you do not need to gain control of EDT during
the editing session, you can use the entry point EDT$XLATE for this
argument or you can omit it.
Condition Value Returned
SS$_NORMAL
|
Normal successful completion.
|
Note
1 This manual has been archived but is
available on the OpenVMS Documentation CD-ROM.
|
Chapter 10 File Definition Language (FDL) Routines
This chapter describes the File Definition Language (FDL) routines.
These routines perform many of the functions of the File Definition
Language that define file characteristics. Typically, you use FDL to
perform the following operations:
- Specify file characteristics otherwise unavailable from your
language.
- Examine or modify the file characteristics of an existing data file
to improve program or system interaction with that file.
10.1 Introduction to FDL Routines
You specify FDL attributes for a data file when you use FDL to create
the data file, set the desired file characteristics, and close the
file. You can then use the appropriate language statement to reopen the
file. Because the data file is closed between the time the FDL
attributes are set and the time your program accesses the file, you
cannot use FDL to specify run-time attributes (attributes that are
ignored or deleted when the associated data file is closed).
The FDL$CREATE routine is the one most likely to be called from a
high-level language. It creates a file from an FDL specification and
then closes the file. The following Compaq Fortran program segment
creates an empty data file named INCOME93.DAT using the file
characteristics specified by the FDL file INCOME.FDL. The
STATEMENT variable contains the number of the last FDL
statement processed by FDL$CREATE; this argument is useful for
debugging an FDL file.
INTEGER STATEMENT
INTEGER STATUS,
2 FDL$CREATE
STATUS = FDL$CREATE ('INCOME.FDL',
2 'INCOME93.DAT',
2 ,,,,
2 STATEMENT,
2 ,,)
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
.
.
.
|
The following three FDL routines provide a way to specify all the
options OpenVMS RMS allows when it executes create, open, or connect
operations. They also allow you to specify special processing options
required for your applications.
- The FDL$GENERATE routine produces an FDL specification by
interpreting a set of RMS control blocks in an existing data file. It
then writes the FDL specification either to an FDL file or to a
character string. If your programming language does not provide
language statements that access RMS control blocks (for example, Compaq
Fortran), you must use FDL$GENERATE from within the context of a
user-open routine to generate an FDL file.
- The FDL$PARSE routine parses an FDL specification, allocates RMS
control blocks, and fills in the relevant fields.
- The FDL$RELEASE routine deallocates the virtual memory used by the
RMS control blocks created by FDL$PARSE.
These routines cannot be called from asynchronous system trap (AST)
level. In addition, in order to function properly, these routines
require ASTs to remain enabled.
An FDL specification can be in either a file or a character string.
When specifying an FDL specification in a character string, use
semicolons to delimit the statements of the FDL specification.
10.2 Using the FDL Routines: Examples
This section provides examples that demonstrate the use of the FDL
routines in various programming scenarios.
- Example 10-1 shows how to use the FDL$CREATE routine in a Fortran
program.
- Example 10-2 shows how to use the FDL$PARSE and FDL$RELEASE
routines in a C program.
- Example 10-3 shows a Compaq Pascal program that uses the
FDL$PARSE routine to fill in the RMS control blocks in a data file. The
program then uses the FDL$GENERATE routine to create an FDL file using
the information in the control blocks.
Example 10-1 Using FDL$CREATE in a Fortran
Program |
* This program calls the FDL$CREATE routine. It
* creates an indexed output file named NEW_MASTER.DAT
* from the specifications in the FDL file named
* INDEXED.FDL. You can also supply a default filename
* and a result name (that receives the name of the
* created file). The program also returns all the
* statistics.
*
IMPLICIT INTEGER*4 (A - Z)
EXTERNAL LIB$GET_LUN, FDL$CREATE
CHARACTER IN_FILE*11 /'INDEXED.FDL'/,
1 OUT_FILE*14 /'NEW_MASTER.DAT'/,
1 DEF_FILE*11 /'DEFAULT.FDL'/,
1 RES_FILE*50
INTEGER*4 FIDBLK(3) /0,0,0/
I = 1
STATUS = FDL$CREATE (IN_FILE,OUT_FILE,
DEF_FILE,RES_FILE,FIDBLK,,)
IF (.NOT. STATUS) CALL LIB$STOP (%VAL(STATUS))
STATUS=LIB$GET_LUN(LOG_UNIT)
OPEN (UNIT=LOG_UNIT,FILE=RES_FILE,STATUS='OLD')
CLOSE (UNIT=LOG_UNIT, STATUS='KEEP')
WRITE (6,1000) (RES_FILE)
WRITE (6,2000) (FIDBLK (I), I=1,3)
1000 FORMAT (1X,'The result filename is: ',A50)
2000 FORMAT (/1X,'FID-NUM: ',I5/,
1 1X,'FID-SEQ: ',I5/,
1 1X,'FID-RVN: ',I5)
END
|
Example 10-2 shows how to use the FDL$PARSE and FDL$RELEASE routines
in a C program.
Example 10-2 Using FDL$PARSE and FDL$RELEASE
in a C Program |
/* FDLEXAM.C
** This program calls the FDL utility routines FDL$PARSE and
** FDL$RELEASE. First, FDL$PARSE parses the FDL specification
** PART.FDL. Then the data file named in PART.FDL is accessed
** using the primary key. Last, the control blocks allocated
** by FDL$PARSE are released by FDL$RELEASE.
** Note; to try this program use the following command on any
** file with textual data: $ANALYZE/RMS/FDL/OUT=PART.FDL
*/
#include <descrip>
#include <rms>
#define REC_SIZE 80 /* as appropriate for files used */
FDLEXAM ()
{
struct FAB *fab_ptr; /* variable to hold pointer to FAB structure */
struct RAB *rab_ptr; /* variable to hold pointer to RAB structure */
$DESCRIPTOR (fdl_file, "PART.FDL"); /* free choice of name */
char record_buffer[REC_SIZE+1]; /* allow for null terminator */
int stat;
/*
** Read and parse FDL file allocating and initializing RAB and
** and FAB accordingly, returning pointers to the FAB & RAB.
*/
stat = FDL$PARSE ( &fdl_file, &fab_ptr, &rab_ptr );
if (!(stat & 1)) LIB$STOP ( stat );
/*
** Try to open file as described by information in the FAB.
** Signal open errors. Note the usage of STAT, instead of
** FAB_PTR->FAB$L_STS because just in case the FAB is invalid,
** the only status returned is STAT.
*/
stat = SYS$OPEN ( fab_ptr );
if (!(stat & 1)) LIB$STOP ( stat, fab_ptr->fab$l_stv );
stat = SYS$CONNECT ( rab_ptr );
if (!(stat & 1)) LIB$STOP ( stat, rab_ptr->rab$l_stv );
/*
** Opened the file and connect some internal buffers.
** Fill in the record output buffer information which is the only
** missing information in the RAB that was created for us by FDL.
** Print a header recod and perform the initial $GET.
*/
rab_ptr->rab$w_usz = REC_SIZE;
rab_ptr->rab$l_ubf = record_buffer;
printf ("------------------- start of records -------------- \n");
stat = SYS$GET ( rab_ptr );
while (stat & 1) /* As long as the $GET is successful */
{
record_buffer[rab_ptr->rab$w_rsz] = 0; /* Terminate for printf */
printf ("%s\n", record_buffer); /* Current record */
stat = SYS$GET ( rab_ptr ); /* Try to get next one */
}
/*
** At this point in the execution, the status should be EOF indicating
** Successfully read the file to end. If not, signal real error.
*/
if (stat != RMS$_EOF) LIB$STOP ( rab_ptr->rab$l_sts, rab_ptr->rab$l_stv );
printf ("-------------------- end of records --------------- \n");
stat = SYS$CLOSE ( fab_ptr ); /* implicit $DISCONNECT */
if (!(stat & 1)) LIB$STOP ( fab_ptr->fab$l_sts, fab_ptr->fab$l_stv );
/*
** Allow FDL to release the FAB and RAB structures and any other
** structures (XAB) that it allocated on behalf of the program.
** Return with its status as final status (success or failure).
*/
return FDL$RELEASE ( &fab_ptr, &rab_ptr );
}
|
Example 10-3 shows a Compaq Pascal program that uses the FDL$PARSE
routine to fill in the RMS control blocks in a data file, and then uses
the FDL$GENERATE routine to create an FDL file.
Example 10-3 Using FDL$PARSE and FDL$GENERATE
in a Compaq Pascal Program |
[INHERIT ('SYS$LIBRARY:STARLET')]
PROGRAM FDLexample (input,output,order_master);
(* This program fills in its own FAB, RAB, and *)
(* XABs by calling FDL$PARSE and then generates *)
(* an FDL specification describing them. *)
(* It requires an existing input FDL file *)
(* (TESTING.FDL) for FDL$PARSE to parse. *)
TYPE
(*+ *)
(* FDL CALL INTERFACE CONTROL FLAGS *)
(*- *)
$BIT1 = [BIT(1),UNSAFE] BOOLEAN;
FDL2$TYPE = RECORD CASE INTEGER OF
1: (FDL$_FDLDEF_BITS : [BYTE(1)] RECORD END;
);
2: (FDL$V_SIGNAL : [POS(0)] $BIT1;
(* Signal errors; don't return *)
FDL$V_FDL_STRING : [POS(1)] $BIT1;
(* Main FDL spec is a char string *)
FDL$V_DEFAULT_STRING : [POS(2)] $BIT1;
(* Default FDL spec is a char string *)
FDL$V_FULL_OUTPUT : [POS(3)] $BIT1;
(* Produce a complete FDL spec *)
FDL$V_$CALLBACK : [POS(4)] $BIT1;
(* Used by EDIT/FDL on input (DEC only) *)
)
END;
mail_order = RECORD
order_num : [KEY(0)] INTEGER;
name : PACKED ARRAY[1..20] OF CHAR;
address : PACKED ARRAY[1..20] OF CHAR;
city : PACKED ARRAY[1..19] OF CHAR;
state : PACKED ARRAY[1..2] OF CHAR;
zip_code : [KEY(1)] PACKED ARRAY[1..5]
OF CHAR;
item_num : [KEY(2)] INTEGER;
shipping : REAL;
END;
order_file = [UNSAFE] FILE OF mail_order;
ptr_to_FAB = ^FAB$TYPE;
ptr_to_RAB = ^RAB$TYPE;
byte = 0..255;
VAR
order_master : order_file;
flags : FDL2$TYPE;
order_rec : mail_order;
temp_FAB : ptr_to_FAB;
temp_RAB : ptr_to_RAB;
status : integer;
FUNCTION FDL$PARSE
(%STDESCR FDL_FILE : PACKED ARRAY [L..U:INTEGER]
OF CHAR;
VAR FAB_PTR : PTR_TO_FAB;
VAR RAB_PTR : PTR_TO_RAB) : INTEGER; EXTERN;
FUNCTION FDL$GENERATE
(%REF FLAGS : FDL2$TYPE;
FAB_PTR : PTR_TO_FAB;
RAB_PTR : PTR_TO_RAB;
%STDESCR FDL_FILE_DST : PACKED ARRAY [L..U:INTEGER]
OF CHAR) : INTEGER;
EXTERN;
BEGIN
status := FDL$PARSE ('TESTING',TEMP_FAB,TEMP_RAB);
flags::byte := 0;
status := FDL$GENERATE (flags,
temp_FAB,
temp_RAB,
'SYS$OUTPUT:');
END.
|
|