TPFDF Keylists in ISOC Paul Stuyvesant

Download Report

Transcript TPFDF Keylists in ISOC Paul Stuyvesant

TPFDF Keylists in ISOC
Paul Stuyvesant
Agenda
•
•
•
•
•
•
The traditional approach - Assembler
The traditional approach - ISOC
Using parameters in ISOC
Overview of Keylists
Writing macros for C programs
Some examples using Keylist macros
Traditional Approach
• Multiple calls in program with different
parameters
– DBOPN with HOLD/DETAC
– DBOPN with NOHOLD
• Keys set on individual commands
• Keylists available but rarely used
Traditional Approach
#IF EBSW01,EQ,X'04’
DBOPN REF=TR01PS,HOLD,DETAC,
ALG=MYORD
#ELSE
DBOPN REF=TR01PS,ALG=MYORD
#EIF
#IF CLI,OPTION,EQ,C’D’
DBRED REF=TR01PS,REG=R5,UP,
ERROR=DBERR,
KEY1=(PKY=#TR01K80),
KEY2=(R=TR01CAR,S=EBX000)
#ELSE
DBRED REF=TR01PS,REG=R5,UP,
ERROR=DBERR,
KEY1=(PKY=#TR01K80)
#EIF
Updates to file?
*
*
*
*
*
*
Traditional Approach
• Simple rewrite in ‘Assembler-ish’ style
• Does not use power of C/C++
parameter passing
• Often caused by lack of design training
– Assembler programmers used to ‘straight
line’ coding techniques
– Not advertising - no course available!
Traditional Approach
dft_fil *tr01ptr = NULL;
if(ecbptr()->ebsw01 == 0x04 )
Updates to file?
tr01ptr = dfopn_acc(TR01NAM, TR01FID, DFOPN_ORD,
DFOPN_HOLD | DFOPN_DETAC, MYORD);
else
tr01ptr = dfopn_acc(TR01NAM, TR01FID, DFOPN_ORD,
0, MYORD);
if(option == ‘D’)
df_setkey(keys, 1,
offsetof(tr01k80, tr01key),
member_size(tr01k80, tr01key),
DF_EQ,
0, TR01K80,
DF_UPORG,
DF_CONST);
Using Parameters
• Most function calls accept parameters
• Parameters can be fixed values or
variables
• You all know this anyway!
Passing Parameters
// Main program here
{
dft_opt opts = 0;
dft_fil *fptr = NULL;
// Set for default options
if(ecbptr()->ebsw01 == 0x04 )
opts = DFOPN_HOLD | DFOPN_DETAC;
fptr = Open_tr01(opts);
}
// User written function to open file using options passed
dft_fil *Open_tr01( dft_opt tr01opt )
{
dft_fil *tr01ptr = NULL;
ptr = dfopn_acc(TR01NAM, TR01FID, DFOPN_ORD, tr01opt, MYORD);
return tr01ptr;
}
Keylist Overview
• Build keylist in area of memory
• Rarely seen - but can be useful
• Uses SW01SR Dsect
#SUBR KEY40_ROUTINE,R4
LA
R1,EBX050
Basing key list - SW01SR
XC
EBX050(L'SW01NKY+5*L'SW01KIT),EBX050 clear it
MVC
EBX050(2),=H'1'
Number of keys
MVC
SW01DIS,=H'2'
Displacement in LREC
MVC
SW01LEN,=H'1'
Length
MVI
SW01MSK,X'40'
Mask to check
MVI
SW01CON,X'70'
Indicate TM
MVI
SW01ID1,#BIT1+#BIT4
Up & CLI on Mask Value
#ESUB
Macros Substitution
• Create macros using #define directive
• Compiler expands macro out at
compile time.
• Parenthesis required to ensure they
are evaluated correctly
• Can sometimes be obtuse
Macros Substitution
#define MAX(A, B)
((A > B) ? A : B )
var = MAX(10, 20)
// Becomes var = ((10 > 20) ? 10 : 20 )
// This example from cdferr.h
#define DF_OK(file) ((file)->sw00rtn == 0)
if(DF_OK(tr01ptr))
//becomes if(((tr01ptr)->sw00rtn == 0))
#define ecbptr() (*(struct eb0eb **)0x00000514ul)
Take Care
//
//
//
//
this line from header file - standard way to calculate size
of fixed length part of lrec. In this example imagine that
tr01k40 = 10 and tr01msg = 1. This means the fixed part of
the lrec is 9
#define TR01L40
sizeof(tr01k40) - member_size(tr01k40,tr01msg)
// Read an lrec - it is 20 bytes long - 11 bytes variable field
ptr = dfred( etc etc );
// calculate length of variable field
a = ptr->tr01siz - TR01L40;
// expands out to
a = ptr->tr01siz - sizeof(tr01k40) - member_size(tr01k40,tr01msg);
a = 20 - 10 - 1;
// WRONG - this result is 9
Correct Version
//
//
//
//
this line from header file - standard way to calculate size
of fixed length part of lrec. In this example imagine that
tr01k40 = 10 and tr01msg = 1. This means the fixed part of
the lrec is 9
#define TR01L40
(sizeof(tr01k40) - member_size(tr01k40,tr01msg))
// Read an lrec - it is 20 bytes long - 11 bytes variable field
ptr = dfred( etc etc );
// calculate length of variable field
a = ptr->tr01siz - TR01L40;
// expands out to
a = ptr->tr01siz - (sizeof(tr01k40) - member_size(tr01k40,tr01msg));
a = 20 - (10 - 1);
// CORRECT - this result is 11
Keylist Examples
•
•
•
•
•
Various ways of dealing with Keylists
Traditional approach
Pass parameters into functions
Write user defined macros
Or a combination of all/some of these
// Key 2 set up depending on value of parameter
// key2: CARCODE = match Carrier Code in lrec
//
Else
= Matching name for length of input
void SetUpKeys(dft_fil *pTr01ps,
dft_kyl *pKeys,
char *Carcode,
int key2setting )
{
df_setkey(pKeys, 1,
offsetof(tr01k80, tr01key),
member_size(tr01k80, tr01key),
DF_EQ,
0,
TR01K80,
DF_UPORG,
DF_CONST);
if(key2 == CARCODE)
{
df_setkey(pKeys, 2,
offsetof(tr01k80, tr01car),
member_size(tr01k80, tr01car),
DF_EQ,
Carcode,
0,
DF_UPORG,
DF_CHAR);
}
else
{
df_setkey(pKeys, 2,
offsetof(tr01k80, tr01nam),
strlen(ecbptr()->ebw000),
DF_EQ,
Carcode,
0,
DF_NOORG,
DF_CHAR);
}
dfkey_nbr(pTr01ps, pKeys, 2);
return;
}
Conditional Operator
df_setkey(pKeys, 1,
offsetof(tr01k80, tr01key),
member_size(tr01k80, tr01key),
DF_EQ,
0,
TR04K80,
DF_UPORG,
DF_CONST);
df_setkey(pKeys, 2,
((key2 == CARCODE) ?
:
((key2 == CARCODE) ?
:
DF_EQ,
Carcode,
0,
((key2 == CARCODE) ?
DF_CHAR);
offsetof(tr01k80, tr01car)
offsetof(tr01k80, tr01nam)),
member_size(tr01k80, tr01car)
strlen(Carcode)),
DF_UPORG : DF_NOORG),
df_setkey() issues
• General df_setkey() function
– Equivalent of Assembler process
• Mutually exclusive parameters
– Always a recipe for disaster
– No indication of problems at compile
time only at run time
• Nine parameters for each key
// This example will try to match the byte at address 0
// with the PKY field in the lrec - NOT GOOD
df_setkey(pKeys, 1,
offsetof(tr01k80, tr01key),
member_size(tr01k80, tr01key),
DF_EQ,
0,
// For DF_CHAR or DF_PACKED
TR04K80,
// For DF_CONST or DF_MASK
DF_UPORG,
DF_CHAR);
// WRONG - should be DF_CONST
Solutions?
• Write some macros
– Easy to do
• Place macros in header file
– Single point of change
• Make sure people know about them!
– Otherwise it’s a waste of time
// Set up our own setkey macros - allows us to cut
// down parameters to 7
#define DF_CONST_KEY(A, B, C, D, E, F, G )
df_setkey(A, B, C, D, E,
0,
F, G,
DF_CONST)
\
\
\
\
#define DF_MASK_KEY(A, B, C, D, E, F, G)
df_setkey(A, B, C, D, E,
0,
F, G,
DF_MASK)
\
\
\
\
#define DF_CHAR_KEY(A, B, C, D, E, F, G)
df_setkey(A, B, C, D, E, F,
0,
G ,
DF_CHAR)
\
\
\
\
//
//
//
//
This Example is using the previously defined
macros and allows us to only worry about 7
parameters and the name of the macro indicates
the type of parameter being used to set the key
DF_CONST_KEY(pKeys, 1,
offsetof(tr01k40, grctkey),
member_size(tr01k40, grctkey),
DF_EQ,
GRCTK40,
DF_UPORG);
if(ptr != NULL)
{
DF_MASK_KEY(pKeys, 2,
offsetof(tr01k40, grctind),
member_size(tr01k40, grctind),
DF_O,
0X21,
DF_NOORG);
}
Next Stage
• In assembler we use PKY
– KEY1=(PKY=#TR01K80)
– Only for Primary Key
– Is (normally) the first key set
– Always length of 1
– Assumes displacement of 2 in lrec
• So lets do the same in ISOC
//
//
//
//
//
Set up our own PKY macros - allows us to cut
down parameters = 2 if we make some assumptions
about the position and size
The only parameters we need are the address of
key area and the organisation
// These are generic macros and can be used
// with ANY file
#define SET_PKY40(A, B)
df_setkey(A, 1, 2, 1, DF_EQ,
0, 0X40, B,
DF_CONST)
\
\
\
#define SET_PKY80(A, B)
df_setkey(A, 1, 2, 1, DF_EQ,
0, 0X80, B,
DF_CONST)
\
\
\
//
//
//
//
This Example is using the previously defined
macros and allows us to only worry about 2
parameters and the name of the macro indicates
the type of parameter being used to set the key
SET_PKY40(pKeys, DF_UPORG);
if(ptr != NULL)
{
DF_MASK_KEY(pKeys, 2,
offsetof(tr01k40, grctind),
member_size(tr01k40, grctind),
DF_O,
0X21,
DF_NOORG);
}
// Take it another stage and create UP/DOWN/NOORG
// versions of the macros
// These are generic macros and can be used
// with ANY file
#define SET_PKY40_UP(A)
df_setkey(A, 1, 2, 1, DF_EQ,
0, 0X40, DF_UPORG,
DF_CONST)
// And now use the macro in a program
SET_PKY40_UP(pKeys);
\
\
\
Last thoughts
• Thanks for listening
• In the spirit of Open Source
– All code samples available (and free)
– www.pcs-training.co.uk/downloads
• Any Questions?