The following XEDIT macro (Figure 1) is an example
of the type of macro you might write to make life a little easier.
The application is typical of a text processing file arrangement,
where many SCRIPT files are imbedded in a master file, with the SCRIPT
control word .im.
The problem with this type of setup is that if you have to make
a global change throughout all the files, you have to edit each file,
make the change, and then file each file.
When issued from the master file, this macro edits each file, performs
a global change, and files it.
The macro is invoked by entering the macro name, GLOBCHG. The arguments
passed to the macro are the old data and the new data, enclosed in
delimiters:
GLOBCHG /string1/string2/
For
example, if a file called MASTER SCRIPT contains:
.im FILE1
.im FILE2
.
.
.
.im FILE100
and the following commands are issued:
XEDIT MASTER SCRIPT
GLOBCHG/WAR AND PEACE/SENSE AND NONSENSE/
WAR AND PEACE is
changed to SENSE AND NONSENSE each time it occurs in every
file. (In this macro, no attempt is made to execute the change on
files that may be imbedded at the next level.)
The GLOBCHG macro can also delete data throughout the files, by
changing a string to a null string, for example:
GLOBCHG /bad data//
The following is a listing of the macro, whose file ID is GLOBCHG
XEDIT A1. After the listing, each line in the macro is explained.
For more information on REXX statements in the macro, see z/VM: REXX/VM Reference.
Figure 1. Sample
Macro
00001 /* Do a global change on imbedded Script files */
00002 /* Input to this macro is the CHANGE command to be executed on */
00003 /* the file currently being xedited and on any files it imbeds. */
00004 parse arg operand /* Get passed CHANGE cmd */
00005 if operand = '' then do /* If omitted, then error */
00006 emsg 'EXE545E Missing operand(s)' /* Give error message */
00007 parse source . . me . /* Get this macros name */
00008 cmsg me /* Put it on command line */
00009 exit /* Leave this macro */
00010 end /* End of DO group */
00011 preserve /* Save current status */
00012 set wrap off /* Set wrap off */
00013 set msgmode on /* Set message mode on */
00014 set case mixed ignore /* Set proper case */
00015 top /* Go to TOP of file */
00016 find .im /* Find first imbed file */
00017 if rc ¬= 0 then do /* If none found, give msg */
00018 restore /* Restore previous status */
00019 emsg 'No IMBED found.' /* Give message */
00020 exit /* Leave this macro */
00021 end /* End of DO group */
00022 do while rc=0 /* Imbed found, process it */
00023 extract '/curline/' /* Get current line */
00024 parse upper var curline.3 . fname . /* Separate out file name */
00025 address command state fname 'SCRIPT *'/* Does this file exist? */
00026 if rc ¬= 0 then do /* If not, issue message */
00027 msg 'IMBEDed file' fname 'SCRIPT does not exist, bypassed.'
00028 find .im /* Search for next imbed */
00029 iterate /* Cause next loop iterat'n*/
00030 end /* End of DO group */
00031 xedit fname 'SCRIPT (NOPROFILE' /* File exists, XEDIT it */
00032 extract '/fname/ftype/fmode/' /* Get name, type, mode */
00033 msg 'Processing file' fname.1 ftype.1 fmode.1 /* Issue message */
00034 change operand '* *' /* Issue CHANGE command */
00035 file /* Save the file & quit */
00036 find .im /* Find the next imbed */
00037 end /* End of DO loop */
00038 restore /* Loop ends, restore */
00039 msg 'No more .imbeds found, global change completed.' /* Give msg */
00040 exit /* All done, leave macro */
Now, let's walk through the macro, a
line at a time.
00001-00003 /* Do a global change on imbedded Script
files */
REXX comment lines. The first line of any REXX macro must be
a comment line to tell the Interpreter this is a REXX file.
00004 parse arg operand
Place the passed arguments into the variable called OPERAND.
00005 if operand = " then do
If no arguments were entered when the macro was invoked, execute
the following statements until an END is reached (DO group). (OPERAND
was set to a null in line 4.)
00006 emsg ‘EXE545E Missing operand(s)’
Display this message.
00007 parse source . . me .
Look at the source string and place the name of this macro into
the variable ME.
00008 cmsg me
The macro name (in the variable ME) is displayed on the command
line.
00009 exit
Return control to the editor.
00010 end
This statement signals the end of the DO group that began in
line 5.
00011 preserve
This subcommand saves the editor settings until a subsequent
RESTORE subcommand is issued (line 38).
00012 set wrap off
Wrapping during the target search is turned off. When the end
of the master file is reached the macro ends, rather than wrapping
around, searching for .im, and getting caught in a loop.
00013 set msgmode on
Messages will be displayed. By turning the message mode on and
off, you can select which messages you want displayed.
00014 set case mixed ignore
In target searches, uppercase and lowercase representations
of the same letter will match.
00015 top
Move the line pointer to the top of the master file, which is
the file from which the macro was invoked.
00016 find .im
Search forward in the master file for the first line that contains .im in column 1, that is, locate the first line that imbeds a
file.
00017 if rc ¬= 0 then do
If there is a nonzero return code from the FIND subcommand,
no .im was found, (previous statement), then do the following
statements up to the END (another DO group).
00018 restore
Restore the settings of XEDIT variables to the values they had
when the PRESERVE subcommand was issued (line 11).
00019 emsg ‘No IMBED found.’
Display this message.
00020 exit
Return control to the editor.
00021 end
This statement signals the end of the DO group that was started
in line 17.
00022 do while rc=0
Repeat the following statements (up to the END in line 37),
as long as the return code (RC) is 0. The initial value for RC is
set with the FIND subcommand in line 16; this point is only reached
if RC was set to 0, which means an imbedded file was found. The last
statement in this loop is also a FIND subcommand, and RC is reset
to the return code for that FIND subcommand just before returning
to this point to execute the statements again. When the return code
is not 0, this macro continues with the statement following the END
(line 37).
00023 extract ‘/curline/’
Return information about the current line in macro variables,
in the form curline.n, where the subscript
distinguishes among the variables.
00024 parse upper var curline.3 . fname .
CURLINE.3 contains the contents of the current line (as returned
by the preceding EXTRACT subcommand). In this case the current line
is the .im statement that was found through “find .im.” This
statement takes the second blank delimited word from the variable
CURLINE.3 and puts it into the variable fname.
00025 address command state fname 'SCRIPT
*'
The STATE command is a CMS command that verifies the existence
of a file. This statement checks to see if the file named in the
.im statement exists. The quotation marks are needed around the asterisk
to avoid confusion with the REXX multiplication operator. Enclosing
the word SCRIPT and the asterisk in quotation marks makes it a literal
string.
00026 if rc ¬=0 then do
If the return code from the STATE command is not zero, then
do the following statements up to the END statement in line 30 (DO
group).
00027 msg ‘IMBEDed file’ fname ‘SCRIPT
does not exist, bypassed.’
Display this message. REXX substitutes the value of fname in
the message before it is displayed.
00028 find .im
This locates the next imbed control word in the file.
00029 iterate
This statement tells REXX to go to the END statement and complete
the processing for this iteration of the DO loop.
00030 end
This statement signals the end of the DO group that was started
in line 26.
00031 xedit fname ‘SCRIPT (NOPROFILE’
This statement invokes the editor (XEDIT) for the file specified.
REXX substitutes the value of fname in this line before passing
it to XEDIT.
00032 extract ‘/fname/ftype/fmode/’
Returns the file name, file type, and file mode in macro variables.