I was writing a program to display information about a RACF keyring, using the RACF callable services. RACF provides a mapping for the structures – but this is an assembler macro, and no C header file is available.
Instead of crafting the header file by hand, I thought I would try the C DSECT conversion utility. This was pretty easy to use (once I had got it working!). But not 100% reliable.
The JCL is
//COLINZP JOB 1,MSGCLASS=H // JCLLIB ORDER=CBC.SCCNPRC //DSECT EXEC PROC=EDCDSECT, // INFILE=COLIN.C.SOURCE(DSECTA), // OUTFILE=COLIN.C.H.VB(TESTASM), // DPARM='EQU(BIT),LP64' /*
The LP64 tells it to generate the header file for an LP64 program. It will generate pointers with __ptr32.
COLIN.C.SOURCE(DSECTA) has
AAAAA CSECT * IRRPCOMP AAA DS CL4 EYE CATCHER ABBB DC CL4'ABBB' END
The name of the structure is taken from the CSECT or DSECT the code is in. The above code produces
#pragma pack(packed) struct aaaaa { unsigned char aaa[4]; /* EYE CATCHER */ unsigned char abbb[4]; }; #pragma pack(reset)
You needed an output dataset with Variable Blocked format. When I used a fixed block, the output was in columns 1 to 79, but by default C reads columns 1-72 for a Fixed Block file.
The JCL invokes the HLASM, and creates an ADATA file. This file has information about all of the data and instructions used. This ADATA file is passed through the CCNEDSCT program which generates C source from the ADATA information.
There are many negative comments in the internet about CCNEDSCT. For example it does not pass block comments through.
I found it a bit buggy.
The source
AAAAA CSECT AAA DS CL4 EYE CATCHER ABBB DC CL4'ABBB' ACCC DC CL4'ACCC' ASIZE EQU *-AAA END
gave me
#pragma pack(packed) struct aaaaa { unsigned char aaa[4]; /* EYE CATCHER */ unsigned char abbb[4]; unsigned int : 4, asize : 2, : 26; }; #pragma pack(reset)
Which is clearly wrong, as it is missing variable ACCC, and ASIZE is a bit field within an integer.
More information about ADATA.
The data is laid out as described in macro (on my system) HLA.SASMMAC1(ASMADATA).