diff --git a/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/CONSOLID.rex b/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/CONSOLID.rex new file mode 100644 index 0000000..5dc77e7 --- /dev/null +++ b/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/CONSOLID.rex @@ -0,0 +1,167 @@ +/* REXX */ +/* CONTROL NOMSG NOSYMLIST NOCONLIST NOLIST NOPROMPT */ + ADDRESS ISPEXEC " CONTROL RETURN ERRORS " ; +/* ARG selectProcessor */ + TRACE oFF + /* set myPrefix to a HLQ for work dataset names */ + myPrefix = USERID() + /* name one processor to compare to all others */ + selectProcessor = 'GCBL' + /*select a processor step 4 SUPER comparisons */ + selectStep = 'COMPILE' + /* if your site requires a VOLUME on allocations, include 1 here */ + volume = '' + UseVolume ='TSOE32' + If Length(UseVolume) > 2 then, + volume = "VOLUME("UseVolume")" +/* Name Dataset that contains the processors to be compared */ + Dataset = myPrefix'.PROCESS.PROCESSR' ; + Dataset = 'YOURSITE.NDVR.TEAM.PROCESS.COBOL' + NEWDD = Dataset ; + OldDD = Dataset ; + Listings =myPrefix'.SUPERC.'selectProcessor'.SAVELIST' ; + UPDATES =myPrefix'.SUPERC.'selectProcessor'.UPDATES' ; + Skeletons = myPrefix'.ENDEVOR.SKELS' ; +/* */ + Listings =myPrefix'.SUPERC.'selectProcessor'.SAVELIST' ; + UPDATES =myPrefix'.SUPERC.'selectProcessor'.UPDATES' ; + Skeletons = myPrefix'.TEAM.MODELS' + Skeletons = 'YOURSITE.YOUR.NDVR.NODES1.ISPS' +/* name the macro that parses the steps of a processor */ + MACRO = 'SUPCSOUT'; + ADDRESS ISPEXEC, + "LIBDEF ISPSLIB Dataset ID('"Skeletons"') COND STACK" ; , +/* */ + Call Allocate_Files ; +/* */ +/* COMPARE ALL MEMBERS OF PROCESSOR LIBRARY WITH MEMBER SPECIFIED BY */ +/* ARG. GET STEPS FOR EACH PROCESSOR TOO. */ +/* */ + List_Processors = " "; + Call Compare_Processors ; +/* */ +/* COMPARE ALL STEPS OF ARG PROCESSOR WITH SAME-NAMED STEPS IN OTHERS */ +/* */ + Call Compare_Processor_Steps + EXIT ; +Compare_Processors: +/* */ +/* List processors (members) in the named dataset */ + TEMP = LISTDSI("'"Dataset"'" RECALL); + ADDRESS ISPEXEC " LMINIT DATAID(MYPDS1) Dataset('"Dataset"') " ; + ADDRESS ISPEXEC " LMOPEN DATAID("MYPDS1") OPTION(INPUT) " ; + RtCode = 0 ; + Do While RtCode = 0 + ADDRESS ISPEXEC " LMMLIST DATAID("MYPDS1") OPTION(LIST) ", + "MEMBER(MYMBR) STATS(NO) " ; + RtCode = RC ; + IF RtCode = 0 THEN , + Do + MYMBR = STRIP(MYMBR) ; + SA= 'PROCESSING FOR *'MYMBR'*' ; + List_Processors = List_Processors MYMBR ; + StepDSN =myPrefix'.SUPERC.'MYMBR'.STEPS' ; + DSNCHECK = SYSDSN("'"StepDSN"'") ; + IF DSNCHECK /= OK THEN, + Do + SA= 'ALLOCATING ' StepDSN ; + ADDRESS TSO "ALLOC DA('"StepDSN"') ", + " LRECL(080) BLKSIZE(32000) SPACE(10,10) ", + " DIR(15) DSNTYPE(LIBRARY) ", + " SPACE(10,10) RECFM(F B) CYLINDERS DSORG(PO) ", + " NEW CATALOG REUSE" volume + ADDRESS TSO "FREE DA('"StepDSN"')" ; + End /* IF DSNCHECK /= OK THEN */ + Input_DSN = Dataset ; + Input_DSN = Input_DSN'('MYMBR')' ; + "ALLOCATE F(PROCESSB) DA('"Input_DSN"') SHR REUSE " ; + "EXECIO * DISKR PROCESSB (STEM PROCESSR. FINIS " ; + ADDRESS TSO "FREE F(PROCESSB) " ; + NEWDSN = StepDSN'('MYMBR')' ; + "ALLOCATE F(NEW#MBR) DA('"NEWDSN"') SHR REUSE " ; + "EXECIO * DISKW NEW#MBR (STEM PROCESSR. FINIS " ; + ADDRESS TSO "FREE F(NEW#MBR) " ; + "ALLOCATE DA('"NEWDSN"') OLD REUSE " ; + DROP PROCESSR. ; + SAY 'Creating members from STEPS of' MYMBR; + "ISPEXEC EDIT Dataset('"NEWDSN"')", + "MACRO("MACRO")" ; + ADDRESS TSO "FREE DA('"NEWDSN"')" ; + SA= 'RUNNING SUPERC FOR' selectProcessor 'AND' MYMBR; + /* if you want whole processor comparisons, uncomment */ + /* Call Do_Superc ; */ + END ; /* IF RtCode */ + END; /* Do While ... */ +/* */ + ADDRESS ISPEXEC " LMCLOSE DATAID(MYPDS1) "; + RETURN +Allocate_Files: + DSNCHECK = SYSDSN("'"Listings"'") ; + IF DSNCHECK /= OK THEN, + Do + ADDRESS TSO "ALLOC DA('"Listings"') BLKSIZE(13300) ", + "CYLINDERS ", + "LRECL(133) RECFM(F B) ", + " DIR(15) DSNTYPE(LIBRARY) ", + " SPACE(10,10) RECFM(F B) CYLINDERS DSORG(PO) ", + " NEW CATALOG REUSE" volume + ADDRESS TSO "FREE DA('"Listings"')" ; + SA= 'ALLOCATING ' Listings ; + END; + DSNCHECK = SYSDSN("'"UPDATES"'") ; + IF DSNCHECK /= OK THEN, + Do + ADDRESS TSO "ALLOC DA('"UPDATES"') ", + " LRECL(080) BLKSIZE(32000) SPACE(10,10) ", + " DIR(15) DSNTYPE(LIBRARY) ", + " SPACE(10,10) RECFM(F B) CYLINDERS DSORG(PO) ", + " NEW CATALOG REUSE" volume + ADDRESS TSO "FREE DA('"UPDATES"')" ; + SA= 'ALLOCATING ' UPDATES ; + END; + RETURN ; +Do_Superc: + ADDRESS ISPEXEC "FTOPEN TEMP" + ADDRESS ISPEXEC "FTINCL CONSOLSK" + ADDRESS ISPEXEC "FTCLOSE " ; + ADDRESS ISPEXEC "VGET (ZUSER ZTEMPF ZTEMPN) ASIS" ; + Debug = 'YES' ; + Debug = 'NAW' ; + X = OUTTRAP("OFF") + IF Debug = 'YES' THEN, + Do + Trace ?R + ADDRESS ISPEXEC "LMINIT DATAID(DDID) DDNAME(&ZTEMPN)" + ADDRESS ISPEXEC "EDIT DATAID(&DDID)" + ADDRESS ISPEXEC "LMFREE DATAID(&DDID)" + END; + ELSE, + ADDRESS TSO "SUBMIT '"ZTEMPF"'" ; + RETURN ; +Compare_Processor_Steps: + /* Go though the members in your processor dataset again */ + /* and compare the selectStep with the one in selectprocessor */ + sa = 'Compare_Processor_Steps' + Do mbr# = 1 to Words(List_Processors) + MYMBR = Word(List_Processors,mbr#) + OLDDD = myPrefix'.SUPERC.'MYMBR'.STEPS' ; + Listings = myPrefix'.SUPERC.'selectStep'.SAVLIST' ; + DSNCHECK = SYSDSN("'"Listings"'") ; + IF DSNCHECK /= OK THEN, + Do + SA= 'ALLOCATING ' Listings ; + ADDRESS TSO "ALLOC DA('"Listings"') BLKSIZE(13300) ", + "CYLINDERS ", + "LRECL(133) RECFM(F B) ", + " DIR(15) DSNTYPE(LIBRARY) ", + " SPACE(10,10) RECFM(F B) CYLINDERS DSORG(PO) ", + " NEW CATALOG REUSE" volume + ADDRESS TSO "FREE DA('"Listings"')" ; + END; + NEWDD = myPrefix'.SUPERC.'selectProcessor'.STEPS' ; + NEWMBR = selectStep + OLDMBR = selectStep + SA= 'PROCESSING FOR *'MYMBR'*' ; + Call Do_Superc + END; /* Do mbr# = 1 to Words(List_Processors) */ + RETURN diff --git a/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/CONSOLSK.skel b/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/CONSOLSK.skel new file mode 100644 index 0000000..423cead --- /dev/null +++ b/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/CONSOLSK.skel @@ -0,0 +1,30 @@ +//CONSOLID JOB (0000), +// CLASS=A,MSGCLASS=X,REGION=4M, +// NOTIFY=&SYSUID +//*==================================================================* +//SUPERC EXEC PGM=ISRSUPC, *0004 +// PARM=(LONGL,LINECMP, 0005 +// 'UPDSEQ0', 0006 +// '') 0007 +//NEWDD DD DSN=&NEWDD(&NEWMBR), 0008 +// DISP=SHR 0009 +//OLDDD DD DSN=&OLDDD(&OLDMBR), 0010 +// DISP=SHR 0011 +//OUTDD DD DSN=&LISTINGS(&MYMBR), 0028 +// DISP=SHR 0028 +//DELDD DD DSN=&&&&DELTA, 0015 +// DISP=(NEW,PASS),UNIT=3390, 0015 +// DCB=(LRECL=80,BLKSIZE=13680), 0016 +// SPACE=(13680,(15,30),RLSE) 0017 +//* 0018 +//*==================================================================* +//*= (optionally save the SUPERC "delta")============================* +//*==================================================================* +//SAVDLTA EXEC PGM=IEBGENER,COND=(0,LE) 0019 +//SYSPRINT DD DUMMY 0020 +//SYSUT1 DD DSN=&&&&DELTA, 0021 +// DISP=(SHR,DELETE) 0021 +//SYSUT2 DD DSN=&UPDATES(&MYMBR), 0022 +// DISP=SHR 0022 +//SYSIN DD DUMMY 0023 +//* 0024 diff --git a/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/ESYMBOLR.rex b/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/ESYMBOLR.rex new file mode 100644 index 0000000..d6db615 --- /dev/null +++ b/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/ESYMBOLR.rex @@ -0,0 +1,46 @@ + /* REXX */ + TRACE Off; + ADDRESS ISPEXEC, + "VGET (ZSCREEN) SHARED" + Table = 'C1SYMBS' || ZSCREEN + ADDRESS ISPEXEC + "TBSTATS "Table" STATUS1(STATUS1) STATUS2(STATUS2)" + /* FOR TABLE STATUS... */ + /* 1 = TABLE EXISTS IN THE TABLE INPUT LIBRARY CHAIN */ + /* 2 = TABLE DOES NOT EXIST IN THE TABLE INPUT LIBRARY CHAIN */ + /* 3 = TABLE INPUT LIBRARY IS NOT ALLOCATED. */ + /* */ + /* 1 = TABLE IS NOT OPEN IN THIS LOGICAL SCREEN */ + /* 2 = TABLE IS OPEN IN NOWRITE MODE IN THIS LOGICAL SCREEN */ + /* 3 = TABLE IS OPEN IN WRITE MODE IN THIS LOGICAL SCREEN */ + /* 4 = TABLE IS OPEN IN SHARED NOWRITE MODE IN THIS LOGICAL SCREEN*/ + /* 5 = TABLE IS OPEN IN SHARED WRITE MODE IN THIS LOGICAL SCREEN. */ + "TBQUERY "Table" KEYS(KEYLIST) NAMES(VARLIST) ROWNUM(ROWNUM)" + IF RC > 0 THEN EXIT + KEYLIST = TRANSLATE(KEYLIST," ","()',"); + VARLIST = TRANSLATE(VARLIST," ","()',"); + VARLIST = Strip(KEYLIST) STRIP(VARLIST); + SA= "KEYLIST=" VARLIST; + VariableCount = Words(VARLIST) ROWNUM + "TBTOP "Table + maxLen = 12 + DO Row# = 1 TO ROWNUM + "TBSKIP "TABLE + tmp = Left(VARSISYM,12) '="' || Strip(VARUSPVA) || '"' + If Length(tmp) > maxLen then maxlen = Length(tmp) + queue tmp + End /* DO Row# = 1 TO ROWNUM */ + Push "Largest_record_size = " maxLen + ADDRESS TSO, + "ALLOC F(TBLSAVE)", + "LRECL(100) BLKSIZE(24000) SPACE(5,5)", + "RECFM(F B) TRACKS ", + "NEW UNCATALOG REUSE " ; + ADDRESS TSO, + "EXECIO" QUEUED() "DISKW TBLSAVE (FINIS" + ADDRESS ISPEXEC "LMINIT DATAID(DDID) DDNAME(TBLSAVE)" + ADDRESS ISPEXEC "VIEW DATAID(&DDID)" + ADDRESS ISPEXEC "LMFREE DATAID(&DDID)" + ADDRESS TSO, + "FREE F(TBLSAVE)" + EXIT ; diff --git a/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/NDVRREPJ.jcl b/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/NDVRREPJ.jcl new file mode 100644 index 0000000..0eba673 --- /dev/null +++ b/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/NDVRREPJ.jcl @@ -0,0 +1,47 @@ +//IBMUSERA JOB (0000), JOB05921 +// 'ENDEVOR JOB',MSGLEVEL=(1,1),CLASS=B,REGION=0M,MSGCLASS=A, +// NOTIFY=&SYSUID +//* RESTART=RUNTEST, +//*==================================================================* +// JCLLIB ORDER=(YOURSITE.NDVR.TEAM.JCL) +// SET TRACE=N T/Y/N/variable-name +//*==================================================================* +//* If a Site Symbol table is inuse at your site, +//* Create a representation of the table in a format like: +//* SYMBOLNAME="value" +//* See the ESYMBOLR.rex member for a method for doing this. +//* Place the results into a dataset(member) for the next step. +//* Something like DSN=YOURSITE.NDVR.TEAM.WRK(ESYMBOLO) +//*----------- +//* Concatenate below it, another input containing variables from +//* one or more processors, in the same format. +//*//*================================================================ +//RUNTEST EXEC PGM=IRXJCL, +// PARM='NDVRREPT &TRACE' +//INPUT DD * < "seed" C1 variables here (only ones necessary) +C1PRGRP = G2345678 +C1SI = P +C1ST = PRD +C1SY = FINAN +C1SU = SSSSS +C1TY = CBL +C1SSTGNUM = 2 +C1SSTAGE = TEST +C1SSTGID = T +C1SSTG = TEST +C1SSTG# = 1 +C1SSUBSYS = A110 +// DD DISP=SHR,DSN=YOURSITE.NDVR.TEAM.WRK(ESYMBOLO) +// DD DISP=SHR,DSN=YOURSITE.NDVR.TEAM.WRK(PSYMBOLS) +// DD * +C1ENVMNT = &C1EN. +C1STGID = &C1SI. +C1STAGE = &C1ST. +C1SYSTEM = &C1SY. +C1SUBSYS = &C1SU. +C1ELTYPE = &C1TY. +//SYSEXEC DD DISP=SHR,DSN=YOURSITE.NDVR.REXX +//REPORT DD SYSOUT=* +//SYSTSIN DD DUMMY +//SYSTSPRT DD SYSOUT=* +//*================================================================ diff --git a/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/NDVRREPT.rex b/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/NDVRREPT.rex new file mode 100644 index 0000000..039a1d4 --- /dev/null +++ b/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/NDVRREPT.rex @@ -0,0 +1,281 @@ +/* REXX */ + /* For references found in the INPUT, repeat the + symbolic substitutions of variables, until further + substitution is impossible. Hopefully, all variables will be + subsituted, but it is possible that variables may be assigned + to other variables for which no value was given */ + ARG TraceV + If TraceV = 'Y' then Trace r + /* Valid Characters for Endevor processor Variables */ + $numbers ='0123456789' + variableChars='ABCDEFGHIJKLMNOPQRSTUVWXYZ@#$?' || $numbers + /* To count the number of periods expected after a variable */ + DotCount. = 1 + "EXECIO * DISKR INPUT (Stem original. Finis" + /* Since later variables may be dependent on earlier + variables, a loop is engaged to repeat substitutions + until all are resolved */ + ResolvedVariables = '' + /* Make up to 25 passes through the inputs */ + /* Some values may depend on others listed lower within */ + /* the inputs. */ + Do pass# = 1 to 25 + StillResolvingVars = 'N' + Say "Starting pass" pass# + /* intermediate values are kept in vars. */ + /* For each pass, step through the inputs to apply + variable->value substitutions */ + Do inp# = 1 to original.0 + If pass# = 1 then vars.inp# = original.inp# + string = Strip(vars.inp#) + If substr(string,1,1) = '*' then Iterate + If Length(TraceV) > 1 then, + If ABBREV(string,TraceV) = 1 then Trace r + Else Trace off + whereEqual = Pos('=',string) + If whereEqual > 0 then, + Do + tempstring = Translate(string," ","=") + thisVariableName = Word(tempstring,1) + thisVariableValue = Strip(Substr(string,whereEqual+1)) + thisVariableValue = Strip(thisVariableValue,"B","'") + thisVariableValue = Strip(thisVariableValue,"B",'"') + string = thisVariableName '=' Strip(thisVariableValue) + End /* If whereEqual > 0 */ + /* look for '&' (ampersand) characters */ + If pass# = 1 & Pos('50'x, string) = 0 then, + say '::: ' string + Else, + If Pos('50'x, string) > 0 then, + Do + string_before = string + Call EndevorVariablesEvaluate + If string /= string_before then, + Do + vars.inp# = Strip(string) + Say thisVariableName 'has this DotCount', + DotCount.thisVariableName + End + End; /*If Pos('50'x, string) > 0 */ + /* If all symbols have been resolved for 1 variable */ + If Pos('50'x, string) = 0 then, + Do + string = vars.inp# + whereEqual = Pos('=',string) + If whereEqual = 0 then iterate + tempstring = Translate(string," ","=") + thisVariableValue=, + Strip(Substr(string,whereEqual+1)) + thisVariableValue= Strip(thisVariableValue,"B","'") + thisVariableValue= Strip(thisVariableValue,"B",'"') + thisVariableValue= Strip(thisVariableValue) + SaveValue.thisVariableName = thisVariableValue + If Wordpos(thisVariableName,ResolvedVariables)=0 then, + ResolvedVariables =, + ResolvedVariables thisVariableName + If Pos("'",thisVariableValue) = 0 then vars.inp# =, + thisVariableName "='" || thisVariableValue || "'" + Else, + If Pos('"',thisVariableValue) = 0 then vars.inp# =, + thisVariableName '="' || thisVariableValue || '"' + Else, + vars.inp# = string + End; /* If Pos('50'x, string) = 0 */ + End; /* Do inp# = 1 to original.0 */ + If StillResolvingVars = 'N' then Leave + End; /* Do pass# = 1 to 50 */ + Say "NDVRREPT- completed" pass# "passes through input data" + "EXECIO * DISKW REPORT (Stem vars. Finis" + exit +EndevorVariablesEvaluate: + say '------------------' + say 'B4: ' string_before + lastSearchPosition = Length(string) + If TraceV = 'T' then Trace Off + noDotsAtEnd = Strip(string,"T",".") + numberOfDots = Length(String) - Length(noDotsAtEnd) + If numberOfDots > 0 then, + Do + DotCount.thisVariableName =, + DotCount.thisVariableName-numberOfDots + String = noDotsAtEnd + End /* If numberOfDots > 0 */ + Do Forever + /* Find last ampersand - replace from back to front */ + sa= string + positionAmper =, + LastPos('50'x,Substr(string,1,lastSearchPosition)) + If positionAmper = 0 then Return + /* Finding a variable preceeded by a double ampersand? */ + If positionAmper > 1 &, + Substr(string,positionAmper-1,2) = '5050'x then, + DoubleAmpersand = 'Y' + Else, + DoubleAmpersand = 'N' + /* Looking at a Site Symbol? (Variable name begins with #) */ + /* Set a length (including the & char) */ + If Substr(string,positionAmper+1,1) = '#' then, + maxVariableLen = 13 + Else + maxVariableLen = 10 + /* Finding a variable name and the variable name length */ + VariableLen#1 = FindVariableNameEnd() + appendVariable =, + Strip(Substr(string,positionAmper+1,VariableLen#1-1)) + appendVariable = Strip(appendVariable) + /* VariableLen#1 have acceptable length ? */ + If VariableLen#1 > (maxVariableLen+1) then, + Do + Say "cannot handle this" Substr(string,positionAmper) + Say " at" Inp# + Say string + Exit 12 + End; /* Else.. */ + /* Is trace requested for this appending variable ? */ + If Length(TraceV) > 1 then, + If ABBREV(appendVariable,TraceV) = 1 then Trace r + /* If appending variable is not yet given a value, + wait for one or more subsequent passes */ + If WordPos(appendVariable,ResolvedVariables) = 0 then, + DO + lastSearchPosition = positionAmper - 1 + Do while lastSearchPosition > 1 &, + Substr(string,lastSearchPosition,1) = '50'x + lastSearchPosition = lastSearchPosition - 1 + End + If pass#=1 | positionAmper=1 |, + lastSearchPosition=1 then, + Return /* come back later */ + Else, /* After 1st pass, try other vars */ + Iterate + End; /* If WordPos(appendVariable,Resolved... */ + /* terminateChar is the character following variable name */ + terminateChar =, + Substr(string || ' ',positionAmper+VariableLen#1,1) + appendValue = SaveValue.appendVariable + /* terminateChar# now the position of character + in string after the variable name*/ + terminateChar# = VariableLen#1 + positionAmper + /* If a '(' appears after the variable name do Substringing */ + SubstringingStatus = 'N/A' /* by Default */ + /* if the character after the variable name is a left paren */ + If terminateChar = '(' then, + Do + If TraceV = 'T' then Trace r + Call GetSubStringValue + sa= 'SubstringingStatus =' SubstringingStatus + If TraceV = 'T' then Trace Off + If SubstringingStatus = 'Dependent' then Return + End + Else, + If terminateChar = '.' then, + /* Check whether the DotCount can be decreased */ + /* This occurs when the value of a variable ends */ + /* and is followed by Dots (periods). */ + Do + If TraceV = 'T' then Trace r + eatDots = DotCount.appendVariable + Do While terminateChar = '.' & eatDots > 0 + string = DELSTR(string, terminateChar#, 1) + terminateChar =, + Substr(string || ' ',terminateChar#,1) + eatDots = eatDots - 1 + End /* Do While terminateChar = '.' ... */ + If TraceV = 'T' then Trace Off + End + /* Check whether the DotCount needs to be increased */ + /* This occurs when the value of a variable ends */ + /* with another variable, and no Dot follows. */ + If TraceV = 'T' then Trace r + sa= 'string = ' string + sa= 'Length(string)=' Length(string) + sa= 'positionAmper =' positionAmper + sa= 'VariableLen#1=' VariableLen#1 + sa= 'appendVariable =' appendVariable + sa= 'thisVariableName=' thisVariableName + sa= 'DotCount.thisVariableName =', + DotCount.thisVariableName + sa= 'DotCount.appendVariable =', + DotCount.appendVariable + sa= 'terminateChar#=' terminateChar# + sa= 'Length(string)' Length(string) + sa= 'SubstringingStatus=' SubstringingStatus + If SubstringingStatus /= 'Done' &, + (terminateChar = '"' | terminateChar = "'" |, + terminateChar = ' ' | terminateChar = "." ) &, + terminateChar# >= Length(string) then, + DotCount.thisVariableName =, + DotCount.thisVariableName + DotCount.appendVariable + /* Rewrite the portion of string where variable is found + ... and eat trailing Dots as counted necessary */ + sa = string + sa = positionAmper + sa = appendValue + If positionAmper > 1 then, + newstring = Substr(string,1,positionAmper-1) + Else newstring = '' + newstring = newstring || appendValue + sa = Substr(string,terminateChar#,1) + If terminateChar# <= length(string) then, + newstring = newstring || Substr(string,terminateChar#) + string = newstring + say 'AF: ' string + StillResolvingVars = 'Y' + If TraceV = 'T' then Trace Off + Iterate + End; /* If terminateChar# <= (maxVariableLen+1)*/ + End; /* Do Forever */ +FindVariableNameEnd: + /* Examine the unresolved original to see where */ + /* the variable name ends. */ + tempEndCharacter =, + VERIFY(Substr(original.inp# || ' ',positionAmper+1), + ,variableChars) + tempVariableName =, + Substr(string,positionAmper+1,tempEndCharacter-1) + tempVariableName = Strip(tempVariableName) + If Wordpos(tempVariableName, ResolvedVariables) > 0 then, + Return tempEndCharacter + /* Examine the last resolved value to see where */ + /* the variable name ends. */ + tempEndCharacter =, + VERIFY(Substr(string_before || ' ',positionAmper+1), + ,variableChars) + tempVariableName =, + Substr(string,positionAmper+1,tempEndCharacter-1) + tempVariableName = Strip(tempVariableName) + If Wordpos(tempVariableName, ResolvedVariables) > 0 then, + Return tempEndCharacter + /* Examine the resolved string to see where */ + /* the variable name ends. */ + VariableLen#1 =, + VERIFY(Substr(string || ' ',positionAmper+1), + ,variableChars) + Return VariableLen#1 +GetSubStringValue: + sa= 'closeparenChar#=' closeparenChar# + closeparenChar# = Pos(')',string, terminateChar#) + If closeparenChar# = 0 then Return + SubstringValues =, + Substr(string,terminateChar#,closeparenChar#-terminateChar#) + If Pos(",", SubstringValues) = 0 then return + If Pos('50'x, SubstringValues) > 0 then, + Do + SubstringingStatus = 'Dependent' + Return + End + SubstringValues =, + translate(SubstringValues," ","(:,)") + SubstringStart = Word(SubstringValues,1) + If VERIFY(SubstringStart,$numbers) > 0 then Return + SubstringLength= Word(SubstringValues,2) + If VERIFY(SubstringLength,$numbers) > 0 then Return + If Words(SubstringValues) > 2 then, + SubstringPad = Word(SubstringValues,3) + Else, + SubstringPad = ' ' + appendValue =, + Substr(appendValue,SubstringStart,SubstringLength,SubstringPad) + SubstringingStatus = 'Done' + terminateChar# = closeparenChar# + 1 + Return diff --git a/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/README.md b/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/README.md new file mode 100644 index 0000000..6b4709d --- /dev/null +++ b/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/README.md @@ -0,0 +1,100 @@ +# Processor Analysis and Maintenance Tools + +These administrative tools provide two key capabilities: +- **Processor Symbol Substitution Analysis:** This helps administrators gain a deeper insight into the processor symbol substitutions utilized within their processors. +- **Processor Step Comparison:** + This feature allows for the comparison of common steps between various processors. This is highly beneficial for activities such as merging processors, which ultimately contributes to reducing the overall number of processors requiring management. + + +## Processor Symbol Substitution Analysis +**NDVRREPT.rex REPTPREP.rex ESYMBOLR.rex NDVRREPJ.jcl** + +Endevor processors utilize [three types of symbols](https://techdocs.broadcom.com/us/en/ca-mainframe-software/devops/ca-endevor-software-change-manager/19-0/administrating/site-symbolics.html): User, Site, and Endevor symbols. Endevor symbols, designated as “C1*” variables, are assigned values by Endevor during execution. The values of User and Site symbols can be dependent on these Endevor symbols. + +Due to the potential for a symbol's value to be another variable name or a combination of text strings and variable names, deciphering these symbol substitutions can be complex. + +The reporting items in this folder are designed to mimic Endevor's functionality, providing a clear, step-by-step demonstration of variable resolution. This process shows the gradual replacement of an initial variable with intermediate results until the final value is determined. During this substitution, dependency variables are reported. It is unnecessary to replicate actual Endevor inventory scenarios. Instead, simply "seed" your chosen values for Endevor's C1 variables and submit the reporting JCL. The resulting output is a report that focuses exclusively on the resolved symbol substitutions. + + +For instance, selected lines from this report illustrate the gradual substitution for the variable #CPYLIB1 and includes the substitutions of a dependent variable, #CGRVL1Q. Before and After images are shown for each substitution. + + + B4: #CPYLIB1 = &#CGRVL1Q...CPYLIB + - - - - - - - - - - - - - - - - 52 Line(s) not Displayed + B4: #CGRVL1Q = &#CGP&#MAP&C1SI.(1,1) + AF: #CGRVL1Q = &#CGP&#MAPP(1,1) + AF: #CGRVL1Q = &#CGP6 + - - - - - - - - - - - - - - - 1537 Line(s) not Displayed + B4: #CGRVL1Q = &#CGP6 + AF: #CGRVL1Q = SCM.P.SHXXX + - - - - - - - - - - - - - - - 980 Line(s) not Displayed + B4: #CPYLIB1 = &#CGRVL1Q...CPYLIB + AF: #CPYLIB1 = SCM.P.SHXXX.CPYLIB + + +The necessary inputs for your site, depending on its configuration, may include: +- Capturing and converting the Site Symbol Table content. +- Copying variable sections from your processor(s). +- Seeding your C1 Variables. + +While Processor Group overrides are not currently supported, you can manually account for them by entering the values as either Site Symbol content or assigned processor values. + + +### Capture and Convert Site Symbol Table content + +Use one of the methods below to convert the content of your Site Symbol table into a REXX format. + +1) You can capture the Site Symbol table content using the [Option Report](https://techdocs.broadcom.com/us/en/ca-mainframe-software/devops/ca-endevor-software-change-manager/19-0/reporting/reports/site-options-report.html), and make manual edits to it to convert it to a REXX format. + + +2) Or, while displaying the Site Symbol under ISPF, execute the ESYMBOLR program, For example: + + TSO EXEC 'MYTEMP.PDS(ESYMBOLR)' + + The Site Symbol content will be displayed back to you, converted into a REXX format. Then, CUT and PASTE the viewed results. + +Copy the results into a dataset, or dataset(member), which is also listed in the JCL for reporting. + +### Collect variable sections from your processor(s) + +To prepare for reporting, first copy the User-defined symbol parameters from the PROC statements located at the beginning of the processor. These statements can then be used as input for the report. + +**Preparation Guidelines:** +- If a single line in your processor contains multiple variable assignments, split them so that each line contains only one assignment. +- Alternatively, use the REPTPREP edit macro to automatically reformat the variables from the top of the processor and to place them into a dataset for reporting. + +You may also include additional variables in the report input. For instance, to see how substitutions work for variables not currently defined in the processor, you can run a report on them before integrating them into the processor. + +Refer to the examples provided in this folder for guidance. + + +### Seed your C1 variables + +When assigning initial values for C1 variables, follow the structure shown in the NDVRREP@.jcl example. Minimally include variables used for subsequent substitution. For instance, you can omit the C1ELEMENT variable if it's not needed for any further variable resolution. However, if you are analyzing the behavior of a MOVE processor, you may need to "seed" both the sending and target C1 variables. + +### Tailor and submit the NDVRREPJ JCL + +Adjust the jobcard and dataset names in the NDVRREPJ jcl. + +The rexx iterates up to 25 times through your inputs to resolve variables. If you need more iterations, simply change this line in the REXX to reflect the number of iterations you want to use: + + Do pass# = 1 to 25 + +The job has been shown to complete thousands of substitutions and multiple iterations in just a few seconds. The job quits when it can no longer find any variables to resolve. If the job encounters a variable for which there is no value given, it will substitute what it can and end with a return code of 8. Look in the SYSTSPRT output to see various levels of substitutions. + +## Comparing processor steps for processor consolidation + +**CONSOLID.rex CONSOLSK.skel SUPCSOUT.rex** + +The real win in consolidation comes from the fact that many of these similar processors share standard steps. If you take a close look at the steps across different processors, especially those with the same or very similar step names, you can gain some valuable benefits: +- **Combine Processors:** By finding and merging any duplicated or nearly-identical logic into one standard processor or [processor Include](https://community.broadcom.com/HigherLogic/System/DownloadDocumentFile.ashx?DocumentFileKey=4e97b9d9-9a2e-6349-96e3-27c89ce5b00d) member, you can make the whole system much simpler. This merging cleans up the processing flow, making it easier to understand, manage, and fix bugs. It encourages a building-block design where common stuff is all in one place. +- **Cut Down on the Lines of Code (LoC) You Have to Support:** A straight-up result of combining things is getting rid of copied code. When similar steps are rolled into reusable parts, the total amount of code you have to keep running, test, and update is reduced. That means fewer places for bugs, better code quality, and a lower cost and headache for maintenance over time. Plus, any future fixes or updates to the shared logic only need to be done once, and every dependent processor instantly benefits. + +When resolving minor discrepancies identified during processor step comparisons, consider implementing the following strategies: +- **Externalize Details:** Utilize processor utilities, such as [CONPARMX](https://techdocs.broadcom.com/us/en/ca-mainframe-software/devops/ca-endevor-software-change-manager/19-0/administrating/processors/processor-utilities/conparmx-utility.html), to keep specific details external to the processors, preventing them from being hard-coded. +- **Employ Conditional Logic:** Incorporate IF/THEN/ELSE logic to accommodate necessary processing differences. +- **Standardize References:** Use Site Symbols for dataset names that are referenced across similar processor steps. + +To compare processor steps, first copy or retrieve them into a dataset. If the steps you want to compare are similar but do not all have the same step name, make them have the same step name in the dataset. Next, modify the CONSOLID.rex file: set the **Dataset** variable to the name of this dataset, set the **selectStep** variable to the name of the step you wish to compare, and set the **selectProcessor** variable to the name of the single processor you choose for comparison against all others. + +Once these variables are set, execute the REXX program under TSO. This action will submit a separate SUPERC job for every member within the specified **Dataset**. The results of each SUPERC comparison will be saved to the location specified by the **OUTDD** in its respective job. \ No newline at end of file diff --git a/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/REPTPREP.rex b/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/REPTPREP.rex new file mode 100644 index 0000000..bb5d216 --- /dev/null +++ b/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/REPTPREP.rex @@ -0,0 +1,81 @@ +/* REXX */ + "ISREDIT MACRO" + TRACE Off +/* Capture User sysmbols from within a processor */ + ADDRESS ISREDIT " (MEMBER) = MEMBER " ; + MyMODELDsn = 'your.pdsfor.MODELS' + myout.0 = 0; my# = 0 + answer = 'X' + answer = ' ' + ADDRESS ISREDIT " EXCLUDE ALL "; + ADDRESS ISREDIT " FIND '//*' 1 ALL" ; + ADDRESS ISREDIT " DELETE ALL NX" +/* ADDRESS ISREDIT " FIND ' PROC ' FIRST" ; */ + DO FOREVER + ADDRESS ISREDIT " FIND '=' NEXT" ; + If RC > 0 then Leave + ADDRESS ISREDIT " (linepos,whereEq) = CURSOR " ; + ADDRESS ISREDIT " (DLINE) = LINE " linepos + If Substr(DLINE,1,3) = '//*' then iterate; + If Word(DLINE,2) = 'EXEC' &, + Substr(Word(DLINE,3),1,4) = 'PGM=' then leave + whereback = whereEq + Call FindVariableBegining + If whereback = whereEQ - 1 ] , + Substr(DLINE,whereback,1) /= ' ' then Iterate + wherespace = whereback + command = Strip(Substr(DLINE,wherespace),) + If Substr(command,length(command),1) /= ',' then, + command = command ]] ',' + If answer /= 'X' then, + Say 'Assignment=' command + nextchar = Substr(DLINE,whereEq+1,1) + If nextchar= "'" then, + Parse var command keyword '=' "'" value "'" + Else + If nextchar= '"' then, + Parse var command keyword '=' '"' value '"' + Else + Do + wherenextequal = Pos('=',DLINE,whereEq+1) + If wherenextequal = 0 then, + Parse var command keyword '=' value ' ' + If wherenextequal > 0 then, + Do + whereback = wherenextequal + Call FindVariableBegining + If whereback = whereEQ - 1 ] , + Substr(DLINE,whereback,1) /= ' ' then Iterate + tmpstring = Substr(DLINE,wherespace,whereback) + Parse var tmpstring keyword '=' value ' ' + End + End + value = Strip(value,'T',',') + If answer /= 'X' then, + Say 'keyword =' keyword " value=" value + my# = my# + 1 + myout.my# = keyword "= '"|| value || "'" + If answer /= 'X' then, + Do; Say 'Continue?'; pull answer; End + if answer = 'N' then Leave + if answer = 'T' then Trace ?R + End /* Do Forever */ + "Alloc F(SAVMODEL) DA('" ]]MyMODELDsn ]]"(" ]]MEMBER ]] ")')", + "SHR REUSE" + myout.0 = my# + "EXECIO * DISKW SAVMODEL (Stem myout. Finis" + "FREE F(SAVMODEL)" + Exit +FindVariableBegining: + Do 10 + whereback= whereback - 1 + If whereback < 1 then Leave + prevchar = Substr(DLINE,whereback,1) + if prevchar = ',' ] prevchar = '/' then, + Do + DLINE = Overlay(' ',DLINE,whereback) + Leave + End + if prevchar = ' ' then Leave + End /* Do 10 */ + Return diff --git a/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/SUPCSOUT.rex b/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/SUPCSOUT.rex new file mode 100644 index 0000000..2982304 --- /dev/null +++ b/endevor/Field-Developed-Programs/Processor-Analysis-and-Maintenance/SUPCSOUT.rex @@ -0,0 +1,69 @@ +/* REXX */ +/* */ + "ISREDIT MACRO" + /* WRITTEN BY DAN Person */ +/* TRACE R ; */ +/* ADDRESS ISREXEC " CONTROL RETURN ERRORS " ; */ + ADDRESS ISREDIT " (MEMBER) = MEMBER " ; + ADDRESS ISREDIT " RESET " ; + ADDRESS ISREDIT " EXCLUDE '//*' 1 ALL "; + ADDRESS ISREDIT " DELETE ALL X " ; + ADDRESS ISREDIT " CURSOR = 1 1 " ; + ADDRESS ISREDIT " FIND 'EXEC' WORD NEXT " + RETCODE = 0 ; + STEPS.0 = 0 ; + NUMBER_STEPS = 0; + ADDRESS ISREDIT " (LPOS1,CPOS1) = CURSOR " ; + DO WHILE RETCODE = 0 + ADDRESS ISREDIT " (LPOS1,CPOS1) = CURSOR " ; + ADDRESS ISREDIT " (DLINE) = LINE "LPOS1 + DLINE = TRANSLATE(DLINE,' ',','); + MYMBR = STRIP(WORD(SUBSTR(DLINE,3,8),1),T) ; + MYMBR = STRIP(MYMBR,B,',') ; + MYMBR = STRIP(MYMBR,B,' ') ; + MYMBR = STRIP(MYMBR,B,',') ; + IF LENGTH(MYMBR) = 0 THEN, + DO + ADDRESS ISREDIT " FIND 'EXEC' WORD NEXT " + ITERATE ; + END; + IF SYSVAR(SYSENV) = FORE THEN , + SA= 'PROCESSING MEMBER ' MYMBR ; + NUMBER_STEPS = NUMBER_STEPS + 1 ; + STEPS.NUMBER_STEPS = MYMBR ; + ADDRESS ISREDIT " FIND 'EXEC' WORD NEXT " + RETCODE = RC ; + IF RETCODE > 0 THEN , + ADDRESS ISREDIT " CURSOR = .ZLAST " ; + ADDRESS ISREDIT " (LPOS2,CPOS2) = CURSOR " ; + IF RETCODE = 0 THEN , + LPOS2 = LPOS2 - 1 ; + ADDRESS ISREDIT " REPLACE "MYMBR LPOS1 LPOS2 ; + REPRC = RC + IF REPRC = 0 THEN , + ADDRESS ISREDIT " DELETE "LPOS1 LPOS2 ; + IF RETCODE = 0 THEN , + DO + ADDRESS ISREDIT " CURSOR = 1 1 " ; + ADDRESS ISREDIT " FIND 'EXEC' WORD NEXT " + END; + END ; + ADDRESS ISREDIT " CURSOR = .ZLAST " ; + ADDRESS ISREDIT " (LPOS2,CPOS2) = CURSOR " ; + LPOS2 = LPOS2 + 1; + IF NUMBER_STEPS > 0 THEN, + DO + ADDRESS ISREDIT " LINE_AFTER .ZLAST =", + "DATALINE '//SUPERCS EXEC SUPERCST,MEMBER="MEMBER"'" ; + DO I = 1 TO NUMBER_STEPS + OLD_PREFIX = SUBSTR(STEPS.I,1,4) ; + OLD_PREFIX = STRIP(OLD_PREFIX) ; + ADDRESS ISREDIT " LINE_AFTER .ZLAST =", + "DATALINE '//SUPERC1 EXEC SUPERC,MEMBER="STEPS.I ||, + ",PROCESSR="MEMBER",OLD="OLD_PREFIX"'" ; + END ; + ADDRESS ISREDIT " REPLACE #STEPS "LPOS2 ".ZL" ; + ADDRESS ISREDIT " DELETE "LPOS2 ".ZL" ; + END ; + ADDRESS ISREDIT " CANCEL " ; + EXIT 0