Chapter Contents

Previous

Next
Handling Files

DL/I Database Support

SAS/C programs can use the DL/I call-level interface to process IMS/VS databases. No special interfaces are required, and DL/I applications written using SAS/C code are not restricted from using any C language features or library functions. The DL/I user interface block (UIB) is defined in the dliuib.h header file, which looks like this:

struct DLIUIB {       /* user interface block   */
   void *uibpcbal;    /* PCB address list       */
   struct{            /*                        */
      char uibfctr;   /* return codes           */
      char uibdltr;   /* additional information */
   } uibrcode;        /* DL/I return codes      */
   unsigned short _;  /* (reserved)             */
};

The EXEC DLI command-level interface to DL/I databases is also fully supported on CICS. EXEC DLI commands can be freely interspersed in your C program. The run-time library automatically performs a DL/I initialization call on your program's behalf the first time an EXEC DLI command is executed. This permits DL/I calls to occur in dynamically loaded C routines. A DL/I interface block (DIB) is also automatically allocated by the library, and can be addressed via the global external variable __dibptr . The header file containing the DIB definition is included in your program by the SAS/C command translator. The DIB is defined as follows:

struct DIB {
   char DIBVER[2];
   char DIBSTAT[2];
   char DIBSEGM[8];
   char DIBFIL01;
   char DIBFIL02;
   char DIBSEGLV[2];
   short DIBKFBL;
   char DIBFIL03[6];
} *__dibptr;

For special considerations on using the DL/I command-level interface in CICS, see the IBM CICS Programmer's Reference Manual. For additional information on using C with DL/I and the call-level interface, see the SAS/C Programmer's Report Developing IMS-DL/I Applications in C with the SAS/C Compiler. A complete example follows:

#include <stdio.h>
#include <ctype.h>
#include <packed.h>
#include <signal.h>
#include <options.h>

typedef struct {
   char ssn[11];
   char name[40];
   char address1[30];
   char address2[30];
   char city[28];
   char state[2];
   char country[20];
   char zipcode[10];
   char home_phone[12];
   char work_phone[12];
   char _1[30];
} Customer_Segment;

typedef struct {
   char number[12];
   char balance[5];
   char date[8];
   char stmt_bal[5];
   char _3[8];
} Account_Segment;

typedef struct {
   int amount;
   char _1[2];
   char date[4];
   char time[4];
   char description[66];
} Debit_Segment;

typedef struct {
   int amount;
   char _1[2];
   char date[4];
   char time[4];
   char description[66];
} Credit_Segment;

static void print_DIB();
static void dump(char *, int);
static void print_customer(const Customer_Segment *);
static void print_account(const Account_Segment *);

static char ioarea[sizeof(Customer_Segment)];

#define STATUS(code) 
        (memcmp(_dibptr->DIBSTAT, code, 2) == 0)

main()
{

   /* Schedule a PSB with the name: ACCTRCOB. */
   EXEC DLI SCHEDULE PSB(ACCTRCOB);

   /* unqualified SSA...                      */
   printf("\n\n -Get All Customer Segments-\n");

   EXEC DLI GET UNIQUE USING PCB(1)
            SEGMENT("CUSTOMER ") INTO(ioarea);

#if defined(DUMPS)
      print_DIB();
   #endif

   while (STATUS("  "))
{
       print_customer((Customer_Segment *)ioarea);

        EXEC DLI GET NEXT USING PCB(1)
                SEGMENT("CUSTOMER ") INTO(ioarea);

     #if defined(DUMPS)
       print_DIB();
    #endif    }

   /*  qualified SSA...                       */
   printf("\n\n -Get Specific Customer Segment-\n");

      EXEC DLI GET UNIQUE USING PCB(1)
               SEGMENT("CUSTOMER ") WHERE(CUSTZIP="26001-0000")
               SEGMENT("CHCKACCT ") INTO(ioarea);

   #if defined(DUMPS)
      print_DIB();
      dump(ioarea, sizeof(Account_Segment));
   #endif

   print_account((Account_Segment *) ioarea);

   exit(0);
}

static void print_customer(const Customer_Segment *ioarea)
{
    puts("Customer Segment Dump:\n");
    printf("   SSN: %.11s\n", ioarea->ssn);
    printf("   Name: %.40s\n", ioarea->name);
    printf("   Address 1: %.30s\n", ioarea->address1);
    printf("   Address 2: %.30s\n", ioarea->address2);
    printf("   City: %.28s\n", ioarea->city);
    printf("   State: %.2s\n", ioarea->state);
    printf("   Country: %.20s\n", ioarea->country);
    printf("   Zip code: %.10s\n", ioarea->zipcode);
    printf("   Home phone: %.12s\n", ioarea->home_phone);
    printf("   Work phone: %.12s\n", ioarea->work_phone);
    printf("   Filler: %.30s\n\n", ioarea->_1);
 }

static void print_account(const Account_Segment *ioarea)
{
    double d;
    puts("Account Segment Dump:\n");
    printf("   Number: '%.12s'\n", ioarea->number);
    d = _pdval((char (*)[])ioarea->balance, 5, 2);
    printf("   Balance: %g\n", d);
    printf("   Date: '%.8s'\n", ioarea->date);
    d = _pdval((char (*)[])ioarea->stmt_bal, 5, 2);
    printf("   Statement Balance: %g\n\n", d);
 }

static void print_DIB()
{
    puts("DIB Dump:\n");
    printf("   Version : '%.2s'\n", _dibptr->DIBVER);
    printf("   Status  : '%.2s'\n", _dibptr->DIBSTAT);
    printf("   Status1 : '%.2x'\n", _dibptr->DIBSTAT[0]);
    printf("   Status2 : '%.2x'\n", _dibptr->DIBSTAT[1]);
    printf("   Seg name: '%.8s'\n", _dibptr->DIBSEGM);
    printf("   Fil  #1 : '%.c'\n", _dibptr->DIBFIL01);
    printf("   Fil  #2 : '%.c'\n", _dibptr->DIBFIL02);
    printf("   Seg ver : '%.2s'\n", _dibptr->DIBSEGLV);
    printf("   Key leng: '%.d'\n", _dibptr->DIBKFBL);
    printf("   Fil  #3 : '%.c'\n", _dibptr->DIBFIL03);
 }

static void dump(char *area, int length)
{
    int c, l;
    #define BYTES_PER_LINE 16

    printf("Data Dump - Length = %d\n\n", length);
    if (length % BYTES_PER_LINE)
       length = ((length + BYTES_PER_LINE-1) / BYTES_PER_LINE)
                                                       * BYTES_PER_LINE;
    for (l = 0; l < length; l += BYTES_PER_LINE)0
        printf("   +%0.4X  *", l);
        for (c = 0; c < BYTES_PER_LINE; c++)
           printf("%0.2X", area<l+c>);
        fputs("*  *", stdout);
        for (c = 0; c < BYTES_PER_LINE; c++)
           putchar(isprint(area[l+c]) ? area[l+c] : '.');
        puts("*");
     }    putchar('\n');
 }

Here is the JCL for this example:

//CICS    EXEC LCCCPCL,
//  PARM.CCP='DLI ',
//  PARM.C='NOEXC SNAME(DLISAMP) RENT '
//  PARM.LKED='LIST MAP RENT REUS XREF '
//CCP.SYSIN    DD DSN=userid.SASC.CCP(DLI$SAMP),DISP=SHR
//LKED.SYSLMOD DD DSN=system.CICSAPPL.LOADLIB,DISP=SHR
//*


Chapter Contents

Previous

Next

Top of Page

Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.