Minimal requirements for script interpreter libs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This document describes the minimal requirements a script interpreter needs to fulfil before a fully function GPMI module can be developed with it. Function names are examples only. Points marked with * are optional but are strongly recommended. Points marked with + are optional, and indifferent for GPMI. Points marked with - are tolerable, but are NOT recommended. Points without any of those marks are mandatory. 1. Script context 1.a. There shall be multiple script contexts available. 1.b. Script contexts must be independent of each other. 1.c. There shall be an context_init() call that creates a new script context and returns a handle to it. 1.d. There shall be an context_uninit() call that destroys the context. 1.e. The context_uninit() call shall be callable at any moment the script is not running (e.g. not from a C callback function called from the script). 1.f. *The context_unint() call shall clean up after the script: free all memory allocated by context_init() or the script. 2. lib init 2.a. +There may be a library-wise initializer, lib_init(), which would be called before the first context_init(). 2.b. +There nay be a library-wise uninit, lib_uninit(), which would be called when the last instance of the module is unloaded, after the last context_uninit. 2.c. -The library may maintain global states (global variables) as long as this does not interfere with requirement 1. However, such library won't be safe with a threaded application. 3. C->script: function calls 3.1. It must be possible to execute (call) a function (or equivalent construct) of the script, from C. 3.2. Script functions are referred to by nul terminated const char *name. 3.3. Script functions must have an 1:1 mapping with names, e.g. the same name in the same context will always mean the same function, no matter what the arguments are. 3.4. +A script function may have a return value, which is ignored by GPMI. 3.5. Script functions are called with a variable number of arguments. All arguments are const char * strings. 3.6. The maximum number of arguments must not be less than 16. 3.7. +The script may convert string arguments to native, e.g. if the argument looks like a number the script may interpret it as a number. 4. C->script: RunData 4.1. *The script may be able to process a stream in a main loop (the way sed or awk matches patterns). This mechanism is called RunData. 4.2. *RunData call has two arguments: a void * data and its int size. 5. script->C: function calls 5.1. The script must be able to call a C function with variable number of arguments. 5.2. C functions are registered in the script context by an unique name and a function pointer. 5.3. The script must be able to reference the function by the name it was registered, from any part of the script. 5.4. -The script may need to use a prefix when calling C functions; e.g. the call may be wrapped in a generic "C function call construct" or functions may be registered as members of a class in OOP languages. 5.5. GPMI code will bind all such function callbacks to a single C function callback, called the dispatcher - this must be supported by the script. 5.6. When the dispatcher is executed, it needs to be able to figure the name of the function being called by the script; this name must match the name registered by GPMI (see 5.3. and 5.4.). If there is a prefix according to 5.4., a C function needs to be provided that removes the prefix. 5.7. The C function has a nul terminated string return value. The actual return type in C depends on the script lib API, but must support passing strings as return value (from the script caller's point of view). 5.8. *If the script language offers multiple constructs for the C function call mechanism, a plain global function call should be chosen. If that fails, a global method call or a method call of a central, global class shall be used. 6. Loading the script 6.1. The script API must be able to load a script into a context. 6.2. +The 1.c. context_init() and the 6.1. script load API may be bound together in a single call that creates a context and loads a script. 6.2. *The file name of the script shall be a simple path, the script API should not try to invent its own search paths and file name transformation for the main file. 6.3. *If the script language has include or module functionality, it should be possible to insert the path of the main script in the include/module search path. 6.4. *If loading the script fails, clear error messages shall be generated. 6.5. *There should be a way that GPMI receives the error messages of 6.4., e.g. a context-specific or context-independent function callback or a field of the context that is a list of error messages. This mechanism is preferred over printing errors to stderr. 6.6. +If possible, the lib should load and parse the whole script so that syntax errors are detected on load. JIT, lazy evaluation and other methods that pushes evaluation to a later time should be minimized.