IBM Books

Net.Data Administration and Programming Guide for OS/400

Defining User-defined Functions

To define your own functions in the macro file, use a FUNCTION block or MACRO_FUNCTION block.

FUNCTION block
Defines a subroutine that is invoked from a Net.Data macro and that is either processed by language environment or calls an external program.

MACRO_FUNCTION block
Defines a subroutine that is invoked from a Net.Data macro and must be processed by Net.Data, rather than another language environment. The statements in the block must be Net.Data macro language source statements.

The MACRO_FUNCTION block is an alternative to the FUNCTION block that can improve performance. The MACRO_FUNCTION block is processed only by Net.Data and does not call a language environment. Details about these two constructs are in Net.Data Reference.

Syntax: Use the following syntax to define functions:

FUNCTION block:

%FUNCTION(type) function-name(usage parameter, ...) [RETURNS(return-var)] {
  executable-statements
  report-block
  ...
  report-block
 
  message-block
%}

MACRO_ FUNCTION block:

%MACRO_FUNCTION function-name(usage parameter, ...)  {
  executable-statements
  report-block
  ...
  report-block
   %}

Where:

type
Identifies a language environment that is configured in the initialization file. The language environment invokes a specific language processor (which processes the executable statements) and provides a standard interface between Net.Data and the language processor.

Several default language environments are provided with Net.Data.

function-name
Specifies the name of the FUNCTION or MACRO_FUNCTION block. Execute the FUNCTION block or MACRO_FUNCTION block with a function call elsewhere in the macro file. The function call references the function-name, preceded by an at (@) sign. See Calling Functions for details.

You can define multiple FUNCTION or MACRO_FUNCTION blocks with the same name so that they are processed at the same time. Each of the blocks must all have identical parameter lists. When Net.Data calls the function, all FUNCTION blocks with the same name or MACRO_FUNCTION blocks with the same name are executed in the order they are defined in the Net.Data macro.

usage
Specifies whether a parameter is an input (IN) parameter, an output (OUT) parameter, or both types (INOUT). This designation indicates whether the parameter is passed into or received back from the FUNCTION block, MACRO_FUNCTION block, or both. The usage type applies to all of the subsequent parameters in the parameter list until changed by another usage type. The default type is IN.

parameter
The name of a variable with local scope that is replaced with the value of a corresponding argument specified on a function call. Parameter references, for example $(parm1), in the executable statements or REPORT block are replaced with the actual value of the parameter. In addition, parameters are passed to the language environment and are accessible to the executable statements using the natural syntax of that language or as environment variables. Parameter variable references are not valid outside the FUNCTION block or MACRO_FUNCTION block.

return-var
Specify this parameter after the RETURNS keyword to identify a special OUT parameter. The value of the return variable is assigned to the function call and replaces the function call in the Net.Data macro processing. If you do not specify the RETURNS clause, the value of the function call is:

executable-statements
The set of language statements that is passed to the specified language environment for processing after the variables are substituted and the functions are processed. executable-statements can contain Net.Data variable references and Net.Data function calls. Prior to passing the executable statements to the language environment, Net.Data replaces these variable references or function calls with the actual value.

For FUNCTION blocks, Net.Data replaces all variable references with the variable values, executes all function calls, and replaces the function calls with their resulting values before the executable statements are passed to the language environment. Each language environment processes the statements differently. For more information about specifying executable statements or calling executable programs, see Executable Variables.

For MACRO_FUNCTION blocks, the executable statements are a combination of HTML statements and Net.Data macro language constructs. In this case, no language environment is involved because Net.Data acts as the language processor and evaluates and runs the executable statements.

report-block
Defines one or more REPORT blocks for handling the output of the FUNCTION block. See Report Blocks.

message-block
Defines the MESSAGE block, which handles any messages returned by the FUNCTION block. See Message Blocks.

Define functions at the outermost Net.Data macro layer and before they are called in the Net.Data macro.

Using Special Characters in Functions

When characters that match Net.Data language constructs syntax are used in the language statements section of a function block as part of syntactically valid embedded program code (such as REXX or Perl), they can be misinterpreted as Net.Data language constructs, causing errors or unpredictable results in a macro.

For example, a Perl function might use the COMMENT block delimiter characters, %{. When the macro is run, the %{ characters are interpreted as the beginning of a COMMENT block. Net.Data then looks for the end of the COMMENT block, which it thinks it finds when it reads the end of the function block. Net.Data then proceeds to look for the end of the function block, and when it can't be found, issues an error.

Use one of the following methods to use COMMENT block delimiter characters, or any other Net.Data special characters as part of your embedded program code, without having them interpreted by Net.Data as special characters:

For example, the following Perl function contains characters representing a COMMENT block delimiter, %{, as part of its Perl language statements:

%function(DTW_PERL) func() {
  ...           
  for $num_words (sort bynumber keys %{ $Rtitles{$num} }) {
     &make_links($Rtitles{$num}{$num_words});          
  }            
  ...         
 %}   

To ensure that Net.Data interprets the %{ characters as Perl source code rather than as a Net.Data COMMENT block delimiter, rewrite the function in either of the following ways:

Message Blocks

The MESSAGE block lets you determine how to proceed after a function call based on the success or failure of the function call, and lets you display information to the caller of the function. Net.Data uses the following message block process:

  1. Net.Data sets RETURN_CODE, a language environment variable, for each function call to a FUNCTION block. RETURN_CODE is not set on a function call to a MACRO_FUNCTION block.

  2. When a language environment passes a return code value back to Net.Data, Net.Data sets the value of RETURN_CODE to the return code value.

  3. When the function call completes, the MESSAGE block uses the value of RETURN_CODE to determine how to proceed.

A MESSAGE block consists of a series of message statements, each of which specifies a return code value, message text, and an action to take. The syntax of a MESSAGE block is shown in the language constructs chapter of Net.Data Reference.

A MESSAGE block can have a global or a local scope. If the MESSAGE block is defined in a FUNCTION block, its scope is local to that FUNCTION block. If it is specified at the outermost macro layer, the MESSAGE block has global scope and is active for all function calls executed in the Net.Data macro. If you define more than one global MESSAGE block, the last one defined is active.

Net.Data uses these rules to process the value of the RETURN_CODE variable from a function call:

  1. Check local MESSAGE block for an exact match; exit or continue as specified.

  2. If RETURN_CODE is not 0, check local MESSAGE block for +default or -default; depending on the sign of RETURN_CODE, exit or continue as specified.

  3. If RETURN_CODE is not 0, check local MESSAGE block for default; exit or continue as specified.

  4. Check global MESSAGE block for an exact match; exit or continue as specified.

  5. If RETURN_CODE is not 0, check global MESSAGE block for +default or -default; depending on the sign of RETURN_CODE, exit or continue as specified.

  6. If RETURN_CODE is not 0, check global MESSAGE block for default; exit or continue as specified.

  7. If RETURN_CODE is not 0, issue Net.Data internal default message and exit.

The following example shows part of a Net.Data macro with a global MESSAGE block and a MESSAGE block for a function.

%{ global message block %}
%MESSAGE {
   -100     : "Return code -100 message"   : exit
    100     : "Return code 100 message"    : continue
   +default : {
This is a long message that spans more
than one line. You can use HTML tags, including
links and forms, in this message. %}   : continue  
%}
 
%{ local message block inside a FUNCTION block %}
%FUNCTION(DTW_REXX) my_function() {
  %EXEC { my_command.mbr %}
  %MESSAGE {
     -100     : "Return code -100 message"   : exit
      100     : "Return code 100 message"    : continue
     -default : {
This is a long message that spans more
than one line. You can use HTML tags, including
links and forms, in this message. %}   : exit  
  %}

If my_function() returns with a RETURN_CODE value of 50, Net.Data processes the error in this order:

  1. Check for an exact match in the local MESSAGE block.

  2. Check for +default in the local MESSAGE block.

  3. Check for default in the local MESSAGE block.

  4. Check for an exact match in the global MESSAGE block.

  5. Check for +default in the global MESSAGE block.

When Net.Data finds a match, it sends the message text to the Web browser and checks the requested action.

When you specify continue, Net.Data continues to process the Net.Data macro after printing the message text. For example, if a macro calls my_functions() five times and error 100 is found during processing with the MESSAGE block in the example, output from a program can look like this:

.
.
.
11 May 1997                  $245.45
13 May 1997                  $623.23
19 May 1997                  $ 83.02
return code 100 message
22 May 1997                  $ 42.67
 
Total:                       $994.37


[ Top of Page | Previous Page | Next Page | Table of Contents | Index ]