SOURCE Procedure: z/OS

Provides an easy way to back up and process source library data sets.
z/OS specifics: All

Syntax

PROC SOURCE <options > ;
SELECT member-1 < . . . member-n > ;
EXCLUDE member-1 < . . . member-n > ;
FIRST 'model-control-statement ';
LAST 'model-control-statement ';
BEFORE 'model-control-statement ' <options > ;
AFTER 'model-control-statement' <options > ;

Details

Overview of PROC SOURCE

Use PROC SOURCE to read PDS or PDSE libraries and produce sequential output.
You can use the SOURCE procedure to perform the following tasks:
  • write the contents of an entire library to the SAS log.
  • process only the directory of a library in order to produce input for SAS software, for a utility, or for other programs.
  • route the members of a library to other programs for processing. By default, PROC SOURCE generates records for the IBM utility, IEBUPDTE, which reloads an unloaded data set.
  • create a sequential, or unloaded, version of the library's directory records.
  • construct an unloaded data set from a library. The unloaded data set is suitable for reloading by IEBUPDTE or other source library maintenance utilities, including the ability to recognize and properly handle aliases.
Using the SOURCE procedure, a source library can be copied into a sequential tape or disk data set to create either a backup or a manually transportable copy of the source data. This copy is called an unloaded data set; it consists of 80-byte records that contain the source data and the control information that are needed to restore the source to its original organization. When an unloaded data set is restored by the proper utility to a device that supports the data in their original form, the data is reconstructed, or loaded.
The INDD and OUTDD data sets can have an LRECL that is greater than 80. The larger LRECL might be useful if you want to simply concatenate input data set members in the output data set with no BEFORE or AFTER records. If the INDD and OUTDD LRECL do not have the same LRECL value, then the value of the OUTTD LRECL must be equal to or greater than the value of the INDD LRECL. If the value of the OUTDD LRECL is less than the value of the INDD LRECL, the records are truncated at the OUTDD LRECL. For example, when the INDD LRECL=128 and the OUTDD LRECL=80, records will be truncated to 80 bytes and the 48 bytes of each record will be lost in OUTDD.
An advantage of having an unloaded data set is that one or more members can be retrieved without reloading the entire library.
PROC SOURCE has several advantages over IBM's IEBPTPCH utility. With PROC SOURCE, you can perform the following tasks:
  • list members in alphabetical order
  • select members by specifying a wildcard or range
  • list the number of records in each member
  • list each member on a new page
  • produce an unloaded version of the library that can be ported to some other host systems.
The model-control-statements in the FIRST, LAST, BEFORE, and AFTER statements are usually either utility or job control statements, depending on the destination given by the OUTDD= option in the PROC SOURCE statement.

PROC SOURCE Statement

PROC SOURCE <options > ;
The following options are used in the PROC SOURCE statement:
DIRDD=file-specification
specifies either the fileref or physical filename of the output data set to which PROC SOURCE writes a sequential, unloaded form of the PDS directory. Each directory record is written into one 80-byte record. Records are left-aligned and padded on the right with blanks. If specified, the fileref must match the reference name that was used in the FILENAME statement, FILENAME function, JCL DD statement, or TSO ALLOCATE command that allocated the output data set.
INDD=file-specification
specifies the fileref or the physical filename of an input PDS that contains 80-byte fixed-length records. The fileref, if specified, must match the reference name that was specified in the FILENAME statement, FILENAME function, JCL DD statement, or TSO ALLOCATE command that allocated the input library. If the INDD= option is not specified, the default fileref is SOURCE.
If OUTDD is specified, then the RECFM of the INDD file must be either F or FB. The fileref cannot refer to a concatenation of data sets. If it does, then an error message is generated. If the member names in the INDD file are nonstandard, then specify FILEEXT=ASIS in an OPTIONS statement.
MAXIOERROR=n
specifies the maximum number of I/O errors to allow before terminating. Normally, PROC SOURCE detects, issues a warning message about, and then ignores I/O errors that occur while reading the library members. When the number of errors specified by MAXIOERROR= has occurred, however, PROC SOURCE assumes that the library is unreadable and stops. The default MAXIOERROR= value is 50.
NOALIAS
treats aliases as main member names. Therefore, PROC SOURCE does not generate
./ ALIAS
cards or alias BEFORE and AFTER cards.
NODATA
specifies that you do not want to read the members in the input PDS. In other words, PROC SOURCE produces only control statements and a list of the member names; it does not produce the contents of the members. The list of member names includes any aliases. NODATA is particularly useful when you want to process only the directory of a library.
NOPRINT
specifies that you do not want to generate the list of member names and record counts. (These listings are produced even when the PRINT option is not specified.) The NOPRINT option is ignored when PRINT is specified.
NOSUMMARY
specifies that you do not want to generate the member summary. The NOSUMMARY option is ignored when the NODATA, NOPRINT, or PRINT option is specified.
NOTSORTED
causes PROC SOURCE to process PDS members in the order in which they either appear (in SELECT statements) or remain (after EXCLUDE statements).
Normally, PROC SOURCE processes (that is, unloads, writes to the SAS log, and so on) the PDS members in alphabetical order by member name.
NULL
specifies that null members (PDS members that contain no records, just an immediate end-of-file) should be processed. Such members occasionally appear in source PDSs, but they are not normally unloaded because IEBUPDTE and most other PDS maintenance utilities do not create null members. If you are using a source library maintenance utility that can properly recognize and create a null member, then specify this option and provide the appropriate BEFORE (and possibly AFTER) statements.
OUTDD=file-specification
specifies the fileref, PDS or PDSE member name, or UNIX System Services filename of the output file to which PROC SOURCE writes the unloaded (sequential) form of the input PDS and any records that FIRST, LAST, BEFORE, and AFTER statements generate. If specified, the fileref must match the reference name used in the FILENAME statement, FILENAME function, JCL DD statement, or TSO ALLOCATE command that allocated the data set. This option cannot be used when the INDD file contains variable-length records.
PAGE
begins the listing of the contents of each member on a new page.
PRINT
lists the contents of the entire PDS. The PRINT option is ignored when NODATA is specified.

SELECT Statement

SELECT member-1 < . . . member-n > ;
When you use the SELECT statement, only the members that you specify are processed. You can specify more than one member in a SELECT statement, and you can use any number of SELECT statements.
Use a colon (:) to indicate that you want to select all members whose names begin with the characters that precede the colon. (See the second example below.)
You can include an alphabetic range of names in the SELECT statement by joining two names with a hyphen (-). The two hyphenated members and all members in between are processed. For example, if a library contains members called BROWN, GRAY, GREEN, RED, and YELLOW, and you want to process the first four members, use this SELECT statement:
select brown-red;
The colon (:) and hyphen (-) notation can be used together. For example, the following statement produces the same results as the previous SELECT statement:
select br:-gr: red;

EXCLUDE Statement

EXCLUDE member-1 < . . . member-n > ;
When you use the EXCLUDE statement, all members except the ones that you specify are processed. You can use any number of EXCLUDE statements.
Use a colon (:) to indicate that you want to exclude all members whose names begin with the characters that precede the colon.
You can include an alphabetic range of names in the EXCLUDE statement by joining two names with a hyphen. The two hyphenated members and all members in between are excluded from processing. (See the SELECT examples in the SELECT statement description.)
The colon and hyphen notation can be used together.
Sometimes it is convenient to use SELECT and EXCLUDE statements together. For example, you can use the colon or hyphen notation in a SELECT statement to select many members, then use the EXCLUDE statement to exclude a few of the selected members. Suppose there are 200 members called SMC1 through SMC200, and you want to copy all of them except SMC30 through SMC34. You could use these statements:
select smc:;
exclude smc30-smc34;
When you use both EXCLUDE and SELECT statements, the EXCLUDE statements should specify only members that are specified by the SELECT statements. However, excluding unspecified members has no effect other than to generate warning messages.

FIRST Statement

FIRST 'model-control-statement ';
The FIRST statement generates initial control statements that invoke a utility program or that are needed only once. The specified model-control-statement is reproduced, left-aligned, on a record that precedes all members in the unloaded data set. You can use any number of FIRST statements. One FIRST statement can specify one model control statement. Each model control statement generates a record.

LAST Statement

LAST 'model-control-statement ';
The LAST statement generates final control statements that terminate a utility program or that are needed only once. The specified model-control-statement is reproduced, left-aligned, on a record that follows all members in the unloaded data set. You can use any number of LAST statements. One LAST statement can specify one model control statement. Each model control statement generates a record.

BEFORE Statement

BEFORE 'model-control-statement' <options> ;
The BEFORE statement generates a utility control statement before each member. You can use any number of BEFORE statements. One BEFORE statement can specify one model control statement. Each model-control-statement that you specify is reproduced, left-aligned, on a record that precedes each member in the unloaded data set.
By default, PROC SOURCE generates control statements for the IBM IEBUPDTE utility program before each member of an unloaded data set. You can use the BEFORE and AFTER statements to override the default and generate control statements for other utility programs. To prevent PROC SOURCE from generating these statements, use the BEFORE statement with no parameters.
Options for the BEFORE and AFTER statements are the same. A list of these options follows the description of the AFTER statement.

AFTER Statement

AFTER 'model-control-statement' <options > ;
The AFTER statement generates a utility control statement after each member. You can use any number of AFTER statements. One AFTER statement can specify one model control statement. Each model-control-statement that you specify is reproduced, left-aligned, on a record that follows each member in the unloaded data set.
By default, PROC SOURCE generates control statements for the IBM IEBUPDTE utility program after each member of an unloaded data set. You can use the AFTER statement to override the default and generate control statements for other utility programs.
The following options are used in the BEFORE and AFTER statements:
ALIAS
tells SAS to produce a record containing the model-control-statement only for each defined alias. (The alias is placed into the record at the specified column, if any.)
column number
tells SAS to substitute the member name in records that are generated by BEFORE and AFTER statements in an 8-byte field beginning in this column. The beginning column can be any column from 1 to 73. Aliases, as well as main member names, are substituted. The name is left-aligned in the field unless the RIGHT option is specified, and it is padded on the right with blanks unless the NOBLANK option is specified.
NOBLANK
is meaningful only if column number is specified. When the member name is substituted in records that are generated by the BEFORE and AFTER statements, NOBLANK eliminates blanks between the end of the member and any text that follows. In the following record, a member name precedes the text; NOBLANK has not been specified:
name ,text text text
When NOBLANK is specified, the same record looks like this:
name,text text text
RIGHT
is meaningful only if column number is specified. When the member name is substituted in records that are generated by the BEFORE and AFTER statements, RIGHT causes the member name to be right-aligned in the specified field. By default, the name is left-aligned in an 8-byte field.

Output

PROC SOURCE writes the following information to the SAS log:
  • the contents of the entire PDS, if the PRINT option is specified
  • a listing of the member names in the PDS (unless you specify NOPRINT)
  • the number of records for each member (unless you specify NOPRINT or NODATA)
  • a summary of the attributes and contents of the PDS.
Even when PRINT is not specified, some records can still be written to the log. The signal NAME: or ENTRY: or AUTHOR: beginning in column 5 of a record in the library starts the listing; the signal END beginning in column 5 stops it. If you do not want SAS to list this subset of records, specify the NOSUMMARY option.

Examples

Example 1: Printing Selected Members from a PDS

The following example writes to the SAS log the contents of the member ORANGES4 from the PDS USERID.TASTE.TEST:
proc source indd='userid.taste.test' print;
   select oranges4;
run;
The following output displays the log:
Selecting a Member from a Source Statement Library
 19   proc source indd='userid.taste.test' print;
 20   select oranges4; run;
 ORANGES4
 data oranges;
    input variety $ flavor texture looks;
    total=flavor+texture+looks;
    datalines;
    navel 9 8 6
    temple 7 7 7
    valencia 8 9 9
    mandarin 5 7 8
    ;
 proc sort data=oranges;
    by descending total;
 proc print data=oranges;
    title 'Taste Test Result for Oranges';
 17 - RECORDS
 NOTE: INDD=SYS00158 data set is :
       Dsname=USERID.TASTE.TEST,
       Unit=3380,Volume=XXXXXX,Disp=SHR,Blksize=23055,
       Lrecl=259,Recfm=FB.
         3348      Members defined in source library.
            0      Aliases defined in source library.
            1      Members selected.
           17      Records read from source library.

Example 2: Building and Submitting a Job to Assemble Programs

The following PROC SOURCE program builds and submits a job to compile assembler programs. It writes the output directly to the internal reader so that the compile job can be executed.
filename out sysout=a pgm=intrdr lrecl=80 recfm=f;
proc source indd='userid.asm.src' nodata outdd=out;
   first '//COMPILE JOB (0,ROOM),''DUMMY'',';
   first '// NOTIFY=,REGION=4M,TYPRUN=HOLD';
   first '/*JOBPARM FETCH';
   last  '//';
   before '//XXXXXXXX EXEC ASMHCL,' 3;
   before '// MAC2=''XXX.MACLIB'' ';
   before '//SYSIN DD DISP=SHR,';
   before '// DSN=USERID.ASM.SOURCE(XXXXXXXX)' 26 NOBLANK;
run;
The output that is written to the internal reader is shown below. Note that this output shows only the statements that are generated by PROC SOURCE, before they are executed.
Building and Submitting a Job to Assemble Programs
 //COMPILE JOB (0,ROOM),'DUMMY',
 // NOTIFY=,REGION=4M,TYPRUN=HOLD
 /*JOBPARM FETCH
 //OUT1601  EXEC ASMHCL,
 // MAC2='XXX.MACLIB'
 //SYSIN DD DISP=SHR,
 // DSN=USERID.ASM.SRC(OUT1601)
 //OUT1602  EXEC ASMHCL,
 // MAC2='XXX.MACLIB'
 //SYSIN DD DISP=SHR,
 // DSN=USERID.ASM.SRC(OUT1602)
 //OUT1603  EXEC ASMHCL,
 // MAC2='XXX.MACLIB'
 //SYSIN DD DISP=SHR,
 // DSN=USERID.ASM.SRC(OUT1603)
 //

Example 3: Producing Directory Records

The following PROC SOURCE program produces directory records. The subsequent DATA step extracts the ISPF statistics, if any are present.
filename indd 'userid.sas.src' disp=shr;
filename out  '&temp';
/* Build directory records. */
proc source indd=indd nodata noprint dirdd=out;
/* Read directory records and extract   */
/*      ISPF statistics.                */
data test;
infile out;
file print header=h;
input member $8. ttr pib3. ind pib1. @;
datalen = 2*mod(ind,32);
if (datalen = 30)
then do;
  input ver pib1. mod pib1. blank pib2.
        ccreate pib1.
         create pd3.
        cchanged pib1.
         changed pd3. hh pk1.
        mm pk1. size pib2. init pib2.
        modl pib2. userid $8.;
  yyyydddc = (ccreate * 100000) + 1900000 + create;
  jcreate = datejul(yyyydddc);
  yyyydddx = (cchanged * 100000) + 1900000 + changed;
  jchange = datejul(yyyydddx);
/* Print the results. */
  put @4 member $8.
      @15 jcreate yymmdd10.
      @27 jchange yymmdd10.
      @39 hh z2. ':' mm z2.
      @48 userid;
end;
return;
h:
put @4 'NAME '
    @15 'CREATED'
    @27 'CHANGED'
    @39 'TIME'
    @48 ' ID ';
put;
return;
run;
The following output displays the results:
Producing Directory Records
                               The SAS System
   NAME       CREATED     CHANGED     TIME      ID
   OUT1601    2005-02-20  2005-02-20  10:50    USERID
   OUT1602    2005-02-20  2005-02-20  10:54    USERID
   OUT1603    2005-02-20  2005-02-20  10:59    USERID

Example 4: Generating Control Cards for IEBCOPY

This example first produces control statements for the IBM utility program, IEBCOPY. Then IEBCOPY executes, copying selected members.
//IEBPDS JOB (0,ROOM),'USERID',
//  NOTIFY=
/*JOBPARM FETCH
//   EXEC SAS
//IN DD DSN=XXX.SUBLIB,DISP=SHR
//OUT DD DSN=&&TEMP,SPACE=(CYL,(1,2)),
//       DISP=(,PASS),UNIT=DISK
//SYSIN DD *
   proc source indd=in outdd=out nodata  noprint;
   select hc:;
   select lm:;
   select sasextrn;
   first ' COPY INDD=IN,OUTDD=NEWPDS';
   before '  SELECT MEMBER=XXXXXXXX -----------'
      17;
   before '       S      M=XXXXXXXX ***ALIAS***'
      17 ALIAS;
//S1     EXEC PGM=IEBCOPY
//SYSPRINT DD SYSOUT=A
//IN     DD DSN=XXX.SUBLIB,DISP=SHR
//NEWPDS DD DSN=&&NEW,SPACE=(CYL,(20,10,20)),
//          UNIT=DISK
//SYSUT1 DD UNIT=DISK,SPACE=(CYL,(2,3))
//SYSUT2 DD UNIT=DISK,SPACE=(CYL,(2,3))
//SYSUT3 DD UNIT=DISK,SPACE=(CYL,(2,3))
//SYSIN  DD DSN=&&TEMP,DISP=(OLD,DELETE)
The first output shows what is written to the SAS log after PROC SOURCE is run. The second output shows the IEBCOPY output.
The following output displays the log:
Producing Control Statements for the IEBCOPY Utility
 1             proc source indd=in outdd=out nodata  noprint;
 2             select hc:;
 3             select lm:;
 4             select sasextrn;
 5             first ' COPY INDD=IN,OUTDD=NEWPDS';
 6             before '  SELECT MEMBER=XXXXXXXX -----------' 17;
 7             before '       S      M=XXXXXXXX ***ALIAS***' 17 ALIAS;
 NOTE: INDD=IN data set is :
       Dsname=USERID.DATASET,
       Unit=3380,Volume=XXXXXX,Disp=SHR,Blksize=6160,
       Lrecl=80,Recfm=FB.
 NOTE: OUTDD=OUT data set is :
       Dsname=SYS96052.T131013.RA000.IEBPDS.TEMP,
       Unit=3390,Volume=,Disp=NEW,Blksize=27920,
       Lrecl=80,Recfm=FB.
            9      Members defined in source library.
            0      Aliases defined in source library.
            6      Members selected.
            0      Records read from source library.
IEBCOPY Output: Selected Members Copied
                     IEBCOPY MESSAGES AND CONTROL STATEMENTS
  COPY INDD=IN,OUTDD=NEWPDS
   SELECT MEMBER=HCMEM1   -----------
   SELECT MEMBER=HCMEM2   -----------
   SELECT MEMBER=HCMEM3   -----------
   SELECT MEMBER=LMMEM1   -----------
   SELECT MEMBER=LMMEM2   -----------
   SELECT MEMBER=SASEXTRN -----------
          .
          .
          .
 IEB167I FOLLOWING MEMBER(S) COPIED FROM INPUT DATA SET REFERENCED BY IN
 IEB154I HCMEM1   HAS BEEN SUCCESSFULLY COPIED
 IEB154I HCMEM2   HAS BEEN SUCCESSFULLY COPIED
 IEB154I HCMEM3   HAS BEEN SUCCESSFULLY COPIED
 IEB154I LMMEM1   HAS BEEN SUCCESSFULLY COPIED
 IEB154I LMMEM2   HAS BEEN SUCCESSFULLY COPIED
 IEB154I SASEXTRN HAS BEEN SUCCESSFULLY COPIED
 IEB144I THERE ARE 239 UNUSED TRACKS IN OUTPUT DATA SET REFERENCED BY NEWPDS
 IEB149I THERE ARE 8 UNUSED DIRECTORY BLOCKS IN OUTPUT DIRECTORY
 IEB147I END OF JOB - 0 WAS HIGHEST SEVERITY CODE

See Also

IBM's DFSMSdfp Utilities