A Better Way To Write Pick/Browse Lists [2/4]
Posted in 1993
Our first version of the general_view_screen system was extremely awkward, due primarily to the lack of function pointers in 4gl. (I will spare you the evolutionary details.) We conclude that function pointers, or a similar mechanism, is necessary. So I wrote one. The C function tb_fneval(..., funcname) pops the string funcname and interprets it as the name of a 4gl function. It scans the symbol table (programs cannot be stripped), finds the function name, reads the location, and calls that 4gl function, leaving the remaining arguments on the stack, as though the call-ing function had invoked the call-ed function directly. The initial lookup can be slow for large symbol tables (not much I can do about that), but subsequent references to that function are instantaneous because I cache all function name/location pairs. Thus the name of the function (as a string) is the function pointer. The system is not perfect. Symbol tables must be retained, and each program must be able to (reliably) read itself. We force all programs to be run with absolute paths, so tb_fneval knows right where to go for the symbol table. This affects our users not at all since we put the absolute path of the application in their .profiles, but it sometimes annoys us. When you build a test version of the program foo, you must invoke it via ./foo. A small price to pay for function pointers. Another problem is the (theoretically helpful) compile time 4gl argument consistency checks. Call tb_fneval with different numbers of parameters or returns from the same file, and 4gl generates an error, even though that is exactly what you want to do. We have simply broken our code up into smaller files and functions, so that this never happens. Most people never use this function directly, so its compile time drawbacks are not a problem. Instead, they call the general_view_screen mechanism, and tell it that, upon f6, it should fetch the current row and call "whatever_f6()". The actual tb_fneval calls are buried inside our gvs code. This function pointer capability is a critical first step towards a general, flexible screen development system. -- I do more all day -- than most people do before 9 A.M. Karl Dahlke eklhad@siss81.sis.rpslmc.edu (312) 942-8040