NULL handing
Handling NULL in C-Extensions.
Variables passed from the BDL code can be checked for NULL
depending on
the data type.
Define macros as follows to check for
NULL
values:#define MY_IS_NULL_SMALLFLOAT(v) (isnan(v))
#define MY_IS_NULL_FLOAT(v) (isnan(v))
#define MY_IS_NULL_INTEGER(v) ((unsigned) v == 0x80000000)
#define MY_IS_NULL_SMALLINT(v) ((unsigned) v == 0x800)
#define MY_IS_NULL_CHAR(v) (v[0] == '\0')
#define MY_IS_NULL_DECIMAL(v) (v.dec_pos < 0)
#define MY_IS_NULL_DATETIME(v) (v.dt_dec.dec_pos < 0)
#define MY_IS_NULL_INTERVAL(v) (v.in_dec.dec_pos < 0)
#define MY_IS_NULL_LOCATOR(v) (v.loc_indicator < 0)
To return a
NULL
value from your C extension function, push an empty string on
the stack as follows:pushquote("", 0);
Example
C Extension source (ext1.c):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "f2c/fglExt.h"
int check_null(int);
UsrFunction usrFunctions[]={
{ "check_null", check_null, 1, 1 },
{ NULL, NULL, 0, 0 }
};
#define MY_IS_NULL_DECIMAL(v) (v.dec_pos < 0)
int check_null( int pc )
{
dec_t price;
const char *answer;
int len;
if (pc != 1) exit(1);
popdec(&price);
if (MY_IS_NULL_DECIMAL(price)) {
answer = "This decimal is NULL";
} else {
answer = "This decimal is not NULL";
}
len = (int) strlen(answer);
pushquote(answer, len);
return 1;
}
Genero program
(main.4gl):
IMPORT libext1
MAIN
DEFINE d DECIMAL(10,2)
LET d = NULL
DISPLAY check_null(d)
LET d = 12.34
DISPLAY check_null(d)
END MAIN
Commands to compile and execute (on
Linux):
$ gcc -fPIC -c ext1.c -I $FGLDIR/include
$ gcc --shared -o libext1.so ext1.o -L$FGLDIR/lib -lfgl
$ fglcomp main.4gl
$ fglrun main.42m
This decimal is NULL
This decimal is not NULL