Write a procedure that extracts a specific macro from a MACLIB. Of course, you could do it with the aid of some CMS commands (like PUNCH or MACLIST), but this time we expect you to use REXX File I/O methods.
Your procedure can use any of the File I/O methods explained in the text. Maybe it's good to review the advantages and disadvantages of the different methods before to choose one for the exercise.
The command format should be:
GETMAC maclib_fn macro
where maclib_fn is the filename of the macro library, and macro is the name of the macro you want to extract.
Note
You can find plenty of MACLIB files on your S-disk. You should
'stress-test' your procedure on one of the largest ones (DMSOM MACLIB).
Your procedure should thus perform these logical steps:
! /**********************************************************************/ ! /* GETMAC - Created by RUDI */ ! /* Function : get macro out of maclib */ ! /* Parameters : maclib and macro name */ ! /**********************************************************************/ 1 ! Address Command 2 ! parse upper source . . myname . 3 ! parse upper arg maclibname macroname . 4 ! if maclibname='' then call error_exit 01,'Give a valid maclib name' 5 ! if macroname='' then call error_exit 02,'Give a valid macro name' 6 ! address '' 'ESTATE' maclibname 'MACLIB *' 7 ! if RC^=0 then call error_exit rc,maclibname 'MACLIB * does not exists' ! /**************** get index pointer from first record ***********/ 8 ! 'EXECIO 1 DISKR 'maclibname ' MACLIB * (FINIS VAR' firstline 9 ! if RC<>0 then call Error_Exit RC,'cannot read 'maclibname' MACLIB.' 10 ! parse var firstline vermac 7 13 indpoint 17 . 11 ! if vermac<>'LIBPDS' then call error_exit 03,maclibname' is not a maclib' 12 ! macroname=left(macroname,8) ! /**** read index from indpoint till end until macro found *******/ 13 ! 'EXECIO * DISKR 'maclibname' MACLIB * 'c2d(indpoint)' (FINIS STEM LIN.' 14 ! line='' 15 ! do i=1 to lin.0 by 1 16 ! line=line''lin.i 17 ! end 18 ! parse var line (macroname) +8 macp +8 nextmacnam +8 nextmacp +8 19 ! if macp='' then call error_exit 28,macroname' not found in 'maclibname 20 ! mlins=c2d(nextmacp)-c2d(macp)-1 ! /***************** read the macro *************************************/ 21 ! 'EXECIO 'mlins' DISKR 'maclibname' MACLIB * 'c2d(macp)' (FINIS STEM LIN.' ! /**** write the macro to a file ***************************************/ 22 ! 'EXECIO 'mlins' DISKW 'macroname' MACRO A (FINIS STEM LIN.' 23 ! call Error_Exit 00,'All done' ! /****************** Exit routine ********************************/ 24 ! Error_Exit: 25 ! parse arg retc,errmsg 26 ! if errmsg<>'' then say myname':' errmsg 27 ! exit retc
if maclibname='' then call error_exit 01,, 'Parameters missing : we expect a MACLIB name and a macro name' if macroname='' then call error_exit 02,, 'Parameter missing : we need a macro name as well'
Or, easier, as both parameters are required anyway:
if macroname='' then call error_exit 01,, 'Parameter(s) missing : correct format is GETMAC maclib macro'
At the same time, the message informs about the correct syntax.
! /***********************************************************************/ ! /* GETMAC - Created by Valerie */ ! /***********************************************************************/ 1 ! address command 2 ! parse upper arg maclib_fn macro . 3 ! select 4 ! when maclib_fn='' then call errexit rc,'You forgot the filename', 5 ! 'of the maclib!' 6 ! when macro='' then call errexit rc,'You forgot the macro name!' 7 ! when length(maclib_fn)>8 then call errexit rc,'The filename of', 8 ! 'the maclib is too long!','Try again' 9 ! when length(macro)>8 then call errexit rc,'The name of', 10 ! 'the macro you want to extract is too long!','Try again' 11 ! otherwise nop 12 ! end 13 ! 'ESTATE' maclib_fn 'MACLIB *' 14 ! if rc<>=0 then call errexit rc,"Didn't find" maclib_fn "on any", 15 ! "accessed disk","Try again" 16 ! 'EXECIO 1 DISKR' maclib_fn 'MACLIB * (MARGIN 13 16 VAR RECC' 17 ! r=c2d(recc) 18 ! 'EXECIO 1 DISKR 'maclib_fn 'MACLIB *' r '(VAR MACC' 19 ! parse var macc (macro) mac1 +8 macadr +8 20 ! if mac1='' then call errexit 5,'The macro' macro 'does not exist' 21 ! 'PIPE COMMAND ERASE' macro 'MACLIB A' 22 ! t=c2d(macadr) 23 ! v='61FFFF61'x 24 ! 'EXECIO * DISKR' maclib_fn 'MACLIB *' t+1 '(LOCATE &'v'& STEM Z.' 25 ! if rc¬=0 then call errexit rc,'does not exist' 26 ! parse var z.2 z . 27 ! 'EXECIO' z ' DISKR' maclib_fn 'MACLIB *' t '(FINIS STEM D.' 28 ! 'EXECIO' z 'DISKW' macro 'MACRO A (FINIS STEM' D. 29 ! if rc<>=0 then call errexit rc,'The write to your A-disk was not', 30 ! 'succesfull' 31 ! else say 'The file' macro 'MACRO is created on your A-disk' 32 ! exit 33 ! ERREXIT: 34 ! parse source . . myname mytype . 35 ! do n=2 to arg() 36 ! say myname mytype ':' arg(n) 37 ! end 38 ! if arg(1)<>='RC' then do 39 ! 'FINIS' maclib_fn 'MACLIB' fn 40 ! exit arg(1) 41 ! end 42 ! else exit
This is definitely agains our rule that says to avoid switching between environments if it is not required.
This is our solution for this exercise:
/***********************************************************************/ /* Procedure GETMAC */ /* Function : Get a macro from a MACLIB file */ /* Format : GETMAC maclib_name macro_name */ /***********************************************************************/ address command parse upper arg maclib macro . if maclib='' then call errexit 8,'Missing parameters, format is', 'GETMAC maclib_name macro_name' if macro='' then call errexit 8,'Missing macro name, format is', 'GETMAC maclib_name macro_name' maclib=maclib 'MACLIB *' 'STATE' maclib /* does maclib exist ? */ if rc<>0 then call errexit rc,maclib 'MACLIB not found on any disk' 'EXECIO 1 DISKR' maclib '(MARGIN 13 16 VAR IDX' /* get ptr to index */ if rc<>0 then call errexit rc,'Problems reading 'maclib' MACLIB file' /* then read index */ 'EXECIO * DISKR' maclib c2d(idx) '(LOCATE /'macro'/ STEM IDX.' if rc<>0 then call errexit rc,'Macro 'macro' not found in library', 'or problems reading 'maclib' MACLIB file' parse var idx.1 . (macro) . +8 macrec +8 . /* search for delimiter */ 'EXECIO * DISKR' maclib c2d(macrec) '(LOCATE &'"61FFFF61"x'& STEM EOM.' if rc<>0 then call errexit rc,'Problems extracting macro 'macro /* extract macro */ 'EXECIO' word(eom.2,1)-1 'DISKR' maclib c2d(macrec) '(FINIS STEM MAC.' if rc<>0 then call errexit rc,'Problems extracting macro 'macro 'ERASE' macro 'MACRO A' 'EXECIO' mac.0 'DISKW' macro 'MACRO A (FINIS STEM MAC.' /* write it */ if rc<>0 then call errexit rc,'Problems creating 'macro' MACRO on disk A' else call exit 0,macro 'MACRO A successfully created' /***********************************************************************/ ERREXIT: EXIT: parse source . . myname . do n=2 to arg() ; say myname':' arg(n) ; end n exit arg(1)
Use the backward navigation of your browser to return to the assignments.