HP 3000 Manuals

Writing a Preprocessor [ Micro Focus COBOL System Reference, Volume 1 ] MPE/iX 5.0 Documentation


Micro Focus COBOL System Reference, Volume 1

Writing a Preprocessor 

This section explains how to write an integrated preprocessorand
describes the interface used to pass information between a preprocessor
and the Compiler.

Although a preprocessor could be written in a language other than COBOL,
the following description assumes that it is written in COBOL.

The integrated preprocessor interface works on the simple concept that
preprocessing is a form of editing.  The preprocessor marks each line of
the source code as original, inserted (that is new lines) or unchanged.
When compiling a COBOL program, the Compiler calls the preprocessor
instead of directly reading the source file and receives the code line by
line from the preprocessor.

The operation of Animator depends upon a mapping of each line of object
code on to each line of source code.  The marking of source lines
described above allows this mapping to be valid even though the object
code does not match the source code.

Definition of the Interface 

This section describes the interfacebetween the Compiler and a
preprocessor.

Preprocessor Parameters.   

Three parameters are passed across the interface:  mode-flag, buffer, and
response.mode-flag is used to pass control information, buffer is used
for text information (source lines and file-names) and response is used
to indicate the type of source line in the buffer.

These parameters are defined as follows:

       01  mode-flag  pic 9(2) comp-x.
      01  buffer pic x(80).
      01  response.
          03  response-status  pic 9(2) comp-x.
          03  response-code-1 pic 9(4) comp-x.
          03  filler redefines response-code-1.
              05  filler  pic x.
              05  resp-main  pic 9(2) comp-x.
          03 response-code-2  pic 9(4) comp-x.
          03 filler redefines response-code-2.
              05 filler pic x.
              05 resp-more  pic 9(2) comp-x.


NOTE See your Language Reference for details on the data type COMP-X.
The Initial Call. The initial call is made to the preprocessor at the point where the Compiler would normally open the source file. The mode-flag parameter is set to 0 and the name of the source file (including path information) is placed in buffer. The preprocessor should open the file and return zero in response-status to indicate success; any other value indicates a failure. The remainder of the response parameter is not used. The operating system command line contains any directives to the preprocessor, terminated by the character x"7F". These directives are specified in the Compiler command line, directives files or $SET statements and follow the PREPROCESS directive itself. See the section Invoking a Preprocessor, for further information. For details on how to read the operating system command line, see COMMAND-LINE in your Language Reference. The directives are used to pass information from the user to the integrated preprocessor and are defined by the designer of the integrated preprocessor. Subsequent Calls. Subsequent calls request a line of source code until the preprocessor indicates that the last line has been reached. In these calls, the Compiler sets mode-flag to 1. The preprocessor returns a line of source code in buffer and information about it in resp-main and resp-more. If there is an error, response-status should be set to a nonzero value (the remaining fields may be left undefined). The first byte of response-code-1 and response-code-2 are reserved for future use and must always be set to zero on return. The simplest way to achieve this is to set response-code-1 and response-code-2 to zero before setting resp-main and resp-more. If you wish to modify your code, you should note that the original source code lines should always be passed back before their replacement line(s). Marking Source Lines. Source lines are marked as unchanged, old (to be treated as commented out) or new. Special information is also required for source lines containing COPY (or equivalent verb) statements. The information to mark these lines is placed in resp-main as follows: Value Description ------------------------------------------------------- 0 The source file has been completely processed and is the end of input. buffer is undefined. 1 buffer contains a new line added by the preprocessor which was not in the original source code. 2 buffer contains a line in the original source code which is either being commented out or will be replaced by the preprocessor. 3 buffer contains a line in the original source code which contains the start of a COPY statement that is about to be expanded by the preprocessor. 4 buffer contains a line in the original source code which contains the continuation of a COPY statement. 5 buffer contains a warning message inserted by the preprocessor. This must have the format of a comment line (that is, the value "*" in the seventh byte). 6 An unrecoverable error has occurred; this forces the Compiler to abort and, in certain Micro Focus add-on products, to enter the COBOL Editor. In such a case, a message of up to 70 characters may be written to the command line and this will be displayed on the bottom line of the editor. 7 An error has occurred; this forces the Compiler to increment its error count. All error classes may be specified by using resp-more (see the section Generating Error Messages below). The contents of buffer are ignored. 11 buffer contains a new line added by the preprocessor which contains the start of a COPY statement that is about to be expanded by the preprocessor. It is used when the COPY statement is not unique on a line. See below for an example of when this might be used. Table 17-0. (cont.) Value Description 12 buffer contains a new line added by the preprocessor which contains the continuation of a COPY statement. 32 buffer contains a line from the original source code which has not been modified by the preprocessor. 128 The end of a COPY-file has been reached. buffer must be empty. resp-more is used to specify additional information when resp-main has a value of 1, 3, 6, 7 or 11. When resp-main contains the value 1, resp-more is used to indicate the position in the original source of the replaced non-COBOL verb as follows. Value Description ------------------------------------------------------- 0 No verb replacement is taking place. nn'' is the number of the column containing the first character of the non-COBOL verb being replaced by the current line. The line(s) containing the non-COBOL verb would have previously been marked by returning the value of 2 in resp-main; if there were more than one line, the verb is assumed to be on the first of them. For example, if the original source contains: exec abc do something useful end-exec and these three lines are replaced by: call abc_something_useful then the value of nn gives the position of the EXEC statement. When resp-main contains the value 3 or 11, resp-more is used to indicate where the word COPY (or equivalent verb) begins, and contains nn, the column number containing the first letter of the verb. When resp-main contains the value 6 or 7, resp-more is used to indicate how the error should be handled. See the section Generating Error Messages later in this chapter for more information. Source Modification. A number of COBOL commands exist to amend a source file. The following statements are not supported by the Compiler when a preprocessor is active and must be handled by the preprocessor: * REPLACE (ANSI'85 verb) * BASIS mechanism COPY-files COPY-files can be expanded by the preprocessor or the Compiler. The preprocessor need only expand COPY-files if the source code they contain has code that needs preprocessing. In all other cases, the Compiler should be used to expand COPY-files. The Compiler will expand COPY statements if they are passed back as either unchanged or amended lines by the preprocessor. The following are supported: * Simple COPY statement * COPY...REPLACING statements * COPY copy-file-name OF/IN library-name * COPY statements spread over several lines * Nested COPY statements * ++INCLUDE * -INC If the Compiler is to expand the COPY-file, the code passed to the Compiler containing the COPY statement must be valid COBOL. This means that if the unpreprocessed source contains a non-COBOL word intended to be treated as the word COPY, then the actual COBOL word COPY must be substituted in the source before passing to the Compiler. If the preprocessor intends to expand the COPY-file itself, then this restriction does not apply. resp-main and resp-more must be used as described above if the preprocessor is handling COPY expansion itself. A value of 11 would be required in resp-main in the following type of situation where the COPY statement is not unique on a line: The source contains: 01 ITEM-A. COPY "CPY-FIL.CPY". This is first returned with resp-main set to 2 to indicate that this is a line that is about to be replaced. On the next call, the preprocessor returns: 01 ITEM-A. with resp-main set to 1 to indicate that this is a replacement line. On the next call, the preprocessor returns: COPY "COPY-FIL.CPY". This time, resp-main is set to 11 to indicate this is a replacement line containing the COPY statement alone. resp-more is set to 20, the position of the word COPY on the original source line. Generating Error Messages If the preprocessor encounters an errorwhen processing the source code, it can communicate this to the Compiler so that the error is treated as a syntax error. There are two ways to do this: * Set resp-main to the value 5 and place a comment line in buffer; the comment will be inserted in the list file. * Set resp-main to the value 6; the Compiler will terminate. The value in resp-more specifies the column number in which the error was found. It is used when positioning the cursor on return to the Editor with certain Micro Focus add-on products. It is also possible to force the Compiler to increment its internal error counts in conjunction with one of the two operations described above. This is done by setting resp-main to the value 7 and specifying which error count is to be increased in resp-more. Possible values for resp-more are: Value Severity --------------------------------------------------- 1 Unrecoverable error 2 Severe error 3 Error 4 Warning 5 Informationa l 6 Flag count Increasing the Unrecoverable error count will cause the Compiler to abort immediately. The contents of buffer are ignored. It is the responsibility of the preprocessor to output error messages to the user before forcing the Compiler to either abort or increment the error counts. This should not be confused with the message that can be inserted in the list file which is for informational purposes only. The sort of message which might be displayed by the preprocessor explains to the user what is happening or requests a choice, for example, the message "Continue Checking Y/N ?". Multiple Preprocessors Several preprocessors may be active simultaneously on the same source program. They are arranged in a stack so that the Compiler calls the top preprocessor in the stack, this preprocessor calls the next preprocessor and so on to the preprocessor at the bottom of the stack which actually reads the source code. Each line of source is then passed through every preprocessor in turn until it reaches the top of the stack and is passed to the Compiler. In order for this to work, the preprocessor must obey some additional rules. Writing a Stackable Preprocessor A stackable preprocessor is identical to one which is not stackable except that it contains extra code to invoke another preprocessor if this is necessary. As described above, the Compiler writes preprocessor directives to the command line when it makes the initial call to a preprocessor. The preprocessor reads this command line and, if it finds a PREPROCESS directive, invokes the preprocessor named in the PREPROCESS directive. It also passes any parameters following the directive to the invoked preprocessor by writing these in turn to the command line. As Preprocessor directives are terminated by the ENDP directive or the end of the line, multiple PREPROCESS directives must all appear on the same line in a directives file. The interface between two preprocessors is identical to that between the Compiler and preprocessor specified above, thus it is possible to use a stackable preprocessor in both stacked and unstacked situations. A preprocessor which has not been designed to be stackable may be stacked at the end of the stack where it is directly reading the source code. In most cases, preprocessors act on discrete sets of syntax and all produce valid COBOL syntax, so it is unlikely that more than one preprocessor will want to process a particular source line. However, it is possible that preprocessors in a stack represent language levels so that a source line is edited several times by the different preprocessors on its route through the stack to the Compiler. In this case, care must be taken to read the information in the response field so that the relationship between the source code and the code that finally reaches the Compiler is maintained. The order in which the stacking takes place should also be chosen carefully if code altered by one preprocessor is also to be successfully modified by a second preprocessor.


MPE/iX 5.0 Documentation