Topic
  • No replies
Maksymas
Maksymas
9 Posts

Pinned topic Packed to unpacked format

‏2010-09-22T09:56:34Z |
Dear Developers,
This is my first thread in the site.
I have a scenario in which i need to convert the packed format to unpacked format in C programs
How can it be done..

For example
consider a cobol copybook having
01 Var01
02 var0101 pic S(9) comp-3
02 var0102 pic S(2) comp-3
02 var0103 pic X(4)

this cobol copybook is populated with values in a COBOL library and passed to a C program.
In C program
We have struct as
struct var01
{
char var0101[5];
char var0102[2];
char var0103[4];
}

But the variable which are in comp3 format has to be converted to display format and populated in the above structure.

How this can be done..

Can you guys please help me solve this..

Thanks
Maksymas.
Updated on 2010-10-08T07:51:53Z at 2010-10-08T07:51:53Z by Maksymas
  • timhahn
    timhahn
    5 Posts

    Re: Packed to unpacked format

    ‏2010-09-22T20:40:12Z  
    Hello Maksymas,

    There are several ways to solve this. To provide you the best answer, please clarify what you are intending to do in the C code with the COMP-3 data values. Are you expecting to use them as C/C++ primitive integer types? Or are you looking to use unpacked decimal types in C code?

    Also, did you mean PIC S9(9) and PIC S9(2) for the first two COBOL structure members?

    There is support in the IBM C compiler for decimal data types which can be used. These types are used as follows:

    #include <decimal.h>
    ...
    decimal(9,2) x; /* nine digit decimal number with 2 digits after the decimal point */
    decimal(3,2) y; /* three digit decimal number with 2 digits after the decimal point */
    ...

    A reference for more information on these is here: http://publibz.boulder.ibm.com/epubs/pdf/cbcpg1a0.pdf

    If you are looking to use int or float primitive C language types, then a conversion using some utility functions will be required.

    Tim Hahn
  • raym
    raym
    7 Posts

    Re: Packed to unpacked format

    ‏2010-09-22T21:46:41Z  
    Maksymas,

    You can use packed-decimal data type in C. The sample code below shows one way of passing arguments from COBOL to C.
    Assuming you are under z/OS Unix, compile the source files as follows.

    c89 -Wc,"lang(extended)" -c d1.c
    cob2 c1.cbl d1.o
    a.out

    It gives the following output:

    =-=-=-=-=-=-=-=-=-=-=-=-=
    var0101=12345
    var0101=56
    var0103=ABCD
    in cobol var0102=36
    =-=-=-=-=-=-=-=-=-=-=-=-=

    In C, if you want to convert packed-decimal data into a character string, you can use the sprint function:

    char buff128;
    ...
    sprintf ( buff, "%D(9,0)", p->var0101);

    This gives the same string as printf. Additional code is needed if you need leading zeros, etc.

    You can also convert the packed-decimal type to int, or floating point directly:

    int varInt;
    double varDouble;
    ...
    varInt = p->var0102;
    varDouble = p->var0101;
    Below are the sample source files.

    <c1.cbl>
    Identification division.
    Program-id. C1.
    Data division.
    Working-storage section.

    01 var01.
    03 var0101 pic s9(9) comp-3.
    03 var0102 pic s9(2) comp-3.
    02 var0103 pic x(4).

    Procedure division.

    move 12345 to var0101.
    move 56 to var0102.
    move 'ABCD' to var0103.

    call 'FOO' using var01.

    DISPLAY 'in cobol var0102=' var0102.
    Goback.
    </c1.cbl>
    <d1.c>
    #include <decimal.h>

    struct S {
    decimal(9,0) var0101;
    decimal(2,0) var0102;
    char var0103[4];
    };

    void FOO(struct S *p) {

    printf("var0101=%D(9,0)\n", p->var0101);
    printf("var0101=%D(2,0)\n", p->var0102);
    printf("var0103=%4.4s\n", p->var0103);

    p->var0102 = 36;
    }
    </d1.c>

    Thanks.
    Regards,
    Raymond Mak
  • Maksymas
    Maksymas
    9 Posts

    Re: Packed to unpacked format

    ‏2010-09-23T16:35:00Z  
    Dear All

    Thanks a lot for the responses..

    Actually i need to first clarify my requirements.

    I have S9(6) comp-3 and S9(2) comp-3 variables.
    In which ,
    the data would be like
    for S9(6) comp-3
    0356
    134F

    for S9(2) comp-3
    02
    4F

    Where F is the signed bit..hence total memory it occupy is 6 bytes

    In C,

    I need this value to be stored in the group variable as
    for 1st variable => 133546
    for 2nd variable => 42
    hence the total memory occupied is 6+2 = 8 bytes.
    How can it be done in C with out writing a user defined utility

    Note: We are using Z/os

    Thanks
    Maksymas
  • raym
    raym
    7 Posts

    Re: Packed to unpacked format

    ‏2010-09-24T00:44:52Z  
    • Maksymas
    • ‏2010-09-23T16:35:00Z
    Dear All

    Thanks a lot for the responses..

    Actually i need to first clarify my requirements.

    I have S9(6) comp-3 and S9(2) comp-3 variables.
    In which ,
    the data would be like
    for S9(6) comp-3
    0356
    134F

    for S9(2) comp-3
    02
    4F

    Where F is the signed bit..hence total memory it occupy is 6 bytes

    In C,

    I need this value to be stored in the group variable as
    for 1st variable => 133546
    for 2nd variable => 42
    hence the total memory occupied is 6+2 = 8 bytes.
    How can it be done in C with out writing a user defined utility

    Note: We are using Z/os

    Thanks
    Maksymas
    Maksymas,
    You can receive packed-decimal data in C, and then convert the data to character string. Suppose the code below is how you want to call the C function:

    01 var01.
    03 var0101 pic s9(6) comp-3.
    03 var0102 pic s9(2) comp-3.
    ...

    CALL FOO USING var01.

    The C function name is FOO. On the C side, you need a C function with the following prototype to receive the parameter:

    #include <decimal.h>

    struct S {
    decimal(6,0) var0101;
    decimal(2,0) var0102;
    };

    void FOO ( struct S *p) {
    ...
    }

    Then convert the packed-decimal data into character string. Declare a C struct as follows:

    struct T {
    char f1[6];
    char f2[2];
    } t;

    char work20; /* a working variable */

    Use the sprintf function to convert packed-decimal data to character string:

    sprintf(work, "%6D(6,0)", p->var0101); /* note that sprintf puts a null character at the end of the string */
    memcpy(t.f1, work, 6); /* copy the 6 characters from work to f1 */
    sprintf(work, "%2D(2,0)", p->var0102);
    memcpy(t.f2, work, 2); /* copy the 2 characters from work to f2 */

    The data is now in the t struct variable.
    Note that leading zeros are suppressed in the sprintf converted string. Also, if the decimal data is negative, for pic s9(6), the maximum length of the character string is 7. A C variable with 6 characters may not be sufficient.

    For more information about packed-decimal in C, please refer to the XL C/C++ Programming Guide, "Using decimal data types in C", http://publibz.boulder.ibm.com/epubs/pdf/cbcpg1b0.pdf (chapter 26).

    Hope that this helps.
    Thanks.
    Regards,
    Raymond Mak
  • Maksymas
    Maksymas
    9 Posts

    Re: Packed to unpacked format

    ‏2010-09-24T07:02:01Z  
    Dear Raymond Mak,

    Thanks a lot for your help.
    I can understand now.
    I tried to test with decimal macro..
    But i am getting a compilation error

    here is my prog

    #include<stdio.h>
    #include<math.h>
    #include <memory.h >
    #include <decimal.h >
    struct S{
    decimal(6,0) var0101;
    decimal(2,0) var0102;
    char var0103[4];
    } st;
    int main()
    {
    printf("\n TEST1:9(1) COMP 3");
    }
    The error is "CCN5063 (S) The text "6" is unexpected"

    Is there any thing i need to modify in compiler options?

    Thanks
    Maksymas.
  • timhahn
    timhahn
    5 Posts

    Re: Packed to unpacked format

    ‏2010-09-24T12:40:29Z  
    • Maksymas
    • ‏2010-09-24T07:02:01Z
    Dear Raymond Mak,

    Thanks a lot for your help.
    I can understand now.
    I tried to test with decimal macro..
    But i am getting a compilation error

    here is my prog

    #include<stdio.h>
    #include<math.h>
    #include <memory.h >
    #include <decimal.h >
    struct S{
    decimal(6,0) var0101;
    decimal(2,0) var0102;
    char var0103[4];
    } st;
    int main()
    {
    printf("\n TEST1:9(1) COMP 3");
    }
    The error is "CCN5063 (S) The text "6" is unexpected"

    Is there any thing i need to modify in compiler options?

    Thanks
    Maksymas.
    Maksymas,

    You do need to use LANGLVL(EXTENDED) in the compiler options.

    Refer here: http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/CBCPG1A0/4.6?SHELF=CBCBS1A0&DT=20090606065305 for more information on using the decimal types.

    Tim Hahn
  • raym
    raym
    7 Posts

    Re: Packed to unpacked format

    ‏2010-09-24T13:34:10Z  
    • timhahn
    • ‏2010-09-24T12:40:29Z
    Maksymas,

    You do need to use LANGLVL(EXTENDED) in the compiler options.

    Refer here: http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/CBCPG1A0/4.6?SHELF=CBCBS1A0&DT=20090606065305 for more information on using the decimal types.

    Tim Hahn
    Maksymas,
    If you are running under z/OS Unix, you can compile with
    c89 -Wc,"LANGLVL(EXTENDED)" hello.c -ohello

    or, if you want to create a load module in a PDS:

    c89 -Wc,"LANGLVL(EXTENDED)" hello.c -o"//'<fully-qualified-pds>(HELLO)'"

    Note that it is not necessary to convert packed-decimal data to a character string in C before doing further processing. If the main purpose in the C side is doing some number crunching computations, you can use the packed-decimal data directly in expressions. Or you can convert them to floating point, or int types.

    Thanks.
    Regards,
    Raymond
  • Maksymas
    Maksymas
    9 Posts

    Re: Packed to unpacked format

    ‏2010-10-06T05:18:43Z  
    Hi Raymond,

    I tried adding the compiler option LANGLVL(EXTENDED)
    As i already mention I am using XLC - inwhich i found that there is LANGLVL option but there is no extended sub-option for this

    can you please help?
    Thanks
    Maksymas
  • raym
    raym
    7 Posts

    Re: Packed to unpacked format

    ‏2010-10-06T15:06:58Z  
    • Maksymas
    • ‏2010-10-06T05:18:43Z
    Hi Raymond,

    I tried adding the compiler option LANGLVL(EXTENDED)
    As i already mention I am using XLC - inwhich i found that there is LANGLVL option but there is no extended sub-option for this

    can you please help?
    Thanks
    Maksymas
    Maksymas,
    Can you cut-and-paste the command line which you were using to compile the program ?
    For example, is it something like (under z/OS UNIX):

    xlc -c prog.c

    or

    c89 -c prog.c

    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    You can pass compiler options in the xlc or c89 utilities using the -W flag:

    xlc -Wc,"LANGLVL(EXTENDED)" -c prog.c

    after -Wc, within quotes, is the string of compiler options. All the options described in the User's Guide are accepted. The option syntax is the same as in a JCL compilation.

    (However ... if you are using xlc, the default for LANGLVL is already EXTENDED. So xlc -c prog.c should work. I wonder why you were getting a syntax error. The default for c89 is LANGLVL(ANSI) (ansi c89 standard).)

    Thanks.
    Regards,
    Raymond Mak
  • Maksymas
    Maksymas
    9 Posts

    Re: Packed to unpacked format

    ‏2010-10-07T07:47:08Z  
    Dear Raymond,

    Thanks a lot for your patience..
    We are using Mainframe/zos/xlc c++ compiler
    here when i checked the compile listing :
    LANGLVL(ANONSTRUCT,ANONUNION,ANSIFOR,ANSISINIT,C99VLA,C99__FUNC__,NODBCS,NODOLLARINNAMES,
    EMPTYSTRUCT,ILLPTOM,IMPLICITINT,LIBEXT,LONGLONG,NONEWEXCP,OFFSETNONPOD,NOOLDDIGRAPH,OLDFRIEND,
    NOOLDMATH,NOOLDSTR,OLDTEMPACC,NOOLDTMPLALIGN,OLDTMPLSPEC,TRAILENUM,TYPEDEFCLASS,NOUCS,
    GNU_INCLUDE_NEXT,ZEROEXTARRAY)
    these are the options i get for LANGLVL

    I checked the proc... we are passing

    SOURCE,LIST,LONGNAME,DLL,BOOL'
    'XREF,SHOWINC',
    these option is compilation

    CPP,NOS,CICS,LIST,SP
    these options in translation ..

    Now where should I add the compiler options
    Am i going in the correct path..
    PLease suggest

    Thanks a lot, Maksymas.
  • raym
    raym
    7 Posts

    Re: Packed to unpacked format

    ‏2010-10-07T16:17:31Z  
    • Maksymas
    • ‏2010-10-07T07:47:08Z
    Dear Raymond,

    Thanks a lot for your patience..
    We are using Mainframe/zos/xlc c++ compiler
    here when i checked the compile listing :
    LANGLVL(ANONSTRUCT,ANONUNION,ANSIFOR,ANSISINIT,C99VLA,C99__FUNC__,NODBCS,NODOLLARINNAMES,
    EMPTYSTRUCT,ILLPTOM,IMPLICITINT,LIBEXT,LONGLONG,NONEWEXCP,OFFSETNONPOD,NOOLDDIGRAPH,OLDFRIEND,
    NOOLDMATH,NOOLDSTR,OLDTEMPACC,NOOLDTMPLALIGN,OLDTMPLSPEC,TRAILENUM,TYPEDEFCLASS,NOUCS,
    GNU_INCLUDE_NEXT,ZEROEXTARRAY)
    these are the options i get for LANGLVL

    I checked the proc... we are passing

    SOURCE,LIST,LONGNAME,DLL,BOOL'
    'XREF,SHOWINC',
    these option is compilation

    CPP,NOS,CICS,LIST,SP
    these options in translation ..

    Now where should I add the compiler options
    Am i going in the correct path..
    PLease suggest

    Thanks a lot, Maksymas.
    Maksymas,
    The C++ compiler doesn't support packed-decimal. The C compiler does. In the PROC, you can add LANGLVL(EXTENDED) before the SOURCE option in the PARM, something like:

    'LANGLVL(EXTENDED),SOURCE,LIST,LONGNAME,DLL, ...'

    Note: Use the EDCxxx PROCs instead of the CBCxxx PROCs. The CBC PROCs are for C++; the EDC ones are for C.

    Thanks
    Regards,
    Raymond Mak
  • Maksymas
    Maksymas
    9 Posts

    Re: Packed to unpacked format

    ‏2010-10-08T07:51:53Z  
    Thanks a lot Raymond
    It worked fine

    -Maksymas