PPWIZARD is a free preprocessor for HTML, REXX, Visual Basic or any text files.
[Bottom][Contents][Search][Prev]: #define[+|?][Next]: #DependsOn
\ -> Commands -> #DefineRexx[+]

#DefineRexx[+]

This command provides a simple way to define multi line/statement rexx code without requiring line continuation characters. This is useful for:

  1. Defining rexx code to be executed at some later stage (if not immediately).

  2. Defining a fragment of rexx code which may act much like a subroutine.

  3. Defining rexx code (or fragments) for generating into the rexx program you are creating (/rexx).

You use this command to define the start and end of a block of rexx code and anything in between is either rexx code or a ppwizard command.

The fact that ppwizard commands are interpreted while the block is being processed allows you to use useful commands such as #include or #if to selectively include or exclude parts of the rexx code (at definition time). To make decisions at runtime you must use the rexx "if" statement and not the ppwizard #if command!

Each line of rexx goes through the following processing:

  1. The line goes through all normal PPWIZARD processing except symbol substitution. This means for example that line continuation occurs so that a "line" that this command sees can actually be made up of many source lines.

  2. All leading and trailing whitespace is removed.

  3. A trailing rexx comment if it exists is removed.

  4. A trailing ';' is removed if it exists.

  5. If the line starts with "$trace" (any case) then if the command:

    Please see the #DefineRexx Tracing section for more information and for details on restrictions. If debug is off then this command will be ignored.

  6. If the line starts with "$BreakPoint" (any case) then processing will pause whether or not you are in debug mode.

  7. Unless you specify otherwise the line is packed and you should be aware of some of the restrictions involved (described below). Packing reduces the chance that the rexx interpreter you are using will reject the code due to clause or line length restrictions. The packing also means that you can format the code to be easier to read (since you aren't worried about the extra spacing etc).

  8. The line is added to any previously collected (separated with "<?xRexxEos>"). This seperator string is automatically handled if the rexx is executed under ppwizard control. If you generate the rexx code (into the output rexx program) then the default is that it is converted to a newline.

    Note that the end of each rexx line is expected to be the end of a rexx statement so if a rexx statement spans multiple lines you will still need to use line continuation on these lines.

    Note that if you combine multiple macros generated this way you must separate them with ';' as this command does not terminate the last statement.

At the end of the block the complete rexx code may have symbols substituted depending on how the DefineMacroReplace option is set.

Note that the last line/statement of the block will not be terminated with a semicolon, if you wish to combine blocks you will need to take this into account.

Note that rexx does not support the definition of functions within the code to be executed, please see the "Rexx Subroutines in PPWIZARD" section for ways around this limitation.

If PPWIZARD detects a syntax error in the rexx code (assuming correct configuration) it will be able to pin point the line number and statement that failed. This is very much worth your while configuring correctly!.

Syntax

[WhiteSpace]#DefineRexx[+]  [["]Variable["] ["]NOPACK["] "TRACE:OFF" "TRACE:ON" "TRACE:AUTO"]

If the command was "#DefineRexx+" then if a redefine of a variable occurs then this is considered to be OK and no warnings are generated.

If the Variable parameter is supplied it defines the name of a #define to be generated with the following lines as their contents. If no parameters are supplied the rexx code block is completed.

If the Variable parameter is given as "" (empty) then the rexx code is immediately executed and not saved. When code is executed immediately then any macro parameters are always replaced.

The TRACE:? options override the default set with the PpwTrace option.

The default situation is that rexx code is packed, the optional NOPACK keyword allows you to prevent this. Some rexx interpreters have trouble with legal rexx code when excess spaces are removed! Rather than completely disabling all packing you can also make use of the AllowPack option to selectively prevent the packing of certain lines.

Use Within Macros

The line by line processing described above can not occur when the rexx code is being defined within a macro (it sees one line).

I recommend that you do not use this command within a macro definition unless this command is used for the immediate execution the rexx code. If defining a macro containing rexx code then there is no reason why it need be imbedded.

You need to end each line with either a ";" or space as appropriate, consider the following:

#( ''
   #define EnclosingMacro
   ...

   #DefineRexx 'Something'
       Var1 = ''
       if (Test) then
       do
          fred = 1
       end
   #DefineRexx
   ...
#)

The rexx code actually ends up looking like:

Var1 = ''if (Test) thendofred = 1end

It was the "#(" command which did this, not the "#DefineRexx" command (it only sees the one "line"!).

Now to fix it you could ensure a ";" was on each line, in the following I use a space also (purely for example):

#( ''
   #define EnclosingMacro
   ...

   #DefineRexx 'Something'
       Var1 = '';
       if (Test) then        \
       do;
          fred = 1;
       end;
   #DefineRexx
   ...
#)

Now the line will look like (ignoring any packing that "#DefineRexx" might do):

Var1 = '';if (Test) then do;fred = 1;end

Much better! This is valid rexx and so should work!

Debugging

You can turn on rexx's inbuilt tracing by ensuring that you have set the "REXXTRACE" DebugLevel and setting the "REXXTRACE" macro to an appropriate value. This tracing does not work well on regina (excellent on OS/2 though).

To simply test a few spots for correct function typically you would use standard rexx "say" commands like:

say 'About to do stuff, Line = "' || TheLine || '"';

A better method to do the same thing is to use the "$trace" facility, the command would now look like:

$trace About to do stuff

The above "$trace" would display the string and dump the contents of all known variables. It would also be possible to set breakpoints and the values at the end of the execution of the rexx code also get displayed.

Now you can also turn on "$trace mode" where $trace commands are automatically added to each line however you should read about the (reasonable) restrictions you should follow when formatting your code.

MORE ON PACKING

The preprocessor packs well written code (by my definition!) and can fail to correctly pack code where strings are appended without the use of the "||" operator (as the excess spaces will be removed). For example the following statement will not create the string you expect when packed:

   BothPartsCombined = 'Value:'   TheValue;

The following statement is a version of the above that will work:

    BothPartsCombined = 'Value:   ' || TheValue;

Note that PPWIZARD may not be able to correctly pack lines that refer to macro variables such as in the following:

#DefineRexx ValidateUrlR_REXX_Location
            #Option PUSH AllowPack=NO
            do  IncIndex = 1 to <?IncludeLevel>  ;;This line can't be packed
            #Option POP
               ;--- Format the input file at this level ---
               ThisBit = FilePart('name', InputComponentLevel(IncIndex));
               ThisBit = ThisBit || '(' || AddCommasToDecimalNumber(InputComponentLineLevel(IncIndex)) || ')';

               ;--- Update location string ----------------
               if  IncIndex = 1 then
                   UrlSourceLocation = ThisBit;
               else
                   UrlSourceLocation = UrlSourceLocation || '->' || ThisBit;
            end
#DefineRexx

The reason for the failure to pack (without the #option commands) in this circumstance is that the rexx code is not valid until the substitution has taken place, this confuses the packing logic (it is not packing "pure" rexx code).

EXAMPLE

#DefineRexx  SomeRexxCode TRACE:auto
             ;--- Comment to be removed (as are blank lines) ---
             $trace   At start of rexx code
             RexxVar1 = strip(GetEnv('PATH'));

             /*--- This rexx comment will also be removed ----*/
             RexxVar2 = '[' || 'stuff';  /*This rexx comment gets removed*/

             ;--- Lets not pack the following rexx code ---
             #option PUSH AllowPack=OFF
             BothPartsCombined = 'Value:'   TheValue;
             #option POP

             ;--- Gets some code from a file ---
             #include "SomeRexx.X"
#DefineRexx
#evaluate   ^^  ^<$SomeRexxCode>^

You could also have a look at the PPWSORT.H header file as a further example.


email me  any feedback, additional information or corrections.
See this page online (look for updates)

[Top][Contents][Search][Prev]: #define[+|?][Next]: #DependsOn


PPWIZARD Manual
My whole website and this manual itself was developed using PPWIZARD (free preprocessor written by Dennis Bareis)
Saturday May 28 2022 at 2:55pm