Re: sqlexit call under 4GL/ESQL
Posted in 1997
>From: rfredet@medicode.com (Rodney R. Fredette) >Date: Tue, 07 Jan 1997 15:40:24 GMT >X-Informix-List-Id: <news.32315> > >A 4th equall unpleasent option is one that I use (on a unix box) is to use >SED to make a change to the '.ec' code before it is passed to the 'C' compiler >as follows: > >c4gl -e foo.4gl <may need -keep to prevent the .ec file from being removed> >fix_ec foo.ec >c4gl foo.ec -o foo.4ge > >where fix_ec has: > >sed s/"fgl_nret = sqlexit(0)"/"sqlexit();fgl_nret=0"/ $1 > tmp >mv tmp $1 > >I'm not sure which method is best, but I already use the fix_ec script to make >other changes to allow dynamic page lengths, so adding one more line was no >big deal. This works, but isn't very nice. There is code in the IIUG archives (at http://www.iiug.org) which handles dynamic page lengths for reports without having to modify the compilation sequence, and that code also works with p-code. One feature of the quoted solution is that it uses the c4gl script for both stages of the compilation. Good! Anything else won't work reliably. >In article <32D0F9BC.3821@erols.com>, plkapp@erols.com says... >>We have recently made the jump from RDS 4.x (SunOS 4.1/OnLine 5.01) to >>RDS6.x (Solaris 2.5/OnLine 7.21) and had some problem with calls to >>sqlexit from 4GL. It seems that the new 4GL version of sqlhdr.h will >>declare sqlexit as void sqlexit();, but the ESQL version of the same >>sqlhdr.h file declares it as int sqlexit(); No I4GL code should ever call sqlexit() directly, notwithstanding the fact that the documentation implies that it can happen. That is a bug in the documentation. The interface to sqlexit() is not compatible with the interface of C functions called from I4GL. Every C function called in I4GL (where you write the call) has the interface: extern int c_function(int nargs); Therefore, you should write and use a C interface function such as: int i4gl_sqlexit(int nargs) { if (nargs != 0) fgl_fatal("i4gl_sqlexit", 1, -1318); sqlexit(); return(0); } and in the I4GL code, you then write: CALL i4gl_sqlexit() The sqlexit() function IS variously defined as returning an int or void, depending on the version of ESQL/C you are using, but this should not matter either. You should compile any ESQL/C code to be embedded in your I4GL program using the c4gl script, so that you get the correct code generated. Anything else is error prone unless you happen to be using a 4.1x version of Engines, ESQL/C *and* I4GL. >>When using c4gl, and the C compiler in ANSI-mode, any program that uses >>sqlexit will not compile, since 4gl attempts to assign the return code >>to an int variable, but the C compiler is being told that sqlexit does >>not return any value. You should not be calling sqlexito directly in I4GL, so this should not be a problem. The fact that you are getting an error highlights the more fundamental problem. Do not forget that the nargs parameter tells the called function how many arguments were pushed onto the I4GL stack, and that the returned value tells I4GL how many arguments to pop off the I4GL stack. If you ever got something other than zero returned by sqlexit(), then you might find an arbitrarily large number of arguments being popped, because sqlexit() does NOT know about the I4GL calling conventions -- it is an ESQL/C function. >>It seems we have three options: >>1) Edit the sqlhdr.h file and change the return type from void to int Don't edit standard header files unless you are sure you know what you are doing. Yes, it will stop the C compiler from bitching, but it won't prevent your code from misbehaving under extreme circumstances. >>2) Don't set the C compiler flag to compile in ANSI C. This will >>prevent __STDC__ from being defined, an the function declaration for >>sqlexit (and ALL the function prototypes) will automatically be ifdef'd >>away, resulting in the compiler ASSUMING that sqlexit's return type is >>int, so the code will compile. This is a valid option, though you should be able to compile with __STDC__ set. >>3) Write an esql/c interface program that handles the call to sqlexit >>under ESQL/C with the function that returns int. This is the correct solution -- see above. >>A problem with all of these options is the actual linked version of >>sqlexit is probably from the 4GL library, not the ESQL library. Actually, sqlexit() does come from the ESQL/C library, even though it is found in a library under $INFORMIXDIR/lib/tools. If you have early enough versions of I4GL 4.1x, then sqlexit() appeared to be in an I4GL-specific library, but the code for sqlexit() was actually extracted from the ESQL/C library and put into the I4GL library. >>Can anybody shed some light as to what is really going on here? I hope I've illuminated the situation a bit. Yours, Jonathan Leffler (johnl@informix.com) #include <disclaimer.h>