3 Generic C programming

Two tools are provided for generic C programming. Which one to use depends on the nature of the C source code:

First create your generic code routines. These actually go into an include file that is conventionally named with extension .cgen. There are several macros defined for use when defining generic functions.

You need to use CGEN_FUNCTION as part of the normal function declaration so that generic forms of the function name can be generated on inclusion. Each routine in a generic include file should start:

  return_type CGEN_FUNCTION(function_name) ( arg decs )

So a routine called kpg1_bad that returned an int and accepted a CGEN_CTYPE pointer, called value, would be defined as:

      int CGEN_FUNCTION(kpg1_bad) (CGEN_CTYPE *value) {
          if ( value[0] == CGEN_BAD ) {
             return 1;
          }
          return 0;
      }

with the trivial job of testing the first element of an array against the BAD value constant.

The value of CGEN_TYPE will be set to the C type, that is double, float, int, short int, unsigned short int, char and unsigned char, as appropriate.

The value of CGEN_BAD will be set to one of the PRIMDAT constants VAL__BADD, VAL__BADR, VAL__BADI, VAL__BADW, VAL__BADUW, VAL__BADB or VAL__BADUB as appropriate, and the value of CGEN_HDS_TYPE will be set to the HDS type, one of _DOUBLE, _REAL, _INTEGER, _WORD, _UWORD, _BYTE or _UBYTE.

Now create a C file to includes the generic code. The include file is included once for each of the data types you want to support (this file can also contain related non-generic code). To do this define the macro CGEN_CODE_TYPE to be one of the values:

      CGEN_DOUBLE_TYPE, CGEN_FLOAT_TYPE, CGEN_INT_TYPE, CGEN_WORD_TYPE,
      CGEN_UWORD_TYPE, CGEN_BYTE_TYPE, CGEN_UBYTE_TYPE

which selects the data type. Then include the file cgeneric_defs.h followed by your generic include file, (called mygenerics.cgen in the following example):

  #include <prm_par.h>
  #include <cgeneric.h>
  
  #define CGEN_CODE_TYPE CGEN_DOUBLE_TYPE
  #include "cgeneric_defs.h"
  #include "mygenerics.cgen"
  #undef CGEN_CODE_TYPE
  
  #define CGEN_CODE_TYPE CGEN_INT_TYPE
  #include "cgeneric_defs.h"
  #include "mygenerics.cgen"
  #undef CGEN_CODE_TYPE

when compiled this will generate code for double precision and integer versions of the generic functions defined in mygeneric.cgen.

When you want to call the generic forms of a function, the name you supply to the CGEN_FUNCTION macro has one of character codes D, F, I, W, UW, B, and UB appended. So for our example kpg1_bad, we have the two functions kpg1_badD and kpg1_badI.

See the comments in the include files for descriptions of the other macros.