Here are several advanced Rexx programming examples.
/* chgall.rex replace all occurrences of one string, by another this EXAMPLE PROGRAM that uses the 'CHANGESTR' function. see the related 'changestr.rex' program. usage: exec chgall "/before/after" < infile > outfile or: exec chgall "!before!after" < infile > outfile note: the first character of the argument string is an arbitrary character that is used to separate the string to replace, and the replacement string. */ parse value strip( arg( 1 ), 'B', '"' ) with sep +1 rest if sep == '' then call usagemsg if pos( sep, rest ) = 0 then call usagemsg 'The separator' sep 'was not found in:' rest parse var rest before (sep) after if length( before ) = 0 then call usagemsg 'The separator' sep 'was not found in:' rest do lines() say changestr( linein(), before, after ) end exit 0 usagemsg : procedure if arg( 1 ) <> '' then say arg( 1 ) say 'Usage:' say ' exec chgall "/before/after" < infile > outfile' say '' say 'Or:' say ' exec chgall "!before!after" < infile > outfile' exit 1 |
/before/after
/* changestr.rex an EXTERNAL PROCEDURE that emulates the 'changestr' builtin function that is available in NetRexx, Object Rexx, and roo!(TM) usage: result = changestr( str, before, after ) */ if arg() <> 3 then return 40 /* incorrect call to routine */ parse arg str, before, after /* note: the length of 'str' can be 0 */ if length( before ) = 0 then return 40 /* incorrect call to routine */ /* note: the length of 'after' can be 0 */ res = '' do while str <> '' if pos( before, str ) = 0 then leave parse var str left (before) str res = res || left || after end return res || str |
The TWIRL program is a simple program that produces all of the permutations of the letters within a word. It can be helpful for solving common jumbles that appear in daily newspapers. It is a good example of various Rexx capabilities. The program is remarkably short.
/* twirl.rex produce permutations of letters in a word (or jumbled word) usage rexx twirl wordToTwirl */ parse arg wordToTwirl rest if wordToTwirl = '' then call usagemsg 'Please specify a word to twirl...' if rest <> '' then call usagemsg 'Only one word is expected...' call permute '', wordToTwirl do queued() parse pull lin say lin end exit 0 permute : procedure parse arg front, back if length( back ) < 2 then do push front || back return end letters = '' /* remember letters that have been used */ do length( back ) parse var back letter +1 rest if pos( letter, letters ) = 0 then call permute front || letter, rest letters = letters || letter /* used another letter */ back = rest || letter /* twirl the remaining letters */ end return usagemsg : say 'Note:' arg(1) say '' say 'Usage:' say ' rexx twirl wordToTwirl' exit 1 |
The REXXTRY program is a simple, but useful, interactive Rexx command shell.
/* rexxtry.rex -- Rexx interactive shell program usage: rexx rexxtry */ prompt = '==>' RC = 0 /* presume no errors */ call on halt say "Type 'EXIT' to end" /* show how to stop */ resume : /* resumption point after erroneous expressions */ /* anticipate errors */ signal on error signal on failure signal on syntax say time() prompt /* solicit initial REXX request */ do while lines() > 0 /* process requests until end of input */ parse linein _line_ /* get REXX request */ if _line_ = 'thanks' then /* answer unexpected praise from user */ say '...Your wish is my command' /* show humility */ else interpret _line_ /* INTERPRET REXX statement(s) */ say time() prompt /* solicit next REXX request */ end exit RC /* final code is returned upward */ error: failure: syntax: /* deal with erroneous requests */ say "???" condition( 'D' ) /* show befuddlement & beep */ say " " _line_ /* show erroneous request */ signal resume /* resume processing */ halt : procedure exit 0 |
/* caldisp.rex, show calendar for current month this is a fast calendar display program because the days section is built by a single instruction ! usage rexx caldisp */ /* obtain year, month, and day of month */ parse value date( 'Standard' ) with year 5 month 7 dayofmon dayofmon = strip( dayofmon, 'L', '0' ) /* strip leading zero */ /* show title lines */ say right( time('C'), 8) center( date('M'), 38 ) , substr( year, 3 )'.'right( date('D'), 3, '0' ) say center( year, 56 ) say ' Sun Mon Tue Wed Thu Fri Sat' /* compute day of week: 1 to 7 */ dayofwk = 1 + ( date('B') // 7 ) /* identify #days in month */ daysinmo = word( '31 28 31 30 31 30 31 31 30 31 30 31', month ) /* add 1 to #days in month if it's February and this is a leap year */ if month = 2 then daysinmo = daysinmo + leap( year ) /* compute day# of 1st day of month */ day1no = 1 + ((35 + dayofwk - dayofmon) // 7 ) vector = left( ' ', 8 * day1no ) || , overlay( ' > 'right( dayofmon, 2 )' < ' , , left( , ' 1 2 3 4 5 ' || , ' 6 7 8 9 10 ' || , ' 11 12 13 14 15 ' || , ' 16 17 18 19 20 ' || , ' 21 22 23 24 25 ' || , ' 26 27 28 29 30 ' || , ' 31 ', (daysinmo * 8) ), , 1 + ((dayofmon-1) * 8) ) /* show calendar lines */ do i=1 to length( vector ) by 56 say substr( vector, i, 56 ) end exit leap : procedure arg yr return (yr//4 = 0) & ((yr//100 <> 0) | (yr//400 = 0)) |
/* revise.rex, revise file lines using input template as per output form Keywords Pictorial form file revision Usage rexx revise {input_template} {output_form} [(selection_criteria)] <inf >outf Arguments {input_template} : a parsing template {output_form} : emission form, using input_template terms [(selection_criteria)] : conditional selection, using input_template terms the special variable '_LNO' can be referenced. Files used Standard input Standard output Exit codes 0 => normal completion non-0 => an error occurred Input record format an ASCII file Sample input file file to revise Sample output file revised file Examples of use rexx revise {f1 f2 rest} {f2 rest} <inf >outf this removes the 1st word from every input line rexx revise {f1 f2} {f2 f1} <inf >outf this puts the 1st word at the end of every input line rexx revise {lin} {lin} "(_lno <= 10)" <inf >outf this extracts the first 10 lines of the input file Explanation This program is useful for a multitude of field rearranging operations. The secret to its success is the use of two INTERPRET statements. The first does generic parsing. The second does generic record selection versus optional selection criteria, and then performs generic output emission. Quoting is required for various command requests. In the last example above "(_lno < 10)" is quoted. If it were unquoted, the '<' character causes file redirection to be performed [from the file named '10']! */ if getenv( 'RXDEBUG' ) = 'Y' then trace Results parse arg '{' parseTemplate '}' '{' outputFormat '}' '(' selectionCondition ')' if selectionCondition = '' then selectionCondition = 1 /* select all */ trace off if parseTemplate = '' | outputFormat = '' then signal usagemsg do _lno=1 while lines() > 0 interpret 'parse linein' parseTemplate /* parse line to terms */ interpret 'if (' selectionCondition ') then' , /* process this line ? */ 'say' outputFormat /* emit output, as per form */ end exit 0 usagemsg : say 'Usage:' say , ' rexx revise {input_template} {output_form} [(selection_criteria)]' , ' <inf >outf' exit 1 |
parseTemplate | parsing template |
outputFormat | output format |
selectionCondition | input line selection condition |