Your Browser is not longer supported

Please use Google Chrome, Mozilla Firefox or Microsoft Edge to view the page correctly
Loading...

{{viewport.spaceProperty.prod}}

Example 2 - C main program

&pagelevel(3)&pagelevel

This example uses the IEDTCMD interface and IEDTGET-interface to read and process the records in a file:

/********************************************************************/
/*                                                                  */
/* Example 2                                                        */
/*                                                                  */
/* This example uses the IEDTCMD interface                          */
/* to execute EDT statements and the IEDGET                         */
/* interface to read lines. All the records in a                    */
/* file which contains accounting data are output                   */
/* if they have an invoice date more than a                         */
/* predefined number of days before the current date.               */
/*                                                                  */
/*                                                                  */
/* The example program performs the following individual            */
/* actions:                                                         */
/*                                                                  */
/* 1) Determine the current date.                                   */
/* 2) Use the @COPY statement (Format 1) to read all the lines of   */
/*    the file together with their invoice dates into work area $0. */
/* 3) Execute a loop in which all the lines in work area            */
/*    $0 are read one after the other and calculate the time        */
/*    difference between the current date and the invoice date.     */
/*    If this time difference is greater than the predefined        */
/*    limit, then the customer number, invoice number and invoiced  */
/*    amount specified in this line are output.                     */
/* 4) Once this loop has terminated, EDT is terminated with the     */
/*    @HALT statement and the example program is then exited.       */
/*                                                                  */
/********************************************************************/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
/* Include files of the EDT subroutine interface */
#define EDT_V17
#include <iedtgle.h>
/* Create and initialize the EDT subroutine interface data  */
/* structures required for this example.                    */
static iedglcb glcb = IEDGLCB_INIT;
static iedupcb upcb = IEDUPCB_INIT;
static iedamcb amcb = IEDAMCB_INIT;
static iedbuff *command = NULL;
static iedbuff *message1 = NULL;
static iedbuff *message2 = NULL;
/* Definition of an output line */
typedef struct line
{
    char kdnr[8];         /* Customer number */
    char free1[2];
    char renr[8];         /* Invoice number  */
    char free2[2];
    char betr[10];        /* Invoice amount  */
    char free3[2];
    char day[2];          /* Day of invoicing   */
    char mon[2];          /* Month of invoicing */
    char trenn2[1];
    char year[4];         /* Year of invoicing  */
    char rest[215];
} LINE;
/********************************************************************/
/* Function: printrc                                                */
/*                                                                  */
/* Task:                                                            */
/* If EDT has returned an error message, then the error message     */
/* is output by this function.                                      */
/*                                                                  */
/* Parameter: errmsg   (IN)  Pointer to the additional error        */
/*                           message to be output if an error occurs*/
/*                                                                  */
/* Return value: none                                               */
/********************************************************************/
static void
printrc(char *errmsg)
{
    char message[81];
  if (glcb.IEDGLCB_RC_MAINCODE != 0)
    {
        printf("%s: %08x\n",errmsg,
         glcb.IEDGLCB_RC_NBR);/* Output passed error message */
        if (glcb.return_message.structured_msg.rmsgl > 0)
        {
            strncpy(message,(char*)glcb.return_message.structured_msg.rmsgf,
                glcb.return_message.structured_msg.rmsgl);
            message[glcb.return_message.structured_msg.rmsgl] = 0x00;
            printf("Meldungstext: %s\n",message);  /* Output EDT message */
        }
        exit(1);
    }
}
/********************************************************************/
/* Function: fill_buff                                              */
/*                                                                  */
/* Task:                                                            */
/* This function enters content and the record length field in a    */
/* record of variable length.                                       */
/*                                                                  */
/* Parameter: p:       (IN)  Pointer to a structure of type         */
/*                           iedbuff, which contains the variable   */
/*                           length record to be set.               */
/*            textp:   (IN)  Points to a string which contains the  */
/*                           text to be entered. The length         */
/*                           of the string implicitly defines the   */
/*                           record length (length of string + 4)   */
/*                                                                  */
/* Return value: none                                               */
/********************************************************************/
static void
fill_buff(iedbuff *p,char *textp)
{
    size_t l_text;                          /* Length of string */
    if ((l_text = strlen(textp)) > 2044)
        l_text = 2044;     /* Restrict length to 2044 characters   */
    strncpy((char *)p->text,textp,l_text);  /* Enter text          */
    p->length = l_text + 4;                 /* Enter record length */
}
/********************************************************************/
/* Function: edtcmd                                                 */
/*                                                                  */
/* Task:                                                            */
/* This function enters the passed strings in records of            */
/* variable lengths (DMS format) and then calls the EDT's           */
/* CMD interface.                                                   */
/*                                                                  */
/* Parameter: cmd:     (IN)  Pointer to a string which contains     */
/*                           the EDT statement(s) that are to be    */
/*                           executed. The length of the string     */
/*                           implicitly defines the record length   */
/*                           (String length + 4).                   */
/*            msg1:    (IN)  Pointer to a string which contains the */
/*                           text to be entered. The length         */
/*                           of the string implicitly defines the   */
/*                           record length (length of string + 4).  */
/*            msg2:    (IN)  Pointer to a string which contains the */
/*                           text to be entered. The length         */
/*                           of the string implicitly defines the   */
/*                           record length (length of string + 4).  */
/*                                                                  */
/* Return value: none                                               */
/********************************************************************/
static void
edtcmd(char *cmd,char *msg1,char *msg2)
{
    fill_buff(command,cmd);
    fill_buff(message1,msg1);
    fill_buff(message2,msg2);
    IEDTCMD(&glcb,&upcb,command,message1,message2);
}
/********************************************************************/
/* Function: edtget                                                 */
/*                                                                  */
/* Task:                                                            */
/* This function uses the subroutine interface's GET function       */
/* to read a line from work file $0. The read operation is always   */
/* performed relative to the record with line number 0.             */
/*                                                                  */
/* Parameter: rec:     (IN)  Pointer to a data area in which        */
/*                           the line read by the GET function      */
/*                           is stored.                             */
/*            disp:    (IN)  Specifies the displacement of the      */
/*                           line to be read from line number 0.    */
/* Return value: none                                               */
/********************************************************************/
static void
edtget(char *rec,int disp)
{
    char localfile[9] = "$0      ";
    iedbyte key1[8] = {0,0,0,0,0,0,0,0};
    iedbyte key[8] = {0,0,0,0,0,0,0,0};
    /* Enter values in IEDAMCB control block */
    IEDAMCB_SET_NO_MARKS(amcb);
    amcb.length_key_outbuffer = 8;
    amcb.length_rec_outbuffer = 256;
    amcb.length_key1 = 8;              /* -------------------------- (1) */
    amcb.displacement = disp;  /* read <disp> records after 0 */
    strncpy((char *)amcb.filename,localfile,8); /* Work file $0 */
    IEDTGET(&glcb,&amcb,key1,key,rec);
}
/********************************************************************/
/* Main program                                                     */
/********************************************************************/
int
main(void)
{
    char filename[] = "edt.rechnung2";
    char cmd[257];
    LINE zeile;
    int  disp;
    int  days = 20;
    int  time_diff;
    time_t zeit1;
    time_t zeit2;
    struct tm t;
    printf("\nStart Beispiel2\n\n");
    /* Provide buffer */
    command = (iedbuff *)malloc(2048);
    message1 = (iedbuff *)malloc(2048);
    message2 = (iedbuff *)malloc(2048);
    /* Determine current date */
    zeit1 = time((time_t *) 0);
    /* For the conversion of the date in the line */
    /* the time is set to 00.00                   */
    t.tm_sec = 0;
    t.tm_min = 0;
    t.tm_hour = 0;
    /* Read the file to be processed using   */
    /* the @COPY statement (format 1)        */
    sprintf(cmd,"COPY FILE=%s",filename);
    edtcmd(cmd,"","");
    printrc("Fehler bei der @COPY-Anweisung!");
    /* The following loop processes all the lines */
    /* in work file $0.                           */
    for (disp = 1; disp < 99999999; disp++)   /*-------------------- (2) */
    {
        /* Read next line */
        edtget((char *)&zeile,disp);
        printrc("Fehler bei der Funktion GET!");
        /* If reading goes beyond the last line number then */
        /* IEDTGET returns "last record"                    */
        if (glcb.IEDGLCB_RC_SUBCODE1 == IEDGLCBlast_record)
            break; /* Exit loop */
        t.tm_mday = atoi(zeile.day);          /* Fetch date from  */
        t.tm_mon = atoi(zeile.mon) - 1;       /* the read-in      */
        t.tm_year = atoi(zeile.year) - 1900;  /* line             */
        zeit2 = mktime(&t);                   /* Conv. date to    */
                                              /* time value       */
        /* Determine time difference in days */
        time_diff = difftime(zeit1,zeit2)/86400;
        /* If the predefined period has expired, output the    */
        /* customer number, invoice number and invoiced amount */
        /* for the current line.                               */
        if (time_diff > days)
        {
            zeile.free1[0] = '\0';   /* ---------------------------- (3) */
            zeile.free2[0] = '\0';
            zeile.free3[0] = '\0';
            printf("Kdnr.: %s, Rechn.nr.: %s, Betrag: %s Euro\n",
                 zeile.kdnr,zeile.renr,zeile.betr);
        }
    }
    /* Terminate EDT and program */
    edtcmd("HALT","","");
    printrc("Fehler bei der @HALT-Anweisung!");
    printf("\n\nEnde Beispiel2\n\n");
    return 0;
}

Explanations

(1)In the IEDTGET function it is only necessary to enter values for length_key1 and length_key_outbuffer.
(2)The method for the sequential reading of the work file implemented here is not particularly effective since it is always necessary to restart the read operation from the beginning again. Readers should consider how it might be possible to develop a more effective algorithm by using the key returned in key with a constant
amcb.displacement = +1.
(3)The end character for C strings is used here to permit direct output without conversion.

If the procedure explained in the section “Producing main programs in C” is stored in a file named CC.DO in BS2000 and the source file is stored as the S element BEISPIEL2.C in the library EDT.BEISPIELE then the above program can be compiled and linked with

/CALL-PROC CC.DO,(2).

The generated program can then be executed using

/START-EXECUTABLE-PROGRAM (E=BSP2C,L=EDT.BEISPIELE)

When CC.DO runs, the following or similar output is generated by the system or the compiler:

%  BLS0524 LLM 'SDFCC', VERSION '03.1A40' OF '2005-02-03 16:16:36' LOADED
%  BLS0551 COPYRIGHT (C) Fujitsu Siemens Computers GmbH 2005. ALL RIGHTS 
RESERVED
%  CDR9992 : BEGIN C/C++(BS2000/OSD) VERSION 03.1A40
%  CDR9907 : NOTES: 0  WARNINGS: 0  ERRORS: 0  FATALS: 0
%  CDR9937 : MODULES GENERATED, CPU TIME USED = 2.6000 SEC
%  BND3102 SOME WEAK EXTERNS UNRESOLVED
%  BND1501 LLM FORMAT: '1'
%  BND1101 BINDER NORMALLY TERMINATED. SEVERITY CLASS: 'UNRESOLVED EXTERNAL'
%  CDR9936 : END; SUMMARY: NOTES: 0  WARNINGS: 0  ERRORS: 0  FATALS: 0
%  CCM0998 CPU TIME USED: 3.6403 SECONDS

Let us assume that the file to be processed by this example program EDT.RECHNUNG2 resembles the following:

00347563  00028654     1378.89  21.05.2007
00345781  00027349    21500.00  07.04.2007
00375863  00028937      248.23  19.05.2007
00242365  00012358     4577.54  23.03.2007
00416467  00046687     6776.31  10.05.2007
00576373  00015463      578.00  19.04.2007
00785214  00053417    65465.00  13.12.2006
00265432  00065743     6534.67  16.05.2007
00546315  00035476      656.34  29.05.2007
00675436  00015334     7878.45  04.05.2007
00353466  00087227      654.24  11.11.2006
00534267  00067854    52346.00  15.05.2007
00243535  00078921     4532.54  22.04.2007
00783432  00063223      548.19  17.05.2007
00623556  00054342     5346.32  17.03.2007
00234354  00065233     4534.65  08.05.2007

When /START-EXECUTABLE-PROGRAM (E=BSP2C,L=EDT.BEISPIELE) is called (on 4.5.2007), the following or similar output is displayed:

%  BLS0523 ELEMENT 'BSP2C', VERSION '@', TYPE 'L' FROM LIBRARY ':A:$USER.EDT
.BEISPIELE' IN PROCESS
%  BLS0524 LLM '$LIB-ELEM$EDT$BEISPIELE$$BSP2C$$', VERSION ' ' OF '2007-05-04 
12
:22:24' LOADED
Start Beispiel2
Kdnr.: 00345781, Rechn.nr.: 00027349, Betrag:   21500.00 Euro
Kdnr.: 00242365, Rechn.nr.: 00012358, Betrag:    4577.54 Euro
Kdnr.: 00785214, Rechn.nr.: 00053417, Betrag:   65465.00 Euro
Kdnr.: 00353466, Rechn.nr.: 00087227, Betrag:     654.24 Euro
Kdnr.: 00623556, Rechn.nr.: 00054342, Betrag:    5346.32 Euro
Ende Beispiel  2
%  CCM0998 CPU TIME USED: 0.3276 SECONDS