Page 1 of 2

Find a string in all the PDS members available.

PostPosted: Wed May 07, 2014 4:50 pm
by anil_817005
Hi All !!

I'm new to REXX and CLIST, I even don't know ABC of REXX and CLIST so plz help. I know COBOL, JCL, DB2 pretty well but not these. Here is my problem, I want to code a rexx program such that when a job is typed it should list the proc used in it, and keeping that proc it should list the parms used in it, and it goes on. If you let me know how to list the proc used in a job, and with the proc how to list its parms, I can carry on the rest cycle. I hope you understood my requirement.

Example :

Job - ABC

//MXDFGH24,notify=&SYSUID
//DFIGO0565 EXEC DEF
//SYSIN
//*....

PROC - DEF

//DEFFOA PROC
//123.123.parmlib(GHI)
//*
//123.123.parmlib(JKL)
//*

When i type the job name "ABC" and give search

It should say

JOB = ABC
PROC = DEF
PARM = GHI
PARM = JKL

Re: Find a string in all the PDS members available.

PostPosted: Wed May 07, 2014 5:03 pm
by enrico-sorichetti
I'm new to REXX and CLIST, I even don't know ABC of REXX and CLIST so plz help.


unfortunately the task is too complex for somebody who does not know even the ABCs

so helping would consist in writing the whole thing for You,
and that' s not the objective of a forum

to find out the procedure name might be pretty easy
search the source file for constructs like

EXEC xxxxxxxx
EXEC PROC=xxxxxxxx

but ....
how will You determine the dataset where the procedure resides ?

Re: Find a string in all the PDS members available.

PostPosted: Wed May 07, 2014 5:13 pm
by enrico-sorichetti
has somebody inside Your organization made a benefit costs analysis ???

Re: Find a string in all the PDS members available.

PostPosted: Wed May 07, 2014 6:22 pm
by NicC
Right - given what Enrico has written but ignoring it anyway (but he is correct) and so continuing with the task (!):
Assuming 1) you will only specify a job that executes a procedure 2) a job only executes ONE procedure 3) each job has a JCLLIB card 4) the jobname is the same as the member name:
Prompt for the jobname
   Allocate the JCL library/member
   Use EXECIO to read the member line by line until you find the JCLLIB line
   Extract the procedure library/s using PARSE
   Continue reading until you find the EXEC line using POS or INDEX function - one is 'defunct'
   Extract the procedure name
   Allocate  the procedure library/member
   read the procedure line by line extracting the symbolics (symbolics will end before the first EXEC PGM=)
   format and display your output
   free the procedure library and the JCL library
   Exit

Check for errors after all external function calls
Use Trace to track your code initially (just so that you can see what is going on) and to debug when you hit a problem
That is one way and it relies on the assumptions. Once you get that working then you can start mucking around to cater for those assumptions being wrong or wanting to do multiple jobs in one execution.

Re: Find a string in all the PDS members available.

PostPosted: Wed May 07, 2014 10:35 pm
by anil_817005
I understand that its complex, but i can code it in cobol but not in clist or rexx...
like yea i myself ll give the job name and ll do a search...
i will specify the jcllib pds.. n in that pds we need to open the job, since the job uses a single procedure only, we can read line line by line when the proc is found, i ll store the proc name in a temporary variable, n keeping tat proc name i ll open the proc, in the proclib pds, then again i ll search line by line n ll read the parm when parm is found ll store that in another temporary variable, once all the searching is done, i ll display with job name , as proc = temporary proc variable, parm = temporary parm variable1 , parm = temporary parm variable2 etc...

Plz help me to implement this logic in CLIST code, actually still my requirement goes on but if i get this code i can do d rest. If you help me we can do it in phases and finish it.. thank you guys :)

Re: Find a string in all the PDS members available.

PostPosted: Wed May 07, 2014 10:36 pm
by anil_817005
NicC yes u r right,,.. the logic is correct n i want d same but i dunno how to code it in rexx or clist :(

Re: Find a string in all the PDS members available.

PostPosted: Wed May 07, 2014 10:40 pm
by anil_817005
enrico-sorichetti... i'm doing this process normally by opening each job, proc and looking into it.. i knw all the pds names so we can specify the path n look into it.
Since i'm fresher I dunno about the cost analysis... actually i got this idea so that it ll automate the process, instead of going and opening and searching in each library.

Re: Find a string in all the PDS members available.

PostPosted: Wed May 07, 2014 11:37 pm
by enrico-sorichetti
first of all stop using kiddie sms abbreviations

I hope you understood my requirement.

Your requirement is badly described because of poor terminology

in jcl jargon a parm is what is specified when executing a procedure
like in
the execution
//S1 EXEC PROC1,PARM1=AAAA,PARM3=CCCCC


the definition/declaration
//PROC1 PROC PARM1=DEFAULT1,PARM2=DEFAULT2


note that it is not necessary to specify in the PROC statement all the parms
the parms in the PROC statement are used to define defaults for the parameters not
specified in the exec statement

so to find out the parms used for the specific run
You will have to merge the parms specified in the exec and those declared
in the proc statement

overall You are simplifying things

and the output should be in the format ( for the example posted )
jobname     stepname    procname    parm        how     value     
<jobname>   s1          proc1       parm1       user    aaaa
                                    parm2       default default2
                                    parm3       user    ccccc

You will have to show also the step name because it is not uncommon
to execute the same procedure multiple times in the same job

note also the the PROC statement is not needed inside a procedure unless You want to set some defaults

the wiser thing would be to review the requirement
and post a much better description

Plz help me to implement this logic in CLIST code,

unfortunately that means writing the code for You
furthermore NOBODY will provide CLIST snippets when REXX is much more effective

PS.
(symbolics will end before the first EXEC PGM=)

NOPE the symbolics should be parsed from the PROC statement
and empty values should be taken into account

Re: Find a string in all the PDS members available.

PostPosted: Wed May 07, 2014 11:50 pm
by anil_817005
Hi Enrico,
I appologise for the sms language.

Yes, I have heard that rexx is powerful than clist.
You got my requirement.

As of now if you can help me to list out the proc name and parm names the rest, I ll carry on and implement it.

The o/p should be somewhat as you told.

jobname procname parm
<jobname> proc1 parm1
parm2
parm3

Thanks,
Anil

Re: Find a string in all the PDS members available.

PostPosted: Thu May 08, 2014 2:28 am
by enrico-sorichetti
just to warn You about what You are trying to attempt

here a quick and dirty snippet
to extract from an exec statement the parms being used
IT IS WRITTEN AS AN EDIT MACRO

/*REXX - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*                                                                   */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
Trace "O"

Parse Source _sys _how _cmd .

_ack = 1

If ( Sysvar(SYSISPF) \= "ACTIVE" ) Then Do
   Say left(_cmd,8)"- Ispf is not active. Command not executed"
   exit 4
End

call $ispex "CONTROL ERRORS RETURN"

if  ( $isred("MACRO (ARGS) NOPROCESS ") \= 0 ) then do
    zedsmsg = "Invocation ERROR"
    zedlmsg = left(_cmd,8)"- Must be invoked as a MACRO"
    call $ispex "SETMSG MSG(ISRZ001)"
    exit 4
end

if ( $isred("PROCESS RANGE S ")  = 0 ) then do
   call $isred "(XFR)  = LINENUM .ZFRANGE "
   call $isred "(XTO)  = LINENUM .ZLRANGE "
end
else do
   call $isred "(XFR)  = LINENUM .ZFIRST "
   call $isred "(XTO)  = LINENUM .ZLAST  "
end

stmt.0 = 0
do l = xfr to xto
   call $isred "(buff) = LINE" l
   j     = stmt.0 + 1
   stmt.j = left(buff, 71)
   stmt.0 = j
end

/* */
ampsnd   = "`"
apostr   = "~"

wchars   = "`~"
jchars   = "&'"
/* */

stmt_numb = 0
stmt_name = ""; stmt_oper = ""; stmt_keys = ""

j = 0
do while ( j < stmt.0 )
   j   = j + 1
   buff = stmt.j
   if strip(buff)      =  "/*"  | ,
      strip(buff)      =  "//"  | ,
      substr(buff, 1,3) = "//*" | ,
      substr(buff, 1,2) = "/*"  | ,
      substr(buff, 1,2) \= "//" then ,
      iterate

   buff = translate(buff, wchars, jchars)
   if $scan(buff) then ,
      iterate

   stmt_keys = stmt_keys || ","
   if wordpos(stmt_oper, "PROC EXEC") = 0 then do
      stmt_name = ""; stmt_oper = ""; stmt_keys = ""
      iterate
   end
   keyw_coun = 0
   posn_coun = 0
   keyw_name = ""
   keyw_data = ""
   keyw_tabl = ""
   do while ( stmt_keys \= "" )
      keyw_name = $keyw(stmt_keys)
      if keyw_name = "$" then do
         posn_coun = posn_coun + 1
         keyw_name = "POSIT" || posn_coun
      end

      interpret  stmt_oper"."keyw_name "= '"keyw_data"' "
      keyw_coun = keyw_coun + 1
      keyw_tabl = keyw_tabl stmt_oper"."keyw_name
   end

   say "*******" ">>>>>"stmt_oper"<<<<<"
   if stmt_oper = "JOB" then do
      jobname = stmt_name
   end

   if stmt_oper = "EXEC" then do
      stepname = stmt_name
      if symbol("exec.proc") = "LIT" then do
         exec.proc = exec.posit1
         keyw_tabl = keyw_tabl "EXEC.PROC"
         drop exec.posit1
     end
   end

   vv = keyw_tabl
   do i = 1 to words(vv)
      v = word(vv, i)
      if symbol(v) = "VAR" then ,
         say left(v, 20) value(v)
   end
   stmt_name = ""; stmt_oper = ""; stmt_keys = ""

end

if  ( _ack = 1 ) then do
    zedsmsg = left(_cmd,8)"- Ended"
    zedlmsg = left(_cmd,8)"- Ended"
    call $ispex "SETMSG MSG(ISRZ001) "
end
Exit 0

/* */
$tsoex:
   tso_0tr = trace("O")
   Address TSO arg(1)
   tso_0rc = rc
   trace value(tso_0tr)
   return tso_0rc

/* */
$ispex:
   isp_tr = trace("O")
   Address ISPEXEC arg(1)
   isp_rc = rc
   trace value(isp_tr)
   return isp_rc

/* */
$isred:
   isr_tr = trace("O")
   Address ISREDIT arg(1)
   isr_rc = rc
   trace value(isr_tr)
   return isr_rc

/* */
$Scan:Procedure expose   apostr ampsnd ,
                  stmt_name ,
                  stmt_oper ,
                  stmt_keys
   buff = arg(1)

   p =  pos("PARM.",buff)
   if p \= 0 then ,
      buff = overlay("PARM^",buff,p,5)
   if stmt_name = "" then do
      if substr(buff,3,1) = " " then do
         stmt_name = "NONAME"
         buff = strip(substr(buff,3))
      end
      else do
         stmt_name = strip(word(substr(buff,3),1))
         buff = strip(substr(buff,3))
         buff = strip(delword(buff,1,1))
      end
      stmt_oper = word(buff,1)
      buff = strip(delword(buff,1,1)) || " "
   end
   else do
      buff = strip(substr(buff,3)) || " "
   end

   _b  = 1
   _a  = pos(apostr,buff)
   do while ( _a > 0 )
      _b = _a
      _a  = pos(apostr,buff,_b+1)
   end

   _b = pos(" ",buff,_b+1)
   buff = strip(substr(buff,1,_b))

   stmt_keys = stmt_keys || buff
   if right(stmt_keys, 1) = "," then ,
      return 1
   else
      return 0

return -99

/* */
$Keyw:Procedure   Expose   ampsnd apostr ,
                  stmt_keys ,
                  keyw_data

   buff = Arg(1)
   Select
      When Left(buff,1) = apostr | ,
         Left(buff,1) = "("    Then do
         l_kwrd = 0
         i_parm = 1
         l_Skip = 1
         keyw   = "$"
      end
      When Pos("=",buff)  =  0 | ,
         Pos("=",buff) <>  0 & ,
         Pos(",",buff)  <  Pos("=",buff) Then do
         l_kwrd = 0
         i_parm = 1
         l_Skip = 1
         keyw   = "$"
      end
      Otherwise do
         l_kwrd = Pos("=",buff) - 1
         i_parm = Pos("=",buff) + 1
         l_Skip = 1
         keyw = Left(buff,l_kwrd)
      end
   end
   Select
      When Substr(buff,i_parm,1) = "(" Then do
         z_parm = Pos(")",buff,i_parm+1)
         i_Skip = Pos("(",buff,i_parm+1)
         do while (i_Skip <> 0 & ,
                  i_Skip  < z_parm)
            z_parm = Pos(")",buff,z_parm+1)
            i_Skip = Pos("(",buff,i_skip+1)
         end
         l_parm = z_parm - i_parm + 1
      end
      When Substr(buff,i_parm,1) = apostr Then do
         z_parm = Pos(apostr,buff,i_parm+1)
         do while Substr(buff,z_parm+1,1) = apostr
            z_parm = Pos(apostr,buff,z_parm+2)
         end
         l_parm = z_parm - i_parm + 1
      end
      Otherwise do
         z_parm = Pos(",",buff,i_parm) - 1
         l_parm = z_parm - i_parm + 1
      end
   end
   keyw_data = Substr(buff,i_parm,l_parm)
   stmt_keys = Delstr(buff,1,z_parm+l_Skip)
   Return keyw


which when run against
 ****** ***************************** Top of Data ******************************
 000001 //    EXEC SOMEPROC,PARM1=AAAA,PARM2=BBBBB
 000002 //    EXEC PROC=SOMEOTHR,ZQW12LOP=WWWWWW,QWQWQ=KKKKK
 000003 //    EXEC PROC=OTHROTHR,ZQW12LOP=WWWWWW,QWQWQ=KKKKK,
 000004 //   QQQQQQQQ=WWWWWW,XXXXX=KKKKK
 ****** **************************** Bottom of Data ****************************


will return
 ******* >>>>>EXEC<<<<<
 EXEC.PARM1           AAAA
 EXEC.PARM2           BBBBB
 EXEC.PROC            SOMEPROC
 ******* >>>>>EXEC<<<<<
 EXEC.PROC            SOMEOTHR
 EXEC.ZQW12LOP        WWWWWW
 EXEC.QWQWQ           KKKKK
 ******* >>>>>EXEC<<<<<
 EXEC.PROC            OTHROTHR
 EXEC.ZQW12LOP        WWWWWW
 EXEC.QWQWQ           KKKKK
 EXEC.QQQQQQQQ        WWWWWW
 EXEC.XXXXX           KKKKK
 ***


frankly You are trying to eat a sandwich too big for Your mouth :geek:


If you help me we can do it in phases and finish it..


what kind of help do You expect ...
more code lines for each phase
so that at the end You have been sitting doing nothing
and I have written the tool for You
:evil: