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

NEAT command counterpart in REXX


IBM Mainframe Forums -> CLIST & REXX
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
darkstar13

New User


Joined: 06 Nov 2008
Posts: 46
Location: Manila, Philippines

PostPosted: Fri Jul 24, 2009 4:31 am
Reply with quote

Hi all,
I am not sure if the NEAT command is our system specific macro, but i'll just explain it anyway..
If I issue the NEAT command in EDIT mode in a PROC, what it will do is substitute all the symbolics in the proc.

Before NEAT
Code:
//PBC1BKPM PROC PR1=,                                               
//         PR2=,                                                   
//         OUTY=Y,                                                 
//         OUTN='*',                                               
//         GDGOUT1='(+1)'                                           
//******************************************************************
//***  PROCEDURE      : PBC1BKPM                                 ***
//******************************************************************
//***                STEP010  -  SORT                            ***
//******************************************************************
//STEP010 EXEC PGM=SORT,COND=(0,NE),REGION=4096K                   
//SYSOUT   DD  SYSOUT=&OUTN                                         
//SYSUDUMP DD  SYSOUT=&OUTY                                         
//SORTIN   DD  DSN=&PR1.BSC.PBC6838M.SRTD.SUMOP,                   
//         DISP=SHR                                                 
//SORTOF01 DD  DSN=&PR2.BKUP.PBC1BKPM.BBC838.SUMOP&GDGOUT1,         


after NEAT

Code:
//PBC1BKPM PROC                                                     
//******************************************************************
//***  PROCEDURE      : PBC1BKPM                                 ***
//******************************************************************
//***                STEP010  -  SORT                            ***
//******************************************************************
//STEP010 EXEC PGM=SORT,COND=(0,NE),REGION=4096K                   
//SYSOUT   DD   SYSOUT=*                                           
//SYSUDUMP DD   SYSOUT=Y                                           
//SORTIN   DD   DSN=BSC.PBC6838M.SRTD.SUMOP,                       
//             DISP=SHR                                             
//SORTOF01 DD   DSN=BKUP.PBC1BKPM.BBC838.SUMOP(+1),                 
//             UNIT=VTAPE1,VOL=(,RETAIN,,99),                       


My question is, how do I invoke NEAT in REXX (if there is a way to do that)?

My ultimate goal is this:
Create a REXX program to get a JCLCARD member and use this values to override the symbolics in the proc. The output is like what NEAT command does, with the overrides in the JCLCARD applied.

Thanks.
Back to top
View user's profile Send private message
MBabu

Active User


Joined: 03 Aug 2008
Posts: 400
Location: Mumbai

PostPosted: Fri Jul 24, 2009 7:06 am
Reply with quote

NEAT is probably a local macro written in Rexx so you can start the editor calling a macro that then calls NEAT. For example, a macro called CALLNEAT might be
Code:
ISREDIT MACRO
ISREDIT NEAT
ISREDIT END
and be called by
Code:
ISPEXEC EDIT DATASET(data-set-name) MACRO(CALLNEAT)


To see if it is a local macro type TSO ISRDDN M(NEAT) and see if it is in a site or vendor library then browse it. Vendor code will usually have a copyright statement in it, local tools usually do not. (General rule, there are many exceptions!)
Back to top
View user's profile Send private message
darkstar13

New User


Joined: 06 Nov 2008
Posts: 46
Location: Manila, Philippines

PostPosted: Fri Jul 24, 2009 7:29 am
Reply with quote

i have search through the librarues and found out that NEAT is a macro that calls another macro...

Thanks for your reply.
It gave me new idea how to write my program in a simpler way.
1. Get JCLCARD name from user
2. read the JCLCARD and locate the PROCNAME
3. continue reading while putting all overrides in a datastack
4. read the procname and insert the datastack into the procedure
5. remove the symbolics in the proc (by matching? sort then remove dups?)
6. exec NEAT macro.

I am now wondering how will I do #5..
Any ideas?

Thanks again, I really appreciate the reply, as this is just my 2nd REXX program to write.
Back to top
View user's profile Send private message
Pedro

Global Moderator


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

PostPosted: Fri Jul 24, 2009 9:15 am
Reply with quote

The way you described it, I thought NEAT did #4 and #5 already. You just have to call NEAT the way MBabu described it.

Suggestion: use VIEW instead of EDIT. Or maybe copy to a temp dataset before changing the contents.
Back to top
View user's profile Send private message
darkstar13

New User


Joined: 06 Nov 2008
Posts: 46
Location: Manila, Philippines

PostPosted: Fri Jul 24, 2009 9:46 am
Reply with quote

NEAT cannot "NEAT" the procedure successfully if there are duplicate symbolics.

What I want to do is replace the proc symbolics with JCLCARD overrides
then issue NEAT.

YEs, I will copy the proc entries to a temp dataset first.
Thanks for the reminder. icon_biggrin.gif
Back to top
View user's profile Send private message
Pedro

Global Moderator


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

PostPosted: Fri Jul 24, 2009 9:19 pm
Reply with quote

I suggest:

1. parsing the PROC statement to find the variables and their values.
2. execute as variable assignments in rexx
3. remove the PEND statement
4. pass the rest of the proc through ISPF file tailoring to resolve the variables
Back to top
View user's profile Send private message
darkstar13

New User


Joined: 06 Nov 2008
Posts: 46
Location: Manila, Philippines

PostPosted: Mon Jul 27, 2009 7:01 am
Reply with quote

Hi all,
So far, I have managed to put the JCL card overrides and the proc contents in one file.
Do you have any sugegstions how I can overwrite the proc defaults with the jcl card overrides?
Code:
000001 //PBC1761D EXEC PBC0761G,               <== JCLCARD OVERRIDES
000002 //         JOBNMOT='PBC1761D',          <== JCLCARD OVERRIDES
000003 //         JOBNMIN1='PBC1350D',         <== JCLCARD OVERRIDES
000004 //         JOBNMIN2='PBC0837D',         <== JCLCARD OVERRIDES
000005 //         VSAMCRD1='BTCHDTSS',         <== JCLCARD OVERRIDES
000006 //         VSAMCRD2='BTCHNGNS',         <== JCLCARD OVERRIDES
000007 //         VSAMCRD3='BTCHNGRS'          <== JCLCARD OVERRIDES
000008 //PBC0761G PROC PR1=,                                         
000009 //         PR2=,                                             
- - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 21 Line(s) not
000031 //         JOBNMOT='PBC0761D',          <== PROC DEFAULTS     
000032 //         JOBNMIN1='PBC0350D',         <== PROC DEFAULTS     
000033 //         JOBNMIN2='PBC0013D',         <== PROC DEFAULTS     
000034 //         VSAMCRD1='BTCHDTST',         <== PROC DEFAULTS     
000035 //         VSAMCRD2='BTCHNGNT',         <== PROC DEFAULTS     
000036 //         VSAMCRD3='BTCHNGRT',         <== PROC DEFAULTS     
Back to top
View user's profile Send private message
Pedro

Global Moderator


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

PostPosted: Mon Jul 27, 2009 9:09 am
Reply with quote

repeating:

I suggest:

1. parsing the PROC statement to find the variables and their values.
2. execute as variable assignments in rexx
3. remove the PEND statement
4. pass the rest of the proc through ISPF file tailoring to resolve the variables
Back to top
View user's profile Send private message
darkstar13

New User


Joined: 06 Nov 2008
Posts: 46
Location: Manila, Philippines

PostPosted: Mon Jul 27, 2009 11:25 am
Reply with quote

Thanks for the suggestions, Pedro
I am now able to generate the proc (with the jclcard overrides properly substituted) that is ready to be 'NEAT'-ed.

I am now just having trouble figuring out how can i resolve the lack or the presence of a comma delimeter..

For example:
Jobcard:
Code:
//XBC1761D JOB (XXX,XXX,XXXX),'XBC1761D',CLASS=T,     
//         MSGCLASS=N                                 
/*JOBPARM  P=PROC09                                   
//XBC1761D EXEC XBC0761G,                             
//         JOBNMOT='XBC1761D',                       
//         JOBNMIN1='XBC1350D',                       
//         JOBNMIN2='XBC0837D',                       
//         VSAMCRD1='XXXXDTSS',                       
//         VSAMCRD2='XXXXNGNS',                       
//         VSAMCRD3='XXXXNGRS'                       


My proc (proc body not shown):
Code:
//XBC0761G PROC PR1=,                                                 
//         PR2=,                                                       
//         OUTY='Y',                                                   
//         OUTN='*',                                                   
//         LIB='PROD',                 TEST / 'QA'                     
//         SYSTEM=DB2P,                                               
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 17 Line(s) not Displayed
//         JOBNMOT='XBC0761D',                                         
//         JOBNMIN1='XBC0350D',                                       
//         JOBNMIN2='XBC0013D',                                       
//         VSAMCRD1='XXXXDTST',                                       
//         VSAMCRD2='XXXXNGNT',                                       
//         VSAMCRD3='XXXXNGRT',                                       
//         CONDXFRM='(4095,GT)'                                       
//******************************************************************   
//***  PROCEDURE      : XBC0761G                                 ***   


Resulting file from my REXX is:

Code:
//XBC1761D PROC PR1=,                                               
//         PR2=,                                                     
//         OUTY='Y',                                                 
//         OUTN='*',                                                 
//         LIB='PROD',                 TEST / 'QA'                   
//         SYSTEM=DB2P,                                             
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 17 Line(s) not Display
//         JOBNMOT='XBC1761D',                                       
//         JOBNMIN1='XBC1350D',                                     
//         JOBNMIN2='XBC0837D',                                     
//         VSAMCRD1='XXXXDTSS',                                     
//         VSAMCRD2='XXXXNGNS',                                     
//         VSAMCRD3='XXXXNGRS'                                       
//         CONDXFRM='(4095,GT)'                                     
//******************************************************************
//***  PROCEDURE      : XBC0761G                                 ***


The problem is that since VSAMCRD3 is the last override in the jclcard and i am using the entire line of the jclcard to replace a line in the proc if the symbolics are equal, i end up not having a comma on VSAMCRD3...
I don't know if it's a good idea to think meticulously and come up with additional code to put a comma at the end of each symbolic, except on the last one..
any ideas?
Thanks..
Back to top
View user's profile Send private message
prino

Senior Member


Joined: 07 Feb 2009
Posts: 1306
Location: Vilnius, Lithuania

PostPosted: Mon Jul 27, 2009 11:46 am
Reply with quote

REXX has a builtin function called STRIP. Read about it.
Back to top
View user's profile Send private message
darkstar13

New User


Joined: 06 Nov 2008
Posts: 46
Location: Manila, Philippines

PostPosted: Tue Jul 28, 2009 10:26 am
Reply with quote

Thanks prino.
I have used STRIP to remove the comma on the last symbolic.
I added a logic to insert a comma at the end of all jclcard lines.

Thanks for all your help.
I am posting the program here.
Sorry if there's a lot of finetuning here...
This is my 2nd program, and I am happy to be learning more.
Code:
/*  REXX               */                /*  created 2009-07-28 */
/*--------------------------------------------------------------*/
/*     This program creates a test job from input JCLCARD       */
/*     Output file is :   <userid>.<jobname>.SUBSTJOB           */
/*--------------------------------------------------------------*/
/*    To invoke this program, issue : TSO CRJOB <jobname>       */
/*--------------------------------------------------------------*/
 ARG jclcard
 Messg_Enable_Sw = MSG(OFF)
/**----------------------**/
/** Start of the program **/
/**----------------------**/
 say_on = 0

/* if no argument has been passed, retry    */
 IF jclcard = '' THEN say_on = 1
/* retries getting jclcard from user        */
 CALL ACCEPT_JCLCARD
/* verify output file if ok to create       */
 CALL ALLOC_OUTFLE
/* main process                             */
 CALL PROCESS_JCLCARD
/* write output file                        */
 CALL WRITE_SUBSTJOB
 EXIT
/**----------------------------------------------------------------*/
 ACCEPT_JCLCARD:
 DO FOREVER
   IF say_on = 1 THEN
      DO
        SAY 'Please enter JCLCARD member...'
        PULL jclcard
      END
   IF jclcard = 'EXIT' ³ jclcard = 'CANCEL' ³ ,
      jclcard = 'exit' ³ jclcard = 'cancel' THEN LEAVE

   cardmem = "'" ³³ 'XXXX.XXX.JCLCARD(' ³³ jclcard ³³ ")'"

   sysdsn_msg = SYSDSN(cardmem)
   IF sysdsn_msg = 'OK' THEN LEAVE
   ELSE DO
          SAY sysdsn_msg
          say_on = 1
        END
 END
 RETURN
/**----------------------------------------------------------------*/
 ALLOC_OUTFLE:
 outproc = "'" ³³ USERID() ³³ "." ³³ jclcard ³³ "." ³³ ,
           "SUBSTJOB" ³³ "'"
/* verifies if file already exists */
 DS_Exist = SYSDSN(outproc)
 IF DS_Exist = "OK" THEN DO
    SAY 'Dataset ' outproc 'has been allocated '³³,
        'and will now be deleted...'
    "DELETE "outproc" PURGE"
    IF RC = 0  THEN DO
       SAY 'Dataset ' outproc 'deleted'
       END
    ELSE DO
       SAY 'Error deleting' outproc ', cannot continue. '
       SAY "Pls. check if it's currently open or being used.."
       LEAVE
    END
 END
/* allocates output file   */
 "ALLOCATE DATASET("outproc") SHR NEW
  SPACE(30,10) TRACKS RELEASE
  DSORG(PS) LRECL(80) RECFM(F B)"
 IF RC ª= 0 THEN DO
    SAY 'Error allocating output file ' outproc '. RC=20'
    EXIT
 END
 RETURN
/**----------------------------------------------------------------*/
 PROCESS_JCLCARD:
/**----------------------------------------------------------------*/
/* allocates input JCLCARD for reading */
 CALL ALLOC_INCARD
/* logic that reads jclcard member  */
 sysdsn_msg1 = SYSDSN(cardmem)
 IF sysdsn_msg1 = 'OK' THEN
    DO
      SAY 'Reading ' cardmem ' for procname...'
      /* this read will start on the 4th line to get the proc name */
      /* it will finish reading at the 4th line as well            */
      CALL GET_PROC_NME
      /* it now read the procname found from jclcard  */
      CALL READ_PROC
    END
 SAY 'Overrides of ' cardmem ' has been copied to ' outproc
 RETURN
/**----------------------------------------------------------------*/
 GET_PROC_NME:
 proc_found = 'NO'
 "EXECIO 1 DISKR INJCL 4 "
 PARSE PULL exec_ln
 excol = INDEX(exec_ln,'EXEC')
 IF SUBSTR(exec_ln,excol,4) = 'EXEC' THEN
    DO
      proc_found = 'YES'
      procnme = SUBSTR(exec_ln,excol + 5,8)
      SAY 'Procedure ' procnme ' found in JCLCARD.'
    END
 RETURN
/**----------------------------------------------------------------*/
 READ_PROC:
 IF proc_found = 'YES' THEN
    DO
    procdsn = "'" ³³ 'XXXX.XXX.PROCLIB(' ³³ procnme ³³ ")'"
    /* checks if proc member exists */
    sysdsn_msg = SYSDSN(procdsn)
    IF sysdsn_msg = 'OK' THEN
       DO
          search_ovr = 'YES'
          CALL ALLOC_INPROC
          /* this will read proc overrides and stores them */
          CALL READ_JCLCARD
          SAY 'Reading ' procdsn
          /* writes the first line of the procedure using jclcard */
          Write_line.1  = '//' ³³ jclcard  ³³ ' PROC PR1=, '
          /* starts reading at line #2 */
          proc_lctr  = 2
          end_of_symb = 'NO'
          /* initial read of procedure                       */
          "EXECIO 1 DISKR INPROC 2"
          PULL procline
          /* this loop if for processing symbolics           */
          CALL PROCESS_SYMBS
          /* this will remove the comma on the last symbolic */
          CALL REMOVE_COMMA
          /* this loop if for copying the procedure body     */
          CALL COPY_PROC
          /* this will close the proc file                   */
          "EXECIO 0 DISKR INPROC (FINIS"
       END
    END
 RETURN
/**----------------------------------------------------------------*/
 ALLOC_INCARD:
    /* allocates input proc for reading */
 "ALLOCATE FILE(INJCL) DATASET("cardmem") SHR REUSE"
 IF RC ª= 0 THEN
    DO
      SAY 'Error opening ' cardmem ' for reading. RC=30'
      EXIT
    END
 RETURN
/**----------------------------------------------------------------*/
 ALLOC_INPROC:
    /* allocates input proc for reading */
 "ALLOCATE FILE(INPROC) DATASET("procdsn") SHR REUSE"
 IF RC ª= 0 THEN
    DO
      SAY 'Error opening ' procdsn ' for reading. RC=30'
      EXIT
    END
 RETURN
/**----------------------------------------------------------------*/
 READ_JCLCARD:
 jcl_lctr = 0
 /* reads and stores overrides until end of jclcard file            */
 "EXECIO 1 DISKR INJCL"
 DO WHILE RC = 0
    PARSE PULL jcl_line
    jcl_lctr = jcl_lctr + 1
    jclsym_val.jcl_lctr = jcl_line
    /*                 //  symbolic       =  override       */
    PARSE VAR jcl_line . jclsym.jcl_lctr '=' jclval.jcl_lctr
    /*  we get the column of the last byte of the override  */
    comma_col = LENGTH(SPACE(jclval.jcl_lctr))
    /*  if last column is not comma, insert a comma         */
    IF SUBSTR(jclval.jcl_lctr,comma_col,1) ª= ',' THEN
       jclval.jcl_lctr = INSERT(",",jclval.jcl_lctr,comma_col)
    /*  read another line of the jclcard                    */
    "EXECIO 1 DISKR INJCL"
 END
 SAY 'There are '  jcl_lctr ' overrides in ' jclcard
 RETURN
/**----------------------------------------------------------------*/
 PROCESS_SYMBS:
 DO UNTIL end_of_symb = 'YES'
    /* this will retrieve stored overrides and substitute */
    /* overrides if values match a proc symbolics         */
    CALL SUBST_OVRRD
    /* read another line                                  */
    "EXECIO 1 DISKR INPROC"
    PULL procline
    proc_lctr = proc_lctr + 1
    IF SUBSTR(procline,3,10) = '**********'
       THEN end_of_symb = 'YES'
 END
 RETURN
/**----------------------------------------------------------------*/
 REMOVE_COMMA:
 last_sym_ctr = proc_lctr - 1
 Write_Last_Sym = STRIP(Write_Line.last_sym_ctr,'T',",")
 Write_Line.last_sym_ctr = Write_Last_Sym
 RETURN
/**----------------------------------------------------------------*/
 COPY_PROC:
 DO WHILE RC = 0
    Write_Line.proc_lctr  = procline
    "EXECIO 1 DISKR INPROC"
    PULL procline
    proc_lctr = proc_lctr + 1
 END
 RETURN
/**----------------------------------------------------------------*/
 SUBST_OVRRD:
 loop_ctr = 1
 ovrrd_found = 'NO'
 /* this will search the overrides array for values */
 PARSE VAR procline . procsym.proc_lctr '=' .
 PARSE VAR procline procsubln   '='
 DO UNTIL loop_ctr > jcl_lctr
    IF procsym.proc_lctr  = jclsym.loop_ctr THEN
       DO
       ovrrd_found = 'YES'
       Write_Line.proc_lctr = procsubln ³³ '=' ³³ jclval.loop_ctr
       END
    loop_ctr = loop_ctr + 1
 END
 IF ovrrd_found = 'NO' THEN
    Write_Line.proc_lctr  = procline
 RETURN
/**----------------------------------------------------------------*/
 WRITE_SUBSTJOB:
 /* frees input jclcard */
 /* frees input proc    */
 "FREE FILE(INJCL INPROC)"
 /* frees output file   */
 "ALLOC DS("outproc") DD(OUTFLE) SHR"
 "EXECIO * DISKW OUTFLE (STEM Write_Line. FINIS"
 "FREE F(OUTFLE)"
 "FREE DATASET("outproc")"
 SAY 'Output  dataset  ' outproc 'created'
 ADDRESS ISPEXEC "EDIT DATASET("outproc")"
 RETURN
/**----------------------------------------------------------------*/
Back to top
View user's profile Send private message
darkstar13

New User


Joined: 06 Nov 2008
Posts: 46
Location: Manila, Philippines

PostPosted: Tue Jul 28, 2009 11:16 am
Reply with quote

Note that:
Code:
/*----------------------------------------------------------------*/
/* This will work only if the following assumptions are satisfied */
/* (1) The JCLCARD is in XXXX.XXX.JCLCARD                         */
/* (2) The PROC NAME found in the JCLCARD satisfies the ff:       */
/*     (a) The PROC is in XXXX.XXX.PROCLIB                        */
/*     (b) The PROC uses PR1 symbolic in the first line           */
/*     (c) The PROC's first  comment line is AT THE END of        */
/*         ALL SYMBOLICS                                          */
/*----------------------------------------------------------------*/


If you'll use it, adjust the codes to allow processing if any of the above is not satisfied
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 -> CLIST & REXX

 


Similar Topics
Topic Forum Replies
No new posts Compile Several JCL JOB Through one r... CLIST & REXX 4
No new posts RACF - Rebuild SETROPTS command which... All Other Mainframe Topics 3
No new posts Running REXX through JOB CLIST & REXX 13
No new posts Error to read log with rexx CLIST & REXX 11
No new posts isfline didnt work in rexx at z/OS ve... CLIST & REXX 7
Search our Forums:

Back to Top