Chapter Contents |
Previous |
Next |
Examples |
#include <dfhbmsca.h> /* useful BMS definitions */ /* C struct defining Map A, produced by DSECT2C */ #include <sascaga.h> /* C struct defining Map C, produced by DSECT2C */ #include <sascagc.h> #include <ctype.h> /* standard C type header */ #include <string.h> /* standard C string handling header */ /* general-purpose variables */ short i; char rid[6] = "000000"; /* record key, the account number */ char ridb[6] = "000000"; /* record key, for backward paging */ char ridf[6] = "000000"; /* record key, for forward paging */ /* indicates in which direction the browsing */ /* is currently moving: F or B */ char currop; /* indicates the previous browsing direction */ char lastop; char status; /* file status: 'H', 'L', or ' ' */ char messages[39]; /* message holding area */ short comlen; /* length of CICS commarea */ char keynum[6]; /* record key, the account number */ /* FILEA record layout */ struct FILEA{ char stat; char numb[6]; char name[20]; char addrx[20]; char phone[8]; char datex[8]; char amount[8]; char comment[9]; } filea; /* function prototypes */ void errors(void); void smnu(void); void smsg(void); void not_found(void); void build_next(void); void build_prev(void); void page_forward(void); void page_backward(void); void receive(void); void too_high(void); void too_low(void); /* The main function begins here. */ main() { /* Prepare to handle paging requests via PF keys. */ EXEC CICS HANDLE AID CLEAR(smsg) PF1(page_forward) PF2(page_backward); /* Prepare to handle error conditions. */ EXEC CICS HANDLE CONDITION ERROR(errors) MAPFAIL(smsg) NOTFND(not_found); /* Read the initial screen. */ EXEC CICS RECEIVE MAP("SASCAGA"); /* Was a starting account number provided? */ if (memcmp(sascaga.keyl,"\0 \0",2) == 0){ /* No, so default to zero. */ strcpy(rid,"000000"); strcpy(ridf,"000000"); } else{ /* Yes, so validate all of its digits. */ for(i=0;i<=5;i++){ if (isdigit((int) sascaga.KEYI[i]) == 0){ strcpy(messages,"ACCOUNT NUMBER MUST BE NUMERIC"); smnu(); /* There is no return from smnu(). */ } } /* Save the starting account number for */ /* use in either direction. */ memcpy(rid,sascaga.keyi,6); memcpy(ridf,sascaga.keyi,6); memcpy(ridb,sascaga.keyi,6); } /* Initiate the VSAM browse file operation. */ EXEC CICS STARTBR DATASET("FILEA") RIDFLD(rid); /* Is the current account number 999999 */ /* (the absolute maximum)? */ if (memcmp(rid,"999999",6) != 0){ /* No, so page forward. */ page_forward(); } else{ /* Yes, so set the status to HIGH and page backward. */ status = 'H'; page_backward(); } receive(); /* There is no return from receive(). */ } /* end of main function */ /* This function processes a forward paging request. */ void page_forward() { currop = 'F'; /* Set the indicator to forward paging mode. */ /* Prepare to handle reading past the end of the file. */ EXEC CICS HANDLE CONDITION ENDFILE(too_high); memset(&sascagc,'\0',SASCAGCE); /* Clear Map C. */ memcpy(rid,ridf,6); build_next(); /* Read more records. */ memcpy(ridf,rid,6); EXEC CICS SEND MAP("SASCAGC") ERASE; /* Display Map C. */ } /* end of page_forward function */ /* This function processes a backward paging request. */ void page_backward() { currop = 'B'; /* Set the indicator to backward paging mode. */ /* Prepare to handle reading before the beginning of the file. */ EXEC CICS HANDLE CONDITION ENDFILE(too_low); memset(&sascagc,',SASCAGCE); /* Clear Map C. */ memcpy(rid,ridb,6); memcpy(ridf,ridb,6); /* READPREV commands will reread the last record read by a */ /* READNEXT command, so perform an extra READPREV to account */ /* for this behavior. */ if ((lastop == 'F') && (status != 'H')){ EXEC CICS READPREV DATASET("FILEA") INTO(&filea) RIDFLD(rid) LENGTH(sizeof(struct FILEA)) KEYLENGTH(sizeof(rid)); } build_prev(); /* Read more records. */ memcpy(ridb,rid,6); EXEC CICS SEND MAP("SASCAGC") ERASE; /* Display Map C. */ } /* end of page_backward function */ /* This function controls the continual processing of */ /* page requests. Remember that the user can decide to */ /* press PF1 or PF2 at any time. Pressing these keys */ /* is an implicit request for forward or backward paging, */ /* respectively. When a PF key is pressed, the */ /* appropriate function is driven; then control */ /* returns to the next executable statement within the */ /* for(;;) loop. From that point, normal FORWARD/BACKWARD */ /* <ENTER> key processing continues. */ void receive() { /* Continue to process page requests until the CLEAR key is */ /* pressed or the user does not enter a direction indicator. */ for(;;){ /* Remember which direction the reading is going. */ lastop = currop; /* Read the latest screen. */ EXEC CICS RECEIVE MAP("SASCAGC"); /* When the MAPFAIL condition occurs here, the browse */ /* operation ends, and smsg() will be driven. */ status = ' '; /* Did the user enter a forward page request by keying an F ? */ if (memcmp(sascagc.diri,"F",1) == 0){ /* Yes, so cause forward paging to occur. */ page_forward(); } /* Did the user enter a backward page request by keying a B ? */ else if (memcmp(sascagc.diri,"B",1) == 0){ /* Yes, so cause backward paging to occur. */ page_backward(); } else{ /* Neither F nor B was keyed, so resend the map. This */ /* eventually results in a MAPFAIL condition and, */ /* therefore, the end of the browse operation. */ EXEC CICS SEND MAP("SASCAGC"); } } /* end of for(;;) loop */ } /* end of receive() */ /* This function is called when a read is attempted past */ /* the end of file. */ void too_high() { /* Set status so that further reads are prevented. */ status = 'H'; memcpy(ridf,rid,6); memcpy(ridb,rid,6); /* Indicate that forward paging has ceased. */ sascagc.diro = ' '; /* Prepare an informative message. */ strcpy(sascagc.msg1o,"Hi-End of File"); sascagc.msg1a= DFHBMASB; } /* end of too_high() */ /* This function is called when a read is attempted */ /* before the beginning of the file. */ void too_low() { /* Set status so that further reads are prevented. */ status = 'L'; strcpy(ridf,"000000"); strcpy(ridb,"000000"); /* Indicate that backward paging has ceased. */ sascagc.diro = ' '; /* Prepare an informative message. */ strcpy(sascagc.msg2o,"Lo-End of File"); sascagc.msg2a = DFHBMASB; } /* end of too_low */ /* This function is called when the specified starting */ /* account number is not found. The VSAM browse */ /* operation is ended and appropriate messages are prepared. */ void not_found() { strcpy(messages,"End of File - Please Restart"); EXEC CICS ENDBR DATASET("FILEA"); smnu(); /* There is no return from smnu() */ } /* end of not_found() */ /* This function prepares an informative */ /* message and calls smnu(). */ void smsg() { strcpy(messages,"Press CLEAR to Exit"); smnu(); /* There is no return from smnu(). */ } /* end of smsg() */ /* This function is called when a severe and */ /* unrecoverable error is detected. It */ /* causes a CICS transaction dump to be taken, */ /* and prepares an error message. */ void errors() { EXEC CICS DUMP DUMPCODE("ERRS"); strcpy(messages,"Transaction Terminated"); smnu(); /* There is no return from smnu(). */ } /* end of errors() */
/* This function displays the main menu on */ /* the screen and returns control to CICS. */ void smnu() { memset(&sascaga,'\0',SASCAGAE); /* Clear Map A. */ sascaga.msga = DFHBMASB; /* Move the message to the map. */ memcpy(sascaga.msgo,messages,strlen(messages)); memset(messages,'\0',39); /* Clear the message variable. */ EXEC CICS SEND MAP("SASCAGA") ERASE; EXEC CICS RETURN; } /* end of smnu() */ /* This function performs up to four READNEXT */ /* commands to fill the screen in a forward paging mode. */ void build_next() 0 int i; /* It takes four iterations to fill the screen. */ for(i=1; i<= 4; i++){ EXEC CICS READNEXT DATASET("FILEA") INTO(&filea) RIDFLD(rid) LENGTH(sizeof(struct FILEA)) KEYLENGTH(sizeof(rid)); /* If you read past the end of the file, STOP. */ if (status == 'H') break; switch(i){ case 1:{ /* Move the record fields to line 1 of the map. */ memcpy(sascagc.number1o,filea.numb,sizeof(filea.numb)); memcpy(sascagc.name1o,filea.name,sizeof(filea.name)); memcpy(sascagc.amount1o,filea.amount,sizeof(filea.amount)); memcpy(ridb,rid,6); break; } /* end of case: 1 */ case 2:0 /* Move the record fields to line 2 of the map. */ memcpy(sascagc.number2o,filea.numb,sizeof(filea.numb)); memcpy(sascagc.name2o,filea.name,sizeof(filea.name)); memcpy(sascagc.amount2o,filea.amount,sizeof(filea.amount)); break; } /* end of case: 2 */ case 3:0 /* Move the record fields to line 3 of the map. */ memcpy(sascagc.number3o,filea.numb,sizeof(filea.numb)); memcpy(sascagc.name3o,filea.name,sizeof(filea.name)); memcpy(sascagc.amount3o,filea.amount,sizeof(filea.amount)); break; } /* end of case: 3 */ case 4:0 /* Move the record fields to line 4 of the map. */ memcpy(sascagc.number4o,filea.numb,sizeof(filea.numb)); memcpy(sascagc.name4o,filea.name,sizeof(filea.name)); memcpy(sascagc.amount4o,filea.amount,sizeof(filea.amount)); break; } /* end of case: 4 */ } /* end of switch(i) * } /* end of for loop */ } } /* end of build_next() */ /* This function performs up to four READPREV commands */ /* to fill the screen in a backward paging mode. */ void build_prev() 0 int i; /* It takes 4 iterations to fill the screen. */ for(i=1; i <= 4; i++)0 EXEC CICS READPREV DATASET("FILEA") INTO(&filea) RIDFLD(rid) LENGTH(sizeof(struct FILEA)) KEYLENGTH(sizeof(rid)); /* If we read before the beginning of the file, STOP. */ if (status == 'L') break; /* The records will be displayed in ascending order, */ /* so put the last one read at the top of the screen. */ switch(i)0 case 4:0 /* Move the record fields to line 1 of the map. */ memcpy(sascagc.number1o,filea.numb,sizeof(filea.numb)); memcpy(sascagc.name1o,filea.name,sizeof(filea.name)); memcpy(sascagc.amount1o,filea.amount,sizeof(filea.amount)); break; } /* end of case: 4 */ case 3:0 /* Move the record fields to line 2 of the map. */ memcpy(sascagc.number2o,filea.numb,sizeof(filea.numb)); memcpy(sascagc.name2o,filea.name,sizeof(filea.name)); memcpy(sascagc.amount2o,filea.amount,sizeof(filea.amount)); break; } /* end of case: 3 */ case 2:0 /* Move the record fields to line 3 of the map. */ memcpy(sascagc.number3o,filea.numb,sizeof(filea.numb)); memcpy(sascagc.name3o,filea.name,sizeof(filea.name)); memcpy(sascagc.amount3o,filea.amount,sizeof(filea.amount)); break; } /* end of case: 2 */ case 1:{ /* Move the record fields to line 4 of the map. */ memcpy(sascagc.number4o,filea.numb,sizeof(filea.numb)); memcpy(sascagc.name4o,filea.name,sizeof(filea.name)); memcpy(sascagc.amount4o,filea.amount,sizeof(filea.amount)); break; } /* end of case: 1 */ } /* end of switch(i) */ } /* end of for loop */ } /* end of build_prev() */
Chapter Contents |
Previous |
Next |
Top of Page |
Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.