"C function library for x4gl" documentation consists of two documents; this one - "Introduction" and Catalogue of functions by source file.
This software was originally developed by Andrew Hamm and donated to OpenSource environment of Aubit 4gl project, under LGPL GNU license. It has a dedicated mailing list hosted at Aubit mailing lists home page.
support is provided via mailing list. At the moment, this software is available only in Source code form, and only directly from CVS. Please see CVS instructions on Aubit project CVS home page.
Most of the functions are in production but some are "good ideas" and may not be 100% correct or may not be 100% elegant. If anyone wants to use them straight away please e-mail me for an opinion. I'll either say "yup - they're good" or "I'm not happy with that one so give me 10 minutes." You'll probably be able to work out the quality of the straight-forward ones anyway.
Noises made recently on the Informix newsgroup have prodded a few people into collating a public collection of C functions. This page is the beginning of my part in the effort.
NOTE: Strictly speaking, 4GL for C compiling is called simply "4GL" and 4GL p-code is called 4GL RDS. However, to be completely clear during any discussion, I'll call them 4GL/C and 4GL/RDS.
Aubit 4GL and other 3rd party 4GL compilers may be automatically supported (perhaps with a little effort) depending on their compatibility with the internals of Informix 4GL. Part of this project could be to adapt the functions for these other products (by putting them on a piece of wood and banging a few nails through them?) This will of course have to be performed by interested parties.
* NOTE: Four J's have stated they will remove their support for C compiled 4GL. This was what I heard a year ago anyway... things might have changed since then. Check with Four J's for more accurate information.
The new printf set of functions were developed by Art S. Kagel, long-time resident of the Informix newsgroup. Once again, pay due respect to any copyright requirements.
At a guess, Jonathan Leffler might contribute something, even if it's only good advice, and I know Andrej Falout will be getting involved. Everyone is invited to participate, especially if you have any interesting functions of your own, or if you are involved with Yet Another 4GL Compiler (YA4C)
Informix, and to a greater extent Four J's, have added some functions to 4GL and they usually start with fgl_. Therefore I consider fgl_ to be a reserved name space, however other people do not. They reason that if Informix ever implements their own version of the functions then the private versions become redundant. That's very true assuming the Informix versions cover all the same functionality. More to the point, the rate of change of 4GL is so slow that you could almost say there will never be a conflict.
All the functions start with c_ and internal functions (ie private to the 4GL library but external in scope) have all been prefixed by cfgl_.
Although it's a generally overblown issue, it still needs light debate so do your best...
All .c files include cfun4gl.h which contains universal #includes and definitions. You'll find defines for many things including a few macros that help to extract some intelligence from the source using Perl scripts.
A file called cfun4gl.c contains the bulk of the support functions. Some support functions are local static in the individual .c file because they have no other use.
The recent printf functions have violated that rule because they have a really difficult job to do. They don't work for Four J's because they are using a different internal stack structure. Looks like we'll be writing a full printf from scratch. Sounds horrible but I did it once when I was a young programmer so can't be that hard to do it again. At least we'll be able to boast a version of printf which is truly portable. I don't think we need to implement 100% of the full C printf.
The script functions.pl performs this dutyes:
See the .c files mentioned to get a feel for it.
This Perl script looks for the function macro lines, and also looks for the optional RUNNER macros in the .c files. These macros are described in cfun4gl.h and maybe here in more detail one day if someone has a question.
Informix 4GL and Four J's support variable argument lists and variable return lists so generally we can achieve our needs for some C functions which are vararg. One or two functions are pathologically difficult so their ambiguity is corrected using some ugly little booster arguments. The need for this is extremely rare, however.
The other kind of error handling is more ordinary. If you attempt to open a file but it doesn't exist, then this failure should be returned to the calling code. If you attempt to open a file with 15 parameters on the function call, then that's clearly a usage error so the first response is more appropriate.
Most if not all low-level UNIX system calls return -1 for error and leave an error number in a variable called "errno". Higher level C functions from the standard libraries have "personalized" error conventions.
Currently the affected functions all record errno into a private variable which can be queried by a simple function call. I would like to look into doing something clever which stuffs the errno value (or other errors) into the 4GL status variable. Jonathan Leffler could probably advise on that, but even if it's possible with Informix, it must also be possible with Four J's and to a lesser extent with other YA4C.
Personally I feel that beyond Informix and Four J's, other 4GL systems should not hold our work to ransom, and it's a good opportunity for them to become more compatible anyway. Some might say Four J's does not deserve special status either, but they are the 2nd-biggest player with many customers.
let x = c_errno() if x = 27 then ....because 27 may be 28 on a different platform.
Defining symbolic constants through 4GL global variables is not good enough because they will have to be initialized differently depending on the platform the 4GL is delivered to. We supply several different platforms so we could not take advantage of the 4GL portability if we were forced into this. (Ed: this is probably a job for Autoconf)
Using a 4GL preprocessor to define constants (we have a 4GL preprocessor which supports constants and typedefs) is not adequate either because ultimately the constants will be mapped to simple numbers and once again the hard-coded, platform dependent numbers would be embedded in the RDS p-code.
To solve this problem, I've written a support function and defined a simple convention for passing constants back to 4GL. For any package that needs constants (and so far that's errno and the network socket functions) there will be a function available to 4GL called (for example) c__errno("str"). Note the double underscore. The string argument is a representation of the C constant - for example, c__errno("ENODIR").
Within the C library, we define a simple array (sorted by string name) which associates the string with the proper value. By the magic of the C compiler's preprocessor, the string will be mapped to the correct value using a simple (and fast) binary search of the array. Our happy 4GL programmers can now write:
let x = c_errno() if x = c__errno("ENODIR") then ....
If anyone thinks they have a performance problem with this in 4GL, they can assign a bunch of 4GL globals with their favorite values somewhere very early in MAIN. Frankly I think that would be excessive and pointless.
The best way to get involved is to subscribe to the mailing list, as the first step. There, you can discuss issues you have, and ask for CVS read/write permissions if there is something you want to contribute to source code or documentation.
This are some initial items on our TODO list:
Of course, your suggestions are welcome, and your participation appreciated.
See you on the mailing list!