Trying to make "bilingual macros" between z/OS HLASM and XL C/C++ metal C compiler

363 Views Asked by At

I am trying to figure out how to include both HLASM and Metal C definitions for the same DSECT/struct in a single dataset/file.

Before trying this, I tried what I described in How do I go about making this work with a #include? It works fine when dropped straight into the code

So, I went down another path and figured I could use a #define to alter the MACRO statement within the assembler to something that the C compiler would use:

  • Change "MACRO" to "#pragma margins(2,72)"
  • Change "MEND" to "#pragma nomargins"

    EDIT       SSAF.METALC.H(CKKTEST) - 01.01                          Columns 00001 00080 
    Command ===>                                                          Scroll ===> CSR  
    ****** ********************************* Top of Data **********************************
    000001          MACRO                                                                  
    000002 */* First line of macro prolog                                       */         
    000003 */* Last line of macro prolog                                        */         
    000004 *#if 0!=0                               // Bypass asm in C                      
    000005 Test     DSECT                                                                  
    000006 Test@    DS A                                                                   
    000007 TestINT  DS F                                                                   
    000008 TestChar DS C                                                                   
    000009 *#endif                                                                         
    000010  MEND                                                                           
    000011 struct Test {                                                                   
    000012   void *Test@;                                                                  
    000013   int TestInt;                                                                  
    000014   char TestChar;                                                                
    000015 };                                                                              
    ****** ******************************** Bottom of Data ********************************
    

And I figured that I could use #define to change "MACRO" and "MEND" to stuff that the C compiler would like, first I tried with no quotes:

    EDIT       SSAF.METALC.C(CKLTHING) - 01.01                         Columns 00001 00080 
    Command ===>                                                          Scroll ===> CSR  
    000207 #define MACRO #pragma margins(2,72)                                          
    000208 #define MEND #pragma nomargins                                              
    000209 #include"ckktest.h"                                                             

Which did not yield the desired results:

    |
      207       |#define MACRO #pragma margins(2,72)                                         
      208       |#define MEND #pragma nomargins                                              
      209       |#include"ckktest.h"                                                         
    *=ERROR===========>     CCN3191 The character # is not a valid C source character.       
    *=ERROR===========>     CCN3166 Definition of function pragma requires parentheses.      
    *=ERROR===========>     CCN3191 The character # is not a valid C source character.       
    *=ERROR===========>     CCN3191 The character # is not a valid C source character.       
    *=ERROR===========>     CCN3191 The character # is not a valid C source character.       
    *=ERROR===========>     CCN3276 Syntax error: possible missing '{'?                                            

Then I tried enclosing the #define value in quotes:

      207       |#define MACRO "#pragma margins(2,72)"                                       
      208       |#define MEND "#pragma nomargins"                                            
      209       |#include"ckktest.h"                                                         
    *=ERROR===========>     CCN3191 The character # is not a valid C source character.       
    *=ERROR===========>     CCN3191 The character # is not a valid C source character.       
      210       |                                                                            

This gives fewer error messages, but is still not what I need.

Note: the # I'm using is EBCDIC 7B.

The description for the error message is rather terse:

CCN3191 The character &1 is not a valid C source character. Explanation Refer to the C/C++ Language Reference for information on valid characters.

In the message text:

&1 is a character.

User response Change the character.

I referred to the C/C++ Language Reference and could not find anything that says I can't use a "#" inside a #define. As a matter of fact there are some words about the # and ## operators...

Is there a way to get around this?

Thanks, Scott

1

There are 1 best solutions below

3
S Perry On

Scott, the problem is that macro's can't expand into preprocessing directives. I'm guessing from the header you want to define the struct definition in one place and use it in hlasm and C/C++. I suggest looking at the dsect tool. This tool produces a C struct declaration from the DSECT declarations in the hlasm file. This could give an solution.

Another option using macro tricks is something like this for ckktest.h:

StructStart(Test)
MbrAddr(Test@)
MbrInt(TestINT)
MbrByte(TestChar)
StructEnd

In the C source you would include with:

#define StructStart(s) struct s {
#define MbrAddr(m) void *m;
#define MbrInt(m) int m;
#define MbrByte(m) char m;
#define StructEnd };
#include "ckktest.h"

And tend similar in hlasm.

I'd look at the dsect tool as it would give the mapping from hlasm to C and enable you to maintain one definition. Your makefile will have one extra rule to create the C header from the hlasm code using the dsect tool.