The most primitive fix is: insert your new line(s) not after, but before the current line; either it ends with ')' or not.
The whole REXX code could also be re-arranged in a more simple and clear way; I'm busy now for this exercise. Maybe later I'll return to it.
I tried to add before but my code is overwriting. I will try again and post the results.
I also will test with trace option and try to figure out.
I can understand. Thanks for your time and help.
I spent about 40 minutes to fix the bugs, to adjust the style of coding, and to remove absolutely unneeded garbage from the code.
It seems to be working correctly.
I am against using too complicated methods to reach simple goals, that's why I always do everything in the most simple way.
Code:
/* REXX */
Address ISREDIT
"MACRO"
"(CURRLN) = LINENUM .ZCSR" /* CURRENT LINE */
"(LASTLN) = LINENUM .ZLAST" /* LAST LINE NUMBER */
I = 0
Defines? = 0
AttrAdded? = 0
Do Forever
I = I + 1
If I > LASTLN Then Leave /* stop at the end of text */
"(LINE) = LINE " I /* read whole line */
Parse Var Line Line '/*' Comments /* separate comment part */
If Line = '' Then /* nothing but comments? */
Iterate /* continue to next line */
If ¬Defines? Then Do /* look for first DEFINE */
Defines? = Pos( ' DEFINE', LINE ) > 0 /* mark "DEFINE clause" */
If Defines? Then
AttrAdded? = 0 /* reset flag when first in DEFINE */
End
Else If Pos( ' DATA', LINE ) > 0 Then /* look for end DEFINE */
Defines? = 0 /* mark "out of DEFINE clause */
If ¬Defines? , /* while not within DEFINE */
| AttrAdded? Then /* or all done already */
Iterate /* continue to next line */
/* Detect all keywords we are interested in */
NoIndex? = Pos( ' NONINDEXED', LINE ) > 0 ,
| Pos( ' NIXD', LINE ) > 0
Index? = Pos( ' INDEXED', LINE ) > 0 ,
| Pos( ' IXD', LINE ) > 0
Number? = Pos( ' NUMBERED', LINE ) > 0 ,
| Pos( ' NUMD', LINE ) > 0
Keysp? = Pos( ' KEYS', LINE ) > 0
Select
When NoIndex? Then
CALL ADD_ATTRB I "LOG(NONE) -"
When Index? ,
| Number? ,
| Keysp? Then
CALL ADD_ATTRB I "LOG(UNDO) -"
Otherwise
Nop
End
End
Return 0
/* ------------------------------------------------------------ */
ADD_ATTRB:
/* ------------------------------------------------------------ */
Arg LN PRMT2 /* variable parts passed as parameters */
Address ISREDIT
PRMT1 = "RLSQUIESCE -" /* constant part defined as local */
P1 = Verify( LINE, ' ' ) /* calculate current indentation */
Blanks = Copies( ' ', P1 - 2 ) /* prepare string of blanks */
"ISREDIT LINE_BEFORE " LN "= DATALINE '" Blanks || PRMT1"'"
"ISREDIT LINE_BEFORE " LN "= DATALINE '" Blanks || PRMT2"'"
LASTLN = LASTLN + 2 /* new last line now moved by 2 */
AttrAdded? = 1 /* flag "this clause done" */
Return
I hope when more special cases need to be considered, it would be much easier to update a short and clear code, rather than a sophisticated and long one.
The most primitive fix is: insert your new line(s) not after, but before the current line; either it ends with ')' or not.
The whole REXX code could also be re-arranged in a more simple and clear way; I'm busy now for this exercise. Maybe later I'll return to it.
I tried to add before but my code is overwriting. I will try again and post the results.
I also will test with trace option and try to figure out.
I can understand. Thanks for your time and help.
I spent about 40 minutes to fix the bugs, to adjust the style of coding, and to remove absolutely unneeded garbage from the code.
It seems to be working correctly.
I am against using too complicated methods to reach simple goals, that's why I always do everything in the most simple way.
Code:
/* REXX */
Address ISREDIT
"MACRO"
"(CURRLN) = LINENUM .ZCSR" /* CURRENT LINE */
"(LASTLN) = LINENUM .ZLAST" /* LAST LINE NUMBER */
I = 0
Defines? = 0
AttrAdded? = 0
Do Forever
I = I + 1
If I > LASTLN Then Leave /* stop at the end of text */
"(LINE) = LINE " I /* read whole line */
Parse Var Line Line '/*' Comments /* separate comment part */
If Line = '' Then /* nothing but comments? */
Iterate /* continue to next line */
If ¬Defines? Then Do /* look for first DEFINE */
Defines? = Pos( ' DEFINE', LINE ) > 0 /* mark "DEFINE clause" */
If Defines? Then
AttrAdded? = 0 /* reset flag when first in DEFINE */
End
Else If Pos( ' DATA', LINE ) > 0 Then /* look for end DEFINE */
Defines? = 0 /* mark "out of DEFINE clause */
If ¬Defines? , /* while not within DEFINE */
| AttrAdded? Then /* or all done already */
Iterate /* continue to next line */
/* Detect all keywords we are interested in */
NoIndex? = Pos( ' NONINDEXED', LINE ) > 0 ,
| Pos( ' NIXD', LINE ) > 0
Index? = Pos( ' INDEXED', LINE ) > 0 ,
| Pos( ' IXD', LINE ) > 0
Number? = Pos( ' NUMBERED', LINE ) > 0 ,
| Pos( ' NUMD', LINE ) > 0
Keysp? = Pos( ' KEYS', LINE ) > 0
Select
When NoIndex? Then
CALL ADD_ATTRB I "LOG(NONE) -"
When Index? ,
| Number? ,
| Keysp? Then
CALL ADD_ATTRB I "LOG(UNDO) -"
Otherwise
Nop
End
End
Return 0
/* ------------------------------------------------------------ */
ADD_ATTRB:
/* ------------------------------------------------------------ */
Arg LN PRMT2 /* variable parts passed as parameters */
Address ISREDIT
PRMT1 = "RLSQUIESCE -" /* constant part defined as local */
P1 = Verify( LINE, ' ' ) /* calculate current indentation */
Blanks = Copies( ' ', P1 - 2 ) /* prepare string of blanks */
"ISREDIT LINE_BEFORE " LN "= DATALINE '" Blanks || PRMT1"'"
"ISREDIT LINE_BEFORE " LN "= DATALINE '" Blanks || PRMT2"'"
LASTLN = LASTLN + 2 /* new last line now moved by 2 */
AttrAdded? = 1 /* flag "this clause done" */
Return
I hope when more special cases need to be considered, it would be much easier to update a short and clear code, rather than a sophisticated and long one.
I am so thankful for what you did.
I just added one more line since i saw some statement "DEF CLUSTER" instead of DEFINE CLUSTER.
Code:
Defines? = Pos( ' DEFINE', LINE ) > 0,
| Pos( ' DEF ', LINE ) > 0
Thanks again for helping me with this requirement.
1) The alternate solution is supposed mainly to resolve another issue: standardized alignment/arrangement of the source statement(s). Logically it is a separate task from adding missing parameters. Those two could be implemented separately from each other, and also applied separately, which makes sense in most cases.
2) Partial syntax check algorithm could be implemented in a less chaotic way, by using the existing REXX operations. Long time ago I did such exercises; maybe I'll present some parsing examples in a separate topic.
3) In all presented examples we did not consider important case(s): what if the parameters to be added do exist already in the source code? (For instance, if this macro has been applied twice to the same library member???)
This case is much more important than re-alignment of the source code, but it requires a changed scan/parse approach.
1) The alternate solution is supposed mainly to resolve another issue: standardized alignment/arrangement of the source statement(s). Logically it is a separate task from adding missing parameters. Those two could be implemented separately from each other, and also applied separately, which makes sense in most cases.
2) Partial syntax check algorithm could be implemented in a less chaotic way, by using the existing REXX operations. Long time ago I did such exercises; maybe I'll present some parsing examples in a separate topic.
3) In all presented examples we did not consider important case(s): what if the parameters to be added do exist already in the source code? (For instance, if this macro has been applied twice to the same library member???)
This case is much more important than re-alignment of the source code, but it requires a changed scan/parse approach.
Thanks for your suggestions and which are valid scenarios.
I already faced the similar example with respect to your third point.
Some other team already added these parameters couple of months ago but by mistakenly client had given same members to us again.
currently we are doing srchfor with keyword in the PDS before running this rexx code.
My idea is to find for string "RSLQUIESCE" and the logic if found.