IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

ISREDIT - Replace string - Exceeding line length issue


IBM Mainframe Forums -> TSO/ISPF
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
chidams78
Currently Banned

New User


Joined: 29 May 2006
Posts: 59
Location: India

PostPosted: Wed Aug 13, 2008 10:30 pm
Reply with quote

Hi all,

Using ISREDIT macro, I am searching and replacing the string in PROClibs.

For example, in the below mentioned PROC, I need to change all the occurances of string XYZ to ZPNDVR.ABC and all the occurances of ABC to ZPNDVR.ABC.

//TESTN1 PROC ENVI1='XYZ',GNBO1='XYZ',GNVR2='ABC',JNKQ2='ABC',
// ZERO='(0)',QTRERFG='(+1)',HLQAO='ZPNDVR',

On running the ISREDIT macro,

ISREDIT MACRO (PROCESS)
ISREDIT C "'XYZ'" "'ZPNDVR.XYZ'" ALL
ISREDIT C "'ABC'" "'ZPNDVR.ABC'" ALL


the strings got replaced fine BUT the line exceeds above 72 bytes.
Could anybody guide me how to get rid of the exceeding line length issue

Thanks
Chidam
Back to top
View user's profile Send private message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2546
Location: Silicon Valley

PostPosted: Wed Aug 13, 2008 10:42 pm
Reply with quote

1. Use FIND macro statement to locate the text.

2. Use the LINE macro statement to get the entire line into a rexx variable.

3. Use Length(Strip(abc)) to get length of text.

4. split the line if you need to. Use LINE_AFTER macro statement to add a new line.

And to it all within a loop so that you FIND one occurrence at a time instead of changing all with one command.
Back to top
View user's profile Send private message
chidams78
Currently Banned

New User


Joined: 29 May 2006
Posts: 59
Location: India

PostPosted: Thu Aug 14, 2008 12:21 am
Reply with quote

Pedro,

Thanks for the steps.
As the third step, I tried getting the length of PROC but got some error

Code
ISREDIT CURSOR = 1 1
ISREDIT (LINE) = LINENUM .ZCSR
ISREDIT (LNE1) = LINE .ZCSR
SET LNELEN = &LENGTH(STRIP(&LNE1))
ISREDIT LINE_AFTER &LINE = DATALINE '&LNELEN'

When the above code is executed to retrieve the length of
//INS0202 PROC DERI1='AIR',ENVO1='AIR',ENVI2='ABC',ENVO2='ABC',

I got the error as
"THIS STATEMENT HAS AN EXPRESSION WITH OPERATORS OUT OF SEQUENCE"

Is it because of the quotes residing in the first PROC line.
Is there any way to get rid of that. Please help me.

Thanks
Chidam
Back to top
View user's profile Send private message
chidams78
Currently Banned

New User


Joined: 29 May 2006
Posts: 59
Location: India

PostPosted: Thu Aug 14, 2008 1:01 am
Reply with quote

Hi,

The above problem regarding getting the length of lone is solved but landed in new problem

If a string has comma or special charcters, convert into string and then take the length
SET LNELEN = &LENGTH(&STRIP(&STR(&LNE1)))

Now the problem is, the line length is always given as 80bytes eventhough it has only 60 bytes and rest as blank spaces.
Since we are converting to string and then using STRIP command, it is showing as 80 bytes.

Could you plz help in getting the syntax of getting the exact line length without blank spaces.

Thanks
Chidams
Back to top
View user's profile Send private message
chidams78
Currently Banned

New User


Joined: 29 May 2006
Posts: 59
Location: India

PostPosted: Thu Aug 14, 2008 7:51 pm
Reply with quote

Hi all,

Any idea how to split up the line (which is converted to string as shown in above code) based on words

Thanks
Chidam
Back to top
View user's profile Send private message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2546
Location: Silicon Valley

PostPosted: Thu Aug 14, 2008 9:49 pm
Reply with quote

I think you are running into CLIST issues. Can you use REXX?
Back to top
View user's profile Send private message
chidams78
Currently Banned

New User


Joined: 29 May 2006
Posts: 59
Location: India

PostPosted: Thu Aug 14, 2008 9:53 pm
Reply with quote

Ya..I think so
I am using ISREDIT macro to change all the prod qualifier to test qualifier
of the impacted jobs and procs.

As per my understanding the below code is CLIST macro, right

ISREDIT MACRO (USRID)
ISREDIT CURSOR = 1 1
ISREDIT (LINE) = LINENUM .ZCSR
ISREDIT (LNE1) = LINE .ZCSR
SET LNE2 = &STR(&LNE1)
SET LNELEN = &LENGTH(&STRIP(&STR(&LNE2)))

1. If itz not, how can we convert this to REXX macro
2. Is there any function to split the line based on the length

Your help is appreciated
Back to top
View user's profile Send private message
chidams78
Currently Banned

New User


Joined: 29 May 2006
Posts: 59
Location: India

PostPosted: Thu Aug 14, 2008 9:54 pm
Reply with quote

Ya..I think so
I am using ISREDIT macro to change all the prod qualifier to test qualifier
of the impacted jobs and procs.

As per my understanding the below code is CLIST macro, right

ISREDIT MACRO (USRID)
ISREDIT CURSOR = 1 1
ISREDIT (LINE) = LINENUM .ZCSR
ISREDIT (LNE1) = LINE .ZCSR
SET LNE2 = &STR(&LNE1)
SET LNELEN = &LENGTH(&STRIP(&STR(&LNE2)))

1. If itz not, how can we convert this to REXX macro
2. Is there any function to split the line based on the length

Your help is appreciated
Back to top
View user's profile Send private message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2546
Location: Silicon Valley

PostPosted: Fri Aug 15, 2008 12:02 am
Reply with quote

Usage of rexx is similar to clists.

To convert to rexx:
1. put /* rexx */ as the first line
2. add ADDRESS ISREDIT statement
3. make your editor macro statements into literal strings
4. use rexx builtin functions

Example:
Code:
/* rexx */
Address ISREDIT
"MACRO"
"(LNE1) = LINE 5"
len = length(strip(lne1))
Back to top
View user's profile Send private message
chidams78
Currently Banned

New User


Joined: 29 May 2006
Posts: 59
Location: India

PostPosted: Fri Aug 15, 2008 2:59 am
Reply with quote

Thanks for the info. I tried converting to REXX instead of CLIST and was able to get the correct line length.

My aim is to split the line if its length is greater than (say 45 bytes) and writing it to the immediate below line BEFORE changing the production high level qualifier to test high level qualifier in the PROC.

Could you plz correct me if my approach is wrong.

1. First find whether the qualifiers that I am converting is there in the line.

2. If YES, then get the length of the whole line to rexx variable. Positon
the cursor to the byte where " ', " is there from the 45th byte of the
whole line. (Mainly truncation happens only to symbolic variables which
is declared at the starting lines of the PROC).

3. Read the remaining contents after " ', " and storing it in REXX variable

4. Having a new line and add // to it and then the saved contents to the
next newly added line after pos 16.

Code:
/* REXX */                             
ADDRESS ISREDIT "MACRO" PROCESS       
"ISREDIT F 'AUTHOR'"                   
"ISREDIT (LINE) = LINENUM .ZCSR"       
"ISREDIT (LINE1) = CURSOR"             
"ISREDIT (LNE1) = LINE .ZCSR"         
LEN = LENGTH(STRIP(LNE1))             
POSI1 = POS("',",LNE1,45)             
IF POSI1 > 0THEN                       
   DO                                 
     "ISREDIT CURSOR = &LINE1 &POSI1" 
   END                                 
ELSE                                   
   "ISREDIT (LINE) = LINENUM .ZCSR"   


Here I was able to get the step 2 as mentioned below.
But I am struck up how to read each line of the PROC and getting the line contents after the " ,' " as told in step3.
Could you plz guide me in this...
Back to top
View user's profile Send private message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2546
Location: Silicon Valley

PostPosted: Fri Aug 15, 2008 3:52 am
Reply with quote

Use the PARSE instruction to break the line apart, something like this:
Code:
Parse var LNE1  part1 45 part2  "'," part3

Which means, find the first "'," after character 45.

You then need to combine part1 and part2 and replace original line with LINE macro command, and add part3 into a new line with LINE_AFTER macro command.
Back to top
View user's profile Send private message
chidams78
Currently Banned

New User


Joined: 29 May 2006
Posts: 59
Location: India

PostPosted: Fri Aug 15, 2008 8:38 pm
Reply with quote

Pedro,

Thanks for the suggestion..
I had made the code as follows; i.e., finding the High level qualifier and then finding for " '," and then getting the line after " ', " in a variable and put it in next line.

Code:
ADDRESS ISREDIT "MACRO" PROCESS             
SLASHES = '//             '                 
"ISREDIT F 'USA#P'"                       
"ISREDIT (LINE) = LINENUM .ZCSR"           
"ISREDIT (LNE1) = LINE .ZCSR"               
LEN = LENGTH(STRIP(LNE1))                   
PARSE VAR LNE1 PART1 45 PART2 "'," PART3   
IF PART3 <> ' ' THEN                       
   DO                                       
     PART3 = SLASHES||PART3                 
     PART = PART1||PART2||"',"             
     "ISREDIT LINE    &LINE = (PART)"       
     "ISREDIT LINE_AFTER &LINE = (PART3)"   
   END                                     
ELSE DO                                     
       "ISREDIT (LINE) = LINENUM .ZCSR"


My concern is that if there are more than one high level qualifier to be changed (USA#P) in the same PROC, how to find the number of occurance and put it in the loop. Is there any way that we can do it?
Back to top
View user's profile Send private message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2546
Location: Silicon Valley

PostPosted: Fri Aug 15, 2008 9:14 pm
Reply with quote

I do not think you need to know the number of them. Your loop should be controlled by the return code from FIND. Issue the FIND and only do your other processing if rc=0. If it is not zero, get out of the loop.
Back to top
View user's profile Send private message
chidams78
Currently Banned

New User


Joined: 29 May 2006
Posts: 59
Location: India

PostPosted: Fri Aug 15, 2008 9:25 pm
Reply with quote

Ya..that will be fine.
Now I am thinking for the other alternative because I had 15 production variables in a PROC to be changed to test naming standards. So i think it is not a good thing to check the same full logic for the 15 variables.

Will this approach works out

1. Just read a line of PROC and if the first 3 charcters of that line are
not //* (comments) then check for " ', " after the 45th byte of that line.

2. Get the remaining line contents of that line (if it is present) and then
insert it into new line.
Note: Obviously the " ', " won't be present in the DSN names and will
be present only for symbolic variable declarations in the PROC

If this approach holds good, how we can read each line by line by puting a loop in REXX
Back to top
View user's profile Send private message
enrico-sorichetti

Superior Member


Joined: 14 Mar 2007
Posts: 10872
Location: italy

PostPosted: Fri Aug 15, 2008 9:45 pm
Reply with quote

Code:
ISREDIT (first) = LINENUM .zfirst
ISREDIT (last) = LINENUM .zlast
i = 0
do linenum = first to last
    i = i + 1
    ISREDIT (temp) = LINE linenum
    line.i = temp
end
line.0 = i
Back to top
View user's profile Send private message
chidams78
Currently Banned

New User


Joined: 29 May 2006
Posts: 59
Location: India

PostPosted: Fri Aug 15, 2008 10:03 pm
Reply with quote

In the above code, first we are getting the first and last line numbers and then execute the loop that many times.

Can you please help me understand what the "LINE.I = TEMP" does.
Anyways we will be getting the current line in "temp" variable and we can manipulate the line with that, right

Also I didnt understand the "ISREDIT (temp) = LINE linenum ". Here from where LINE gets the value.

Please help
Back to top
View user's profile Send private message
enrico-sorichetti

Superior Member


Joined: 14 Mar 2007
Posts: 10872
Location: italy

PostPosted: Fri Aug 15, 2008 10:13 pm
Reply with quote

here is a link to the ispf bookshelf

Quote:
"ISREDIT (temp) = LINE linenum "


tells ISPF to store into the rexx variable the line with a linenumber of linenum

the code posted was just a snipped to show how to put in a properly build stem
all the lines of member being edited/viewed
Back to top
View user's profile Send private message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2546
Location: Silicon Valley

PostPosted: Fri Aug 15, 2008 11:11 pm
Reply with quote

I think your first approach,of using FIND, is cleaner programming.

I think it should be something like this, where the change is done from a subroutine, and the driving program just tells it what to change:
Code:
a = chg_proc('test1', 'prod1')
a = chg_proc('test2', 'prod2')
a = chg_proc('some_text3', 'other_text3')
.
.
Exit

chg_proc:
parse arg  oldtext newtext
findrc = 0
"CURSOR = 1 1"
"EXCLUDE '//*' 1 ALL" /* ignore comments */
Do while (findrc= 0)
  "FIND" oldtext  "NX"
   findrc = rc
   If (findrc = 0) Then
     Do;   /*some stuff */; end;
End
return 0
Back to top
View user's profile Send private message
chidams78
Currently Banned

New User


Joined: 29 May 2006
Posts: 59
Location: India

PostPosted: Mon Aug 18, 2008 9:33 pm
Reply with quote

Thanks Pedro..That program logic holds good.I had implemented and it works gr8..:-)

Concern:
For changing the text DFG to UBA#BA,B2, we can code in REXX macro as
"ISREDIT C 'DFG' 'UBA#BA.C2' ALL"

But if I need to change the DFG qualifier if it between the quotes, whether there is any way to do so

If it is CLIST macro, i can code as
ISREDIT C " 'DFG' " " 'UBA#BA.C2' " ALL

But since we are using REXX macro, we already have quotes before ISREDIT statement. So whether there is any way to change the text only if it is between the single quotes.
Back to top
View user's profile Send private message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2546
Location: Silicon Valley

PostPosted: Mon Aug 18, 2008 10:01 pm
Reply with quote

Whenever I have conflicts between macro syntax and data in the file, I temporarily change the file:

Code:

Address ISREDIT
"C '7d'x  '~' All"
...
/* do other stuff and use new character instead */
...
"C '~' '7d'x All"

Use a character that is not otherwise in the text.
Back to top
View user's profile Send private message
chidams78
Currently Banned

New User


Joined: 29 May 2006
Posts: 59
Location: India

PostPosted: Tue Aug 19, 2008 9:09 pm
Reply with quote

Thanks Pedro for your suggestion. Indeed it was somewhat tricky logic.:-)

The other problem I had encountered is,
When the macro is exeuted in the PROC, it changes the existing TAPE name to TAPE,RETPD=60, thereby truncating the below shown lines 5 and 8.

//TST0222W EXEC PGM=SORT
//SYSPRINT DD SYSOUT=*
//SYSUT1 DD DSN=UBA.INS.QTRGRST.TEST1,
// DISP=(OLD,KEEP,KEEP),
// UNIT=&TAPE,LABEL=1,VOL=,RETAIN,REF=*.TST020.PRINTR)
// DD DSN=&ENVO2..INS.QTRUNIST.SPOOL,
DISP=(OLD,KEEP,KEEP),
// UNIT=&TAPE,LABEL=2,VOL=,RETAIN,REF=*.TST0202S.PRINTR)


The logic i thought to handle this situation is like
1. Just search for DISP= after the column number 35 and if it is
encountered, put it in new line. The same thing for UNIT= and VOL=
Note: The disadv with this logic is that we will be unneccessarily puting all
the DISP=, UNIT= and VOL= into the new line even if the variable
in that line is not changed.

Whether this logic holds good or is there any other good logic to acheive this result
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic View Bookmarks
All times are GMT + 6 Hours
Forum Index -> TSO/ISPF

 


Similar Topics
Topic Forum Replies
No new posts Store the data for fixed length COBOL Programming 1
No new posts How to split large record length file... DFSORT/ICETOOL 10
No new posts Replace each space in cobol string wi... COBOL Programming 3
No new posts PARSE Syntax for not fix length word ... JCL & VSAM 7
No new posts SFTP Issue - destination file record ... All Other Mainframe Topics 2
Search our Forums:

Back to Top