Sample code walk-through

The sample code snippets illustrate how the output from preprocessors can be linked by using the Developer for z/OS® error feedback mechanism and multiple preprocessor support.

Code snippets

This example makes reference to the following code snippets:
COBOL segment
The following COBOL program segment is from the DEMODATA source code. This program was preprocessed and compiled. The lines that begin with FRAGMENT are at line 48, 55, and 74. The misspelled display statement "DSPLAY" is at line 54. The member NOTTHERE is intentionally missing from the FRAGMNT concatenation so that the preprocessor flags an error at that line.

       Procedure Division.
FRAGMENT HELLO;
           Initialize Program-pass-fields
                      Program-other-fields
                      Program-flags.
           copy  MYINC6.
           Perform until Loop-done
               Dsplay " "
FRAGMENT NOTTHERE;
               Display "Enter a name or Q to quit:"
               Move Spaces to Input-name
               Accept Input-name
               IF Input-name = Spaces
                 Move "Q" to Input-name
               End-IF

               Move 1 to Char-count
               Inspect Input-name Tallying Char-count For Leading Spaces
               Move Input-name(Char-count: 30 - Char-count) to Temp-name

               If function upper-case (Temp-name) = "Q"
                     or Temp-name = Spaces
                  Set Loop-done to true
               Else
                  Call 'PrintApp' using Program-pass-fields
               End-if
           End-perform.
FRAGMENT BYE;
           Goback.
Fragment MEL.A001.DATA.FRAGMENT(BYE)
***************************************************
*BYE
***************************************************
Fragment MEL.A001.DATA.FRAGMENT(HELLO)
 **************************************************
 *HELLO
 ***************************************************

Preprocessor output

The code sample at the end of this section shows the output XML file of the preprocessor. The preprocessor XML file contains a set of values for the source that is read in <FILEREFERENCETABLE>. This XML file also has the messages that the preprocessor generated between the <MESSAGE> tag. The <OUTFILEREFERENCETABLE> values describe the output files that the preprocessor created for consumption by the compiler. The <STATEMENTTABLE> values describe each output line that the preprocessor created. Each of the ordered quads describes a single output line in the following way:
(oln,ofn,iln,ifn)
oln
Output line number:the line number in the expanded source file.
ofn
Output file number. A preprocessor often emits only a single output file, but it is possible for a preprocessor to write out copy members to be fed to the compiler.
iln
Input line number: the line number from the input file that was processed to cause the output line to be written.
ifn
Input file number: the file number of the input file that is being read. It contains the line of input that is described by iln.
From the preprocessor XML file, the following information can be determined:
  • The program that was preprocessed was MEL.A001.DATA.COBOL(DEMODATA).
  • The files that are used during the preprocess were MEL.A001.DATA.COBOL(DEMODATA), MEL.A001.DATA.FRAGMENT(HELLO), and MEL.A001.DATA.FRAGMENT(BYE).
  • The preprocessor produced a single output file, SYS09225.T113157.RA000.MEL1.TEMPFILE.H01.
  • The preprocessor error DD:FRAGMNT(NOTTHERE) not found occurred on line 55 of the input source file 1, MEL.A001.DATA.COBOL(DEMODATA).
  • The statement table entry (48,1,1,2) indicates that line 48 of the output file 1, SYS09225.T113157.RA000.MEL1.TEMPFILE.H01, was written as a result of reading line number 1 of input file 2, MEL.A001.DATA.FRAGMENT(HELLO).
Figure 1. Output XML file

<?xml version="1.0" standalone="yes"?>
<BUILD>
<PACKAGE>
<FILEREFERENCETABLE>
<FILECOUNT>3</FILECOUNT>
<FILE>
<FILENUMBER>1</FILENUMBER>
<FILENAME>
MEL.A001.DATA.COBOL(DEMODATA)
</FILENAME>
</FILE>
<FILE>
<FILENUMBER>2</FILENUMBER>
<FILENAME>
MEL.A001.DATA.FRAGMENT(HELLO)
</FILENAME>
</FILE>
<FILE>
<FILENUMBER>3</FILENUMBER>
<FILENAME>
MEL.A001.DATA.FRAGMENT(BYE)
</FILENAME>
</FILE>
</FILEREFERENCETABLE>
<MESSAGE>
<MSGNUMBER>DEMO9999E</MSGNUMBER>
<MSGLINE>55</MSGLINE>
<MSGFILE>1</MSGFILE>
<MSGTEXT>
DD:FRAGMNT(NOTTHERE) not found
</MSGTEXT>
</MESSAGE>
<OUTFILEREFERENCETABLE>
<OUTFILECOUNT>
1
</OUTFILECOUNT>
<OUTFILE>
<OUTFILENUMBER>
1
</OUTFILENUMBER>
<OUTFILENAME>
SYS09225.T113157.RA000.MEL1.TEMPFILE.H01
</OUTFILENAME>
</OUTFILE>
</OUTFILEREFERENCETABLE>
<STATEMENTTABLE>
(1,1,1,1);(2,1,2,1);(3,1,3,1);(4,1,4,1);(5,1,5,1);(6,1,6,1);
(7,1,7,1);(8,1,8,1);(9,1,9,1);(10,1,10,1);(11,1,11,1);(12,1,12,1);
(13,1,13,1);(14,1,14,1);(15,1,15,1);(16,1,16,1);(17,1,17,1);(18,1,18,1);
(19,1,19,1);(20,1,20,1);(21,1,21,1);(22,1,22,1);(23,1,23,1);(24,1,24,1);
(25,1,25,1);(26,1,26,1);(27,1,27,1);(28,1,28,1);(29,1,29,1);(30,1,30,1);
(31,1,31,1);(32,1,32,1);(33,1,33,1);(34,1,34,1);(35,1,35,1);(36,1,36,1);
(37,1,37,1);(38,1,38,1);(39,1,39,1);(40,1,40,1);(41,1,41,1);(42,1,42,1);
(43,1,43,1);(44,1,44,1);(45,1,45,1);(46,1,46,1);(47,1,47,1);(48,1,1,2);
(49,1,2,2);(50,1,3,2);(51,1,49,1);(52,1,50,1);(53,1,51,1);(54,1,52,1);
(55,1,53,1);(56,1,54,1);(57,1,55,1);(58,1,56,1);(59,1,57,1);(60,1,58,1);
(61,1,59,1);(62,1,60,1);(63,1,61,1);(64,1,62,1);(65,1,63,1);(66,1,64,1);
(67,1,65,1);(68,1,66,1);(69,1,67,1);(70,1,68,1);(71,1,69,1);(72,1,70,1);
(73,1,71,1);(74,1,72,1);(75,1,73,1);(76,1,1,3);(77,1,2,3);(78,1,3,3);
(79,1,75,1);(80,1,76,1);(81,1,77,1);(82,1,78,1);(83,1,79,1);
</STATEMENTTABLE>
</PACKAGE>
</BUILD>

Compiler output

The code sample at the end of this section shows the output XML file of the compiler. The compiler XML file is generated by the compiler when the appropriate compiler options are used. These compiler options are inserted automatically when a syntax check, build, or show dependencies operation is performed. The compiler XML file has a slightly different format than the preprocessor XML file. User-written preprocessors and builders must follow the preprocessor XML file format.

The compiler XML file shows that there is a compilation error: &quot;DSPLAY&quot; was invalid. Skipped to the next verb, period or procedure-name definition. This error pertains to line 56 of input file 1, SYS09225.T113157.RA000.MEL1.TEMPFILE.H01. The compiler reports only errors against the file that was fed to it. The compiler does not know about MEL.A001.DATA.COBOL(DEMODATA). It knows about input file number 1, SYS09225.T113157.RA000.MEL1.TEMPFILE.H01. From the naming convention, and from the JCL procedure that was used to invoke the preprocessor and compiler, you can determine that SYS09225.T113157.RA000.MEL1.TEMPFILE.H01 is a temporary file that is deleted once the job is complete.

Combining the two XML files, you can find the correct line of source to map the compilation error back to:
  • The compilation error was reported against file number 1.
  • The compiler FILEREFERENCETABLE indicates that file 1 is SYS09225.T113157.RA000.MEL1.TEMPFILE.H01.
  • From the preprocessor XML file, you can find the file SYS09225.T113157.RA000.MEL1.TEMPFILE.H01 in the OUTFILEREFERENCETABLE. It has an OUTFILENUMBER of 1. So, the output file number is 1, and the output line number is 56.
Expressed another way:
oln = 56
ofn = 1
From the STATEMENTTABLE, you need to find iln, and ifn, where the ordered quad is (56,1,iln,ifn). From this information, you can determine the following values:
iln = 54
ifn = 1
In summary, the compiler reported an error at line 56 in file SYS09225.T113157.RA000.MEL1.TEMPFILE.H01. This line corresponds to line 54 in MEL.A001.DATA.COBOL(DEMODATA). The compilation error is reported against line 54 of file MEL.A001.DATA.COBOL(DEMODATA).

<?xml version="1.0" standalone="yes"?>
<!-- ************************************************************************************ -->
<BUILD>
<PACKAGE>
<FILEREFERENCETABLE>
<FILECOUNT>2</FILECOUNT>
<FILE>
<FILENUMBER>1</FILENUMBER>
<FILENAME>SYS09225.T113157.RA000.MEL1.TEMPFILE.H01</FILENAME>
</FILE>
<FILE>
<FILENUMBER>2</FILENUMBER>
<FILENAME>MEL.A001.COPYLIB1.COPYLIB(MYINC6)</FILENAME>
</FILE>
</FILEREFERENCETABLE>
<MESSAGE>
<MSGNUMBER>IGYPS2112-E</MSGNUMBER>
<MSGLINE>55</MSGLINE>
<MSGFILE>1</MSGFILE>
<MSGTEXT>
The "PERFORM" statement did not have a matching scope terminator.  A scope terminator was assumed on line 82.  The execution results may not be correct.
</MSGTEXT>
</MESSAGE>
<MESSAGE>
<MSGNUMBER>IGYPS2072-S</MSGNUMBER>
<MSGLINE>56</MSGLINE>
<MSGFILE>1</MSGFILE>
<MSGTEXT>
"DSPLAY" was invalid.  Skipped to the next verb, period or procedure-name definition.
</MSGTEXT>
</MESSAGE>
<MESSAGE>
<MSGNUMBER>IGYPS0002-E</MSGNUMBER>
<MSGLINE>57</MSGLINE>
<MSGFILE>1</MSGFILE>
<MSGTEXT>
A character other than "*", "D", "/" or "-" was found in column 7.  A blank was assumed.
</MSGTEXT>
</MESSAGE>
<MESSAGE>
<MSGNUMBER>IGYPS2008-E</MSGNUMBER>
<MSGLINE>57</MSGLINE>
<MSGFILE>1</MSGFILE>
<MSGTEXT>
A period was required before procedure-name "T".  A period was assumed before "T".
</MSGTEXT>
</MESSAGE>
<MESSAGE>
<MSGNUMBER>IGYPS2145-E</MSGNUMBER>
<MSGLINE>57</MSGLINE>
<MSGFILE>1</MSGFILE>
<MSGTEXT>
A period was required.  A period was assumed before "NOTTHERE".
</MSGTEXT>
</MESSAGE>
<MESSAGE>
<MSGNUMBER>IGYPS2015-I</MSGNUMBER>
<MSGLINE>57</MSGLINE>
<MSGFILE>1</MSGFILE>
<MSGTEXT>
The paragraph or section prior to paragraph or section "NOTTHERE" did not contain any statements.
</MSGTEXT>
</MESSAGE>
<MESSAGE>
<MSGNUMBER>IGYPS2145-E</MSGNUMBER>
<MSGLINE>58</MSGLINE>
<MSGFILE>1</MSGFILE>
<MSGTEXT>
A period was required.  A period was assumed before "DISPLAY".
</MSGTEXT>
</MESSAGE>
<MESSAGE>
<MSGNUMBER>IGYPS2113-E</MSGNUMBER>
<MSGLINE>75</MSGLINE>
<MSGFILE>1</MSGFILE>
<MSGTEXT>
The explicit scope terminator "END-PERFORM" was found without a matching verb.  The scope terminator was discarded.
</MSGTEXT>
</MESSAGE>
</PACKAGE>
</BUILD>