PLISRTx Subroutines

Purpose

These routines enable data to be sorted, with source and destination as indicated by the following table:

  Input Data From     Output Data To
PLISRTA     Input file Output file
PLISRTB Procedure Output file
PLISRTC Input file Procedure
PLISRTD Procedure Procedure
RECORD Input file ??

Syntax

CALL PLISRTA(fields–spec, records-spec, storage,
			 ret-code [,prefix][,msg-level]
			 [,algorithm]);
CALL PLISRTB(fields-spec, records-spec, storage,
			 ret-code, input-proc[,prefix][msg-level][,algorithm]);
CALL PLISRTC(fields-spec, records-spec, storage,
			 ret-code, output-proc [,prefix][,msg-level]
			 [,algorithm]);
CALL PLISRTD(fields-spec, records-spec, storage,
			 ret-code, input-proc, output-proc [,prefix]
			 [,msg-level][,algorithm]);

Parameters

fields-spec is a character-string having the following format:

`boxSORTboxFIELDS=(pos,len,type,seq,[,posj,lenj,typej,seqj]...) [,options-list]box'

box, in each of the three instances, represents one or more space characters. These are the only spaces that may occur in the string.

  • pos is the start position of a sort key-field with the records. The position is given in bytes, with 1 representing the first byte.
  • len is the length of the key in bytes.
  • type is the key type, as follows:
    CH character string
    ZD pictured
    PD fixed decimal
    Fl fixed binary
    BI bit string
    FL float binary
  • seq must be A or D, indicating whether to sort with ascending or descending values of this key.

    The following items can be specified in the options-list:

    FILSZ=n Specifies the number of records in the sort. This option is ignored.
    SKIPREC=n Specifies that n records at the beginning of the input file are to be skipped.
    CKPT or CHKPT Specifies that checkpoints are to be taken. This option is ignored.
    EQUALS Specifies a stable sort algorithm (that is, that records with identical key values are to be kept in the same order they have in the input file or were given by the input procedure.
    NOEQUALS Specifies that a stable sort algorithm will not be used. This is the default.
    DYNALLOC=(d,n) Specifies the intermediate storage.

records–spec is a character-string having the following format:

`boxRECORDboxTYPE=rectype,LENGTH=(len)[,ftype]box'

box, in each of the three instances, represents one or more space characters. These are the only spaces that may occur in the string.

  • rectype is F or V, indicating fixed-length records or variable-length ASCII records, respectively.
  • len specifies the length of the records to be sorted.
  • ftype is INDEXED. If ftype is omitted, CONSECUTIVE is assumed.

storage: This argument is ignored.

Description

The input records are sorted as specified by the parameters and written to the output file or passed to the output procedure, as appropriate.

If an input or output procedure is used, it is called repeatedly by the sort subroutine, once for each record involved in the sort. Hence, the procedure must be written so as to process one record at a time. These procedures are ordinary PL/I procedures, and all PL/I language rules apply. Any contained AUTOMATIC variables are reinitialized at each invocation of the procedure and any allocated BASED or CONTROLLED variables are freed when the procedure returns.

An input procedure must have the form:

IN_PROC: PROCEDURE RETURNS(CHAR(len));
   DECLARE S CHAR(len);
   IF LAST_REC THEN DO;
      CALL PLIRETC(8);
/* must tell the sort routine all records have been sent */
      RETURN(S);
      END;
   ELSE DO;
      /* code to produce the record goes here */
      CALL PLIRETC(12);
/* tell the sort routine this is not the last record */ 
      RETURN(S);
      END;
END IN_PROC;

An output procedure must have the form:

OUT_PROC: PROCEDURE(S);
   DECLARE S CHAR(*);
   /* code to process the sorted record goes here */ 
   CALL PLIRETC(4);
/* tell the sort routine to continue sending records */ 
END OUT_PROC;

In the output procedure, use CALL PLI RETC(16); to tell the sort routine to terminate unsuccessfully.

Examples

Example 1

 plisrt1: proc options(main);
   /* 
      Examples of the PLISRT Built in functions.

      This program uses a data file named 'SRT1IN', 
      with a record length of 20, which must already exist.
   */

   dcl  (plisrta, plisrtb, plisrtc, plisrtd) builtin;

   declare ret_code fixed bin(31);
   declare eof bit(1);
   declare chkdata file;
   declare rec char(20);

   put skip list('Plisrt1 starting...');
   put skip(2) list('Contents of SRT1IN :-');

   /* display the input file */
   open file(chkdata) record title('SRT1IN');
   eof = '0'b;
   on endfile(chkdata) eof='1'b;
   read file(chkdata) into(rec);
   do while(eof = '0'b);
      put skip list(rec);
      read file(chkdata) into(rec);
      end;
   close file(chkdata);
   revert endfile(chkdata);

   put skip(2) list('Calling plisrta ---------------------------->');
   call plisrta(' sort fields=(1,10,ch,a),equals',
             ' record type=F,length=(20) ',
             0 ,              /* strg */
             ret_code,
             'SRT1',         /* data name prefix */
             'AP',           /* msg level */
             'xxxx'          /* sort method */);
   put skip list('result code is ', ret_code);

   /* display output file of above */
   put skip(2) list('Contents of SRT1OUT :-');
   open file(chkdata) record title('SRT1OUT');
   eof = '0'b;
   on endfile(chkdata) eof='1'b;
   read file(chkdata) into(rec);
   do while(eof = '0'b);
      put skip list(rec);
      read file(chkdata) into(rec);
      end;
   close file(chkdata);
   revert endfile(chkdata);

   put skip(2) list('Calling plisrtb ---------------------------->');
   call plisrtb(' sort fields=(1,10,ch,a)',
             ' record type=f,length=(20) ',
             0 ,              /* strg */
             ret_code,
             input_proc,
             ,               /* data name prefix */
             'AP',           /* msg level */
             'xxxx'          /* sort method */);
   put skip list('result code is ',ret_code);

   /* display output file of above */
   put skip(2) list('Contents of SORTOUT :-');
   open file(chkdata) record title('SORTOUT');
   eof = '0'b;
   on endfile(chkdata) eof='1'b;
   read file(chkdata) into(rec);
   do while(^eof);
      put skip list(rec);
      read file(chkdata) into(rec);
      end;
   close file(chkdata);
   revert endfile(chkdata);

   put skip(2) list('Calling plisrtc ---------------------------->');
   call plisrtc(' sort fields=(1,10,ch,a) ',
             ' record type=f,length=(20) ',
             0 ,              /* strg */
             ret_code,
             output_proc,
             'SRT1',          /* data name prefix */
             'AP',            /* msg level */
             'xxxx'           /* sort method */);
   put skip list('result code is ',ret_code);

   put skip(2) list('Calling plisrtd ---------------------------->');
   call plisrtd(' sort fields=(1,10,ch,a),skiprec=3 ',
             ' record type=f,length=(20) ',
             0 ,              /* strg */
             ret_code,
             input_proc,
             output_proc,
             ,                /* data name prefix */
             'AP',            /* msg level */
             'xxxx'          /* sort method */);
   put skip list('result code is ',ret_code);

   /* reset the PL/1 return code */
   call pliretc(0);
   put skip(2) list('Plisrt1 processing completed');


 input_proc: procedure returns(char(20));
   dcl x char(20);
   dcl cnt fixed bin(31) static internal initial(0);
   dcl rec(1:5) char(20) static internal initial (
        'abc2', 'abc4', 'abc1', 'abc6', 'abc3');
   
   cnt = cnt + 1;
   if cnt <= 5 then do;
      x=rec(cnt); 
      call pliretc(12);
      end;
   else do;
      x = '';
      call pliretc(8);   /* no more */
      cnt = 0;
      end;
   return(x);
 end input_proc;

 output_proc: procedure(y);
   dcl y char(*);

   put skip list(y);
   call pliretc(4);    /* ready for more */
 end output_proc;

end plisrt1;

Example 2

test: proc options(main);

   /* Test of SORT Bif using a indexed file as input.
   /* The input file is 1st created by this program prior to the sort. */

/*
/* How to compile/link
/*
/* mfplx srt2.pl1 -defext -cisam
*/

/* Output of this program:
/*
/* Creating a indexed file with following records:
/*
/* Calling plisrtc ---------------------------------------
/* Sorting on 2nd column ASCENDING, 1st column DECENDING
/*    Boston                             abc
/*    Albany                             ccc
/*    Westboro                           xyz
/*    Milford                            xyz
/*    Acton                              xyz
/*
/**/

   dcl   plisrtd builtin;
   declare ret_code fixed bin(31);
   declare (input_proc,output_proc) entry;

   dcl SORTIN direct env(vsam keylength(8) keyloc (5) recsize(50));
   dcl rec char(50);

   %replace KEY2 by 40;       /* be sure to change other references */
   %replace KEY2_LEN by 3;    /* be sure to change other references */

   put skip list('Creating a indexed file with following records:');
   open file(SORTIN) output;

   rec = ' ';
   substr(rec,KEY2,KEY2_LEN) = 'ccc';
   write file(SORTIN) from(rec) keyfrom('Albany');

   rec = ' ';          
   substr(rec,KEY2,KEY2_LEN) = 'xyz';
   write file(SORTIN) from(rec) keyfrom('Acton');

   rec = ' ';          
   substr(rec,KEY2,KEY2_LEN) = 'abc';
   write file(SORTIN) from(rec) keyfrom('Boston');

   rec = ' ';          
   substr(rec,KEY2,KEY2_LEN) = 'xyz';
   write file(SORTIN) from(rec) keyfrom('Westboro');

   rec = ' ';          
   substr(rec,KEY2,KEY2_LEN) = 'xyz';
   write file(SORTIN) from(rec) keyfrom('Milford');
   close file(SORTIN);
   put skip;

   put skip list('Calling plisrtc ---------------------------------------');
   put skip list('Sorting on 2nd column ASCENDING, 1st column DECENDING');
   call plisrtc(' sort fields=(40,3,ch,a,5,8,ch,d) ',
             ' record type=f,length(50),indexed ',
             0 ,            /* strg */
             ret_code,      /* result status */
             output_proc,
             ,              /* data name prefix */
             'AP',          /* msg level */
             'xxxx'         /* sort method */);
   put skip list('result code is ',ret_code);

end test;

output_proc: procedure(x);
   dcl x char(*);

   put skip list(x);
   call pliretc(4);    /* ready for more */
end output_proc;

Restrictions

Open PL/I supports up to 64 sort keys. All sort control keys must fit into 1024 bytes.