1 / 27

TPFDF Keylists in ISOC

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.

blake-noble
Download Presentation

TPFDF Keylists in ISOC

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. TPFDF Keylists in ISOC Paul Stuyvesant

  2. 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

  3. 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

  4. Traditional Approach #IF EBSW01,EQ,X'04’ Updates to file? 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

  5. 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!

  6. 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);

  7. Using Parameters • Most function calls accept parameters • Parameters can be fixed values or variables • You all know this anyway!

  8. Passing Parameters // Main program here { dft_opt opts = 0; // Set for default options dft_fil *fptr = NULL; 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; }

  9. 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

  10. 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

  11. 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)

  12. 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

  13. 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

  14. 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

  15. // 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);

  16. 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; }

  17. 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) ? offsetof(tr01k80, tr01car) : offsetof(tr01k80, tr01nam)), ((key2 == CARCODE) ? member_size(tr01k80, tr01car) : strlen(Carcode)), DF_EQ, Carcode, 0, ((key2 == CARCODE) ? DF_UPORG : DF_NOORG), DF_CHAR);

  18. 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

  19. // 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

  20. 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

  21. // 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)

  22. // 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); }

  23. 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

  24. // 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)

  25. // 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); }

  26. // 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);

  27. 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?

More Related