Special File Handling
IOLIST processing  
Input/Output Lists In order to simplify and reduce coding, all Input/Output directives allow the use of common parameter lists called IOLISTs. An IOLIST is a statement that consists of a list of parameters to be used in an Input/Output directive.

To reference an IOLIST the programmer includes the 'IOL=nnnn' option either as the parameter list or within a parameter list of an Input/Output directive. The value of 'nnnn' must be the line number or label of a statement which consists of the IOLIST directive followed by the parameters to be used or a string containing either a compiled object of an IOLIST statement or the name of an IOLIST for the file when the file contains multiple record formats.

An Input/Output directive or IOLIST may contain as many IOL= options as desired.

Example:

0340 READ (1,KEY=K$+"00") IOL=1000
........
0500 WRITE (1,KEY=K$+"00") IOL=1000
........
1000 IOLIST A,D,K(1),F$,F1$

In the above example both the read and the write statements use the same IOLIST assuring that the same record contents are written as were read.

   
Defining IOLISTS on OPEN Another method to reduce the requirements of providing IOLISTs on file Input/Output statements is to provide the IOLIST with the file OPEN directive. If you include the option IOL= within the OPEN statement, all further READ or WRITE statements (which do not specify any form of IOLIST) will automatically use the one given in the OPEN.

For Example:

0010 OPEN(1,IOL=1000) "CSTFLE"
........
0340 READ (1,KEY=K$+"00")
........
0500 WRITE (1,KEY=K$+"00")
........
1000 IOLIST A,D,K(1),F$,F1$

The READ statement at line 0340 and the WRITE statement at line 0500 both will utilize the IOLIST at line 1000.

One major advantage of this technique is that as long as the file remains open, all subsequent READ or WRITE statements will use the IOLIST at 1000 even if they are executed from different programs thus passing just the channel number of an open file, can effectively pass its associated IOLIST.

   
Variable IOLISTs ProvideX also allows you pass IOLISTs as variables and use variables as IOLISTS. In order to utilize a variable as an IOLIST, it must first be initialized with the object code for the desired IOLIST. This can be accomplished via the CPL or PGM functions.

Example:

0100 IOL_1$=CPL("IOLIST A$,B$,D")
or
0100 IOL_1$=PGM(1000)
1000 IOLIST A$,B$,D

NOTE:



*Note* Due to the fact that a RENUMBER directive could change the line number of the IOLIST in the above example, we suggest you use one of the following two pieces of logic:
  1. 0100 IOL_1$=PGM(TCB(4)+1)
    0110 IOLIST A$,B$,D

    This logic uses the function TCB(4) to get the current line number then adds 1. When this is passed to the PGM function, the contents of the NEXT line will be returned, which should have the desired IOLIST. This type of coding will not be effected by a RENUMBER directive.
  2. 0100 IOL_1$=PGM(LNO(MY_IOL))
    .....
    1000 MY_IOL: IOLIST A$,B$,D

    The above logic is similar however uses the LNO function to compute and return the line number of the statement that contains the IOLIST.


  Once a variable has been loaded with the IOLIST, it may be specified following the IOL= option rather than a line number or statement name.

For Example:

READ (1) IOL=IOL_1$

* TIP * One of the easiest ways to handle IOLISTs is to assign them during initialization to Global variables.

For example:

0100 %CST_IOL$=PGM(TCB(4)+1)
0110 IOLIST CST_NM$,CST_ADR$,CST_CITY$,..

This will allow you to easily change IOLISTs without having to make large scale program changes. If desired you could even open the files and assign them Global file numbers.

   
Formatted IOLISTS In addition to simply naming the variables which are to be used in a READ of WRITE directive, an IOLIST can also define the exact Format of a data record. A format specification may be given immediately following the variable names on a IOLIST directive. The Format specification is used to define the exact size and form that the data has on the file record.

Format specifications should be separated from the variable name by a colon and enclosed within square brackets [].

The following table defines the currently supported format specifications:

CHR(len) Variable length string (fixed output)
CHR(dlm) Variable length string (delimited)
LEN(len) Fixed length string
STR(dlm) Quoted String
NUM(len,scl) Fixed length numeric
SGN(len,scl) Signed fixed length numeric
BIN(len,scl) Binary numeric
INT(len,scl) Unsigned integer numeric
BCD(len,scl) Packed decimal numeric

Where:

dlm Defines a single whose first character defines the character that marks the end of the of the field in the record.
len Defines the number of bytes that the fiels will occupy.
scl Defines the number of implied decimal points that are to be included in the numeric value read/written. (The scaling factor)

For Example:

1000 IOLIST NAME$:[CHR(30)],ADDR1$:[CHR(30)]
1010 IOLIST CUST$:[STR(",")],AMNT:[STR(",")], DUEDT$:[STR("")]

In Line 1000 above, the IOLIST would be used for a 60 character record, with the field NAME in positions 1-30 and ADDR1 in positions 31-60. No delimiter would exist between the fields.

In Line 1010 above, the IOLIST would be used against a comma delimited file where the string values would be enclosed in quotes.



*Note* Normal unformatted output is equivalent to a format of CHR(SEP).


  When using the NUM, SGN, BIN, INT, and BCD format specifiers, the scl parameter is used to define the scaling factor to be applied to the numeric data. It represents the number of implied decimal places that are to exist in the number as it resides on the file.

Example:

Value Format File format
123.45 NUM(8,2) 00012345
1 NUM(8,2) 00000100
-23 NUM(8,2) 00002300
-23 SGN(8,2) 0002300-
1.6 BIN(2,1) $0010$
   
Prefixing via REC= Sometimes when using common IOLISTs it is desirable to temporarily override the variable names in the IOLIST. The REC= option provides this capability. When this option is specified, the variable name which is provided (following the REC=) is used to prefix all the variables in the IOLIST.

Example:

0010 LET GL_FL=HFN; OPEN (GL_FL,IOL=8000) "GLTRAN"
0100 INPUT "Which Credit GL account:",CR$:"AA-0000"
0110 READ (GL_FL,KEY=CR$,REC=CR$,DOM=0100)
0120 INPUT " Debit GL account:",DB$:"AA-0000"
0130 READ (GL_FL,KEY=DB$,REC=DB$,DOM=0120)
0140 INPUT "Amount:",AMNT:"$###,##0.00-"
0150 IF AMNT=0 THEN GOTO 0140
0160 CR.BAL=CR.BAL+AMNT, DB.BAL=DB.BAL+AMNT
0170 WRITE (GL_FL,KEY=CR$,REC=CR$)
0180 WRITE (GL_FL,KEY=DB$,REC=DB$)
0190 GOTO 0100
8000 IOLIST DESC$,BAL

In the above example, the REC= option is used to maintain two separate records in memory. One record will have all its variables prefixed with 'DB.' , the other will have 'CR.' prefixes.



*Note* The REC= option may also appear in the OPEN directive.


Data Dictionary IOLIST ProvideX includes several facilities for building and accessing a data dictionary. While the data dictionary itself has multiple uses from rapid application development to the conversion of data; one of its main features is the ability to embed the dictionary into data files and thereby allow the system to generate IOLISTs automatically.

When the definition is embedded in the physical data file, the need for an IOLIST statement in your database application is rendered obsolete. An IOList reference is not required for a READ or WRITE statement. For example, the usual method for reading data from a data file without an embedded definition would appear as follows:

OPEN (1)"SomeFile"
READ (1)name$,address$,company$

or

READ (1)IOL=MyIOL
PRINT name$
MyIOL: IOLIST name$,address$,company$

If a data dictionary definition is embedded in the physical file, the same routine could be handled as follows:

OPEN (1,IOL=*)"SomeFile" ! OPEN using Data Dictionary
READ (1)
PRINT name$

The IOL=* option defines a standard IOList to be used while the file is open and the asterisk indicates that the system is to use the IOLIST embedded within the file itself.. You can also use the REC= option to supply a prefix to be added to all the variables in the IOL=. For example in:

Open (1,IOL=*,REC="a")"SomeFile" ! OPEN using Data Dictionary
Read (1)
Print a.name$

The asterisk itself is used to indicate the use of the the embedded definition. Optionally you can use a caret to open a file using analternate IOList.

The following program illustrates how to open a file and read its contents using an embedded definition.

00020 BEGIN
00030 OPEN (1,IOL=*)"cstfile" ! Open with data dictionary access
00040 PRINT "Load regular IOLIST ___________________"
00050 READ (1,END=0080) ! No reference to IOL required
00060 GOSUB PRINT_RECORD
00070 GOTO 0050
00080 CLOSE (1)
00160 END
00170 PRINT_RECORD:
00180 PRINT "___"+KEC(1)+"___"
00190 PRINT "Standard iolist"
00200 PRINT "CST_ID$=",CST_ID$
00210 PRINT "CST_NAME$=",CST_NAME$
00220 PRINT "CST_ADDR$=",CST_ADDR$
00230 RETURN

   
Multiple Record Formats The data dictionary system also supports multiple-format files, such as those with header and detail records. These are often referred to as variant records. The ability to define non-normalized data files is provided within the data dictionary maintence facility and access to the multiple formats is supported by PxPlus.

Language level multiple record format access is a +PxPlus Exclusive

To access the various formats embedded within a data file, the IOL= option has been extended to allow the programmer to specify the name of the format to use.

For example, assuming a file contains two formats "Header" and "Detail":

OPEN (HFN, IOL="Detail" ) "TheFile"

This will open the data file and assign the default IOLIST to the format named "Detail". All subsequent READ/WRITE requests that do not specify the data format will use the format as defined by "Detail". To override the format, the programmer may specifiy the name of the format as follows:

READ (nnn, KEY=Invoice$) IOL="Header"

Named formats may also be accessed in the IOL( ) function as in:

X$ = IOL (nnn:"Header")

This function will return the internally 'compiled' IOLIST that matches the format specified. The FIN ( ) function with a "FORMATS" specificaion can be used to obtain a comma seperated list of valid formats for an opened file.



*Note* An Error # 81:Invalid IOLIST specification will be generated if a named format requested does exist on the file.