'Header to support the embedding of ScriptBasic into an application 'Derived from ScriptBasic 2.1 source code (Original Author Peter Verhas) 'Scriba.inc 'Charles Pegge '16 September 2009 'For PowerBasic, thinBasic and Oxygen '/* 'scriba.h '*/ '/* '#ifndef __SCRIBA_H__ '#define __SCRIBA_H__ 1 '#ifdef __cplusplus ' extern "C" { '#endif '#include "report.h" '#include "lexer.h" '#include "sym.h" '#include "expression.h" '#include "syntax.h" '#include "reader.h" '#include "myalloc.h" '#include "builder.h" '#include "memory.h" '#include "execute.h" '#include "buildnum.h" '#include "conftree.h" '#include "filesys.h" '#include "errcodes.h" '#ifdef _DEBUG '#include "testalloc.h" '#endif '#include "command.h" '#include "epreproc.h" '#include "ipreproc.h" '#include "uniqfnam.h" '#include "modumana.h" '#include "ipreproc.h" '*/ '/* 'typedef struct _SbProgram { ' void *pMEM; ' void * (*maf)(size_t); ' void (*mrf)(void *); ' unsigned long fErrorFlags; ' char *pszFileName; ' char *pszCacheFileName; ' char *FirstUNIXline; ' ' void *fpStdouFunction; ' void *fpStdinFunction; ' void *fpEnvirFunction; ' void *pEmbedder; ' void *fpReportFunction; ' void *pReportPointer; ' pSupportTable pSTI; ' ExecuteObject *pEPo; ' ' tConfigTree *pCONF; ' ReadObject *pREAD; ' LexObject *pLEX; ' eXobject *pEX; ' BuildObject *pBUILD; ' ExecuteObject *pEXE; ' PreprocObject *pPREP; ' } SbProgram, *pSbProgram; '*/ TYPE SbProgram pMEM AS DWORD maf AS DWORD mrf AS DWORD fErrorFlags AS DWORD pszFileName AS DWORD pszCacheFileName AS DWORD FirstUNIXline AS DWORD fpStdouFunction AS DWORD fpStdinFunction AS DWORD fpEnvirFunction AS DWORD pEmbedder AS DWORD fpReportFunction AS DWORD pReportPointer AS DWORD pSTI AS DWORD pEPo AS DWORD pCONF AS DWORD pREAD AS DWORD pLEX AS DWORD pEX AS DWORD pBUILD AS DWORD pEXE AS DWORD pPREP AS DWORD END TYPE ' } SbProgram, *pSbProgram; '/* 'typedef struct _SbData { ' unsigned char type; ' unsigned long size; ' union { ' double d; ' long l; ' unsigned char *s; ' } v; ' } SbData, *pSbData; '*/ 'ONE OF THESE '% o2Basic =1 '% PowerBasic=1 #IF %DEF(%o2Basic) TYPE datau dbl AS DOUBLE = lng AS LONG = str AS ASCIIZ PTR END TYPE TYPE SbData typ AS BYTE siz AS DWORD datau END TYPE #define SBT_UNDEF 0 #define SBT_DOUBLE 1 #define SBT_LONG 2 #define SBT_STRING 3 #define SBT_ZCHAR 4 MACRO scriba_GetType(Y,X) ( (X).TYPE ) MACRO scriba_GetLength(Y,X) ( (X).SIZE ) MACRO scriba_GetString(Y,X) ( (X).v.s ) MACRO scriba_GetLong(Y,X) ( (X).v.l ) MACRO scriba_GetDouble(Y,X) ( (X).v.d ) #ENDIF #IF %DEF(%PowerBasic) UNION datau dbl AS DOUBLE lng AS LONG str AS ASCIIZ PTR END UNION TYPE SbData typ AS BYTE siz AS DWORD dat AS datau END TYPE %SBT_UNDEF =0 %SBT_DOUBLE =1 %SBT_LONG =2 %SBT_STRING =3 %SBT_ZCHAR =4 MACRO scriba_GetType(Y,X) =( (X).TYPE ) MACRO scriba_GetLength(Y,X) =( (X).SIZE ) MACRO scriba_GetString(Y,X) =( (X).v.s ) MACRO scriba_GetLong(Y,X) =( (X).v.l ) MACRO scriba_GetDouble(Y,X) =( (X).v.d ) #ENDIF '/* '#ifdef WIN32 '#define CONFIG_ENVIR "Software\\ScriptBasic\\config" '#define CONFIG_FILE "SCRIBA.INI" '#else '#define CONFIG_ENVIR "SCRIBACONF" '#define CONFIG_FILE "/etc/scriba/basic.conf" '#endif ' '#if (defined(_WIN32) || defined(__MACOS__) || defined(WIN32)) '# ifdef __cplusplus '# define SCRIBA_MAIN_LIBSPEC extern "C" __declspec(dllexport) '# else '# define SCRIBA_MAIN_LIBSPEC __declspec(dllexport) '# endif '#else '# ifdef __cplusplus '# define SCRIBA_MAIN_LIBSPEC extern "C" '# else '# define SCRIBA_MAIN_LIBSPEC '# endif '#endif '*/ 'NEW ' 'To create a new T object you have to call this function. The two arguments 'should point to T and T or similar functions. All later memory allocation 'and releasing will be performed using these functions. ' 'Note that this is the only function that does not require a pointer to an T object. 'SCRIBA_MAIN_LIBSPEC pSbProgram scriba_new(void * (*maf)(size_t), void (*mrf)(void *)); DECLARE FUNCTION scriba_new ALIAS "scriba_new" (BYVAL maf AS DWORD, BYVAL mrf AS DWORD) AS DWORD 'DESTROY 'After a ScriptBasic program was successfully execued and there is no need to 'run it anymore call this function to release all memory associated with the 'code. 'void scriba_destroy(byval pSbProgram as dword); DECLARE SUB scriba_destroy ALIAS "scriba_destroy" (BYVAL pSbProgram AS DWORD) 'NEW SBDATA 'Allocate and return a pointer to the allocated T structure. ' 'This structure can be used to store ScriptBasic variable data, 'long, double or string. This function is called by other functions 'from this module. Usually the programmer, who embeds ScriptBasic will rarely 'call this function directly. Rather he/she will use R (as an example) 'that creates a variable capable holding a T, sets the type to 'be T and stores initial value. ' 'See also R, R, R, R, 'R, R. 'pSbData scriba_NewSbData(pSbProgram pProgram); DECLARE FUNCTION scriba_NewSbData ALIAS "scriba_NewSbData" (BYVAL pSbProgram AS DWORD) AS DWORD 'INIT SBDATA 'This function initializes an SbData structure to hold undef value. 'This function should be used to initialize an allocated T 'memory structure. This function internally is called by R. ' 'See also R, R, R, R, 'R, R. 'void scriba_InitSbData(pProgram, pSbData p); DECLARE SUB scriba_InitSbData ALIAS "scriba_InitSbData" (BYVAL pSbProgram AS DWORD, d AS SbData) 'UNDEF DATA 'This function sets an T structure to hold the undefined value. 'This function should should not be used instead of R. 'While that function should be used to inititalize the memory structure this 'function should be used to set the value of an alreasdy initialized and probably 'used T variable to T. ' 'The difference inside is that if the T structure is a string then this 'function releases the memory occupied by the string, while R does not. ' 'See also R, R, R, R, 'R, R. 'void scriba_UndefSbData(pSbProgram pProgram, pSbData p); DECLARE SUB scriba_UndefSbData ALIAS "scriba_UndefSbData" (BYVAL pSbProgram AS DWORD, p AS SbData) '//1 'NEW SBLONG 'This function allocates and returns a pointer pointing to a structure of 'type T holding a T value. If the allocation failed the return 'value is T. If the memory allocation was successful the allocated 'structure will have the type T and will hold the initial value 'specified by the argument T. 'See also R, R, R, R, 'R, R. 'pSbData scriba_NewSbLong(pSbProgram pProgram,long dInitValue); DECLARE SUB scriba_NewSbLong ALIAS "scriba_NewSbLong" (BYVAL pSbProgram AS DWORD, BYVAL dInitValue AS LONG) 'NEW SBDOUBLE 'This function allocates and returns a pointer pointing to a structure of 'type T holding a T value. If the allocation failed the return 'value is T. If the memory allocation was successful the allocated 'structure will have the type T and will hold the initial value 'specified by the argument T. 'See also R, R, R, R, 'R, R. 'pSbData scriba_NewSbDouble(pSbProgram pProgram,double dInitValue); DECLARE FUNCTION scriba_NewSbDouble ALIAS "scriba_NewSbDouble" (BYVAL pSbProgram AS DWORD,BYVAL dInitValue AS DOUBLE) AS DWORD 'NEW SBUNDEF 'This function allocates and returns a pointer pointing to a structure of 'type T holding an T value. If the allocation failed the return 'value is T. If the memory allocation was successful the allocated 'structure will have the type T. 'See also R, R, R, R, 'R, R. 'pSbData scriba_NewSbUndef(pSbProgram pProgram); DECLARE FUNCTION scriba_NewSbUndef ALIAS "scriba_NewSbUndef" (BYVAL pSbProgram AS DWORD) AS DWORD 'NEW SBSTRING ' 'This function allocates and returns a pointer pointing to a structure of 'type T holding a string value. If the allocation failed the return 'value is T. If the memory allocation was successful the allocated 'structure will have the type T and will hold the initial value 'specified by the argument T. 'B 'The init value T should be a zchar terminated string. Note that 'ScriptBasic internally stores the strings as series byte and the length of the 'string without any terminating zchar. Therefore the length of the string 'that is stored should have been T. This does not contain the 'terminating zchar. 'In reality however we allocate an extra byte that stores the zchar, but the 'size of the string is one character less. Therefore ScriptBasic routines 'will recognize the size of the string correct and also the caller can 'use the string using the macro T as a zchar terminated 'C string. This requires an extra byte of storage for each string passed from the 'embedding C application to ScriptBasic, but saves a lot of hedeache and also 'memory copy when the string has to be used as a zchar terminated string. 'See also R, R, R, R, 'R, R. 'pSbData scriba_NewSbString(pSbProgram pProgram, char *pszInitValue); DECLARE FUNCTION scriba_NewSbString ALIAS "scriba_NewSbString" (BYVAL pSbProgram AS DWORD, pszInitValue AS ASCIIZ) AS DWORD 'NEW SBBYTES 'This function allocates and returns a pointer pointing to a structure of 'type T holding a string value. If the allocation failed the return 'value is T. If the memory allocation was successful the allocated 'structure will have the type T and will hold the initial value 'specified by the argument T of the length T. 'This function allocates T+1 number of bytes data and 'stores the initial value pointed by T in it. 'The extra plus one byte is an extra terminating zero char 'that may help the C programmers to handle the string 'in case it is not binary. Please also read the not on the terminating ZChar 'in the function R. ' 'See also R, R, R, R, 'R, R. 'pSbData scriba_NewSbBytes(pSbProgram pProgram, unsigned long len, unsigned char *pszInitValue); DECLARE FUNCTION scriba_NewSbBytes ALIAS "scriba_NewSbBytes" (BYVAL pSbProgram AS DWORD, BYVAL LEN AS LONG, pszInitValue AS ASCIIZ) AS DWORD 'DESTROY SBDATA 'Call this function to release the memory that was allocated by any 'of the T functions. This function releases the memory and 'also cares to release the memory occupied by the characters in case the 'value had the type T. ' 'See also R, R, R, R, 'R, R. 'void scriba_DestroySbData(pSbProgram pProgram, pSbData p); DECLARE SUB scriba_DestroySbData ALIAS "scriba_DestroySbData" (BYVAL pSbProgram AS DWORD, d AS SbData) 'PURGE READER MEMORY 'Call this function to release all memory that was allocated by the 'reader module. The memory data is needed so long as long the lexical analyzer 'has finished. 'void scriba_PurgeReaderMemory(pSbProgram pProgram); DECLARE SUB scriba_PurgeReaderMemory ALIAS "scriba_PurgeReaderMemory" (BYVAL pSbProgram AS DWORD) 'PURGE LEXER MEMORY 'void scriba_PurgeLexerMemory(pSbProgram pSBProgram); DECLARE SUB scriba_PurgeLexerMemory ALIAS "scriba_PurgeLexerMemory" (BYVAL pSbProgram AS DWORD) 'PURGE SYNTAX MEMORY 'void scriba_PurgeSyntaxerMemory(pSbProgram pProgram); DECLARE SUB scriba_PurgeSyntaxerMemory ALIAS "scriba_PurgeSyntaxerMemory" (BYVAL pSbProgram AS DWORD) 'PURGE BUILDER MEMORY 'void scriba_PurgeBuilderMemory(pSbProgram pProgram); DECLARE SUB scriba_PurgeBuilderMemory ALIAS "scriba_PurgeBuilderMemory" (BYVAL pSbProgram AS DWORD) 'PRURGE PREPROCESSOR MEMORY 'This function purges the memory that was needed to run the preprocessors. 'void scriba_PurgePreprocessorMemory(pSbProgram pProgram); DECLARE SUB scriba_PurgePreprocessorMemory ALIAS "scriba_PurgePreprocessorMemory" (BYVAL pSbProgram AS DWORD) 'PURGE EXECUTE MEMORY 'This function purges the memory that was needed to execute the program, 'but before that it executes the finalization part of the execution. 'void scriba_PurgeExecuteMemory(pSbProgram pProgram); DECLARE SUB scriba_PurgeExecuteMemory ALIAS "scriba_PurgeExecuteMemory" (BYVAL pSbProgram AS DWORD) 'SET FILENAME 'Call this function to set the file name where the source informaton is. 'This file name is used by the functions R and 'R as well as error reporting functions to display 'the location of the error. 'int scriba_SetFileName(pSbProgram pProgram, char *pszFileName); DECLARE FUNCTION scriba_SetFileName ALIAS "scriba_SetFileName" (BYVAL pSbProgram AS DWORD, pszFileName AS ASCIIZ) AS LONG 'LOAD CONFIGURATION 'R and R can be used to 'specify configuration information for a ScriptBasic program. Here 'we describe the differences and how to use the two functions for 'single-process single-basic and for single-process multiple-basic 'applications. ' 'To execute a ScriptBasic program you usually need configuration information. 'The configuration information for the interpreter is stored in a file. 'The function R reads the file and loads it into memory 'into the T object. When the object is destroyed the configuration 'information is automatically purged from memory. ' 'Some implementations like the Eszter SB Engine variation of ScriptBasic starts 'several interpreter thread within the same process. In this case the configuration 'information is read only once and all the running interpreters share the same 'configuration information. ' 'To do this the embedding program has to create a pseudo T object that 'does not run any ScriptBasic program, but is used only to load the configuration 'information calling the function R. Other T objects 'that do intepret ScriptBasic program should inherit this configuration calling the 'function R. When a T object is destroyed the 'configuration is not destroyed if that was inherited belonging to a different object. 'It remains in memory and can later be used by other intrepreter instances. ' 'Inheriting the configuration is fast because it does not require loading the 'configuration information from file. This is essentially sets a pointer in the 'internal interpreter structure to point to the configuration information held 'by the other object and all the parallel running interpreters structures 'point to the same piece of memory holding the common configuration information. ' 'See the configuration handling functions R and R. 'int scriba_LoadConfiguration(pSbProgram pProgram, char *pszForcedConfigurationFileName); DECLARE FUNCTION scriba_LoadConfiguration ALIAS "scriba_LoadConfiguration" (BYVAL pSbProgram AS DWORD, pszForcedConfigurationFileName AS ASCIIZ) AS LONG 'GET CONFIG FILENAME 'This function tells whet the configuration file is. There is no need to call this function to read the configuration file. 'This is needed only when the main program want to manipulate the configuration file in some way. For example the command 'line version of ScriptBasic uses this function when the option T<-k> is used to compile a configuration file. ' 'The first argument has to be a valid ScriptBasic program object. The second argument should point to a valid T pointer that 'will get the pointer value to the configuration file name after the function returns. 'The function returns zero if no error happens, or the error code. 'int scriba_GetConfigFileName(pSbProgram pProgram, char **ppszFileName); DECLARE FUNCTION scriba_GetConfigFileName ALIAS "scriba_GetConfigFileName" (BYVAL pSbProgram AS DWORD, ppszFileName AS DWORD) AS LONG 'INHERIT CONFIGURATION 'Use this function to get the configuration from another program object. 'The return value is zero on success and error code if error has happened. 'int scriba_InheritConfiguration(pSbProgram pProgram, pSbProgram pFrom); DECLARE FUNCTION scriba_InheritConfiguration ALIAS "scriba_InheritConfiguration" (BYVAL pSbProgram AS DWORD, BYVAL pFrom AS DWORD) AS LONG 'INIT MODULE INTERFACE 'Initialize the Support Function Table of a process level ScriptBasic program object to be inherited 'by other program objects. If you read it first time, read on until you understand what this 'function really does and rather how to use it! ' 'This is going to be a bit long, but you better read it along with the documentation of the 'function R. ' 'This function is needed only for programs that are '=itemize '=item multi thread running several interpreters simultaneous in a single process '=item support modules like the sample module T that support multithread behaviour and ' need to implement worker thread needing call-back functions. '=noitemize ' 'You most probably know that modules can access system and ScriptBasic fucntions via a 'call-back table. That is a huge T containing pointers to the functions that 'ScriptBasic implements. This is the T (aka support table). ' 'This helps module writers to write system independent 'code as well as to access ScriptBasic functions easily. On the other hand modules are 'also free to alter this table and because many functions, tough not all are called via this 'table by ScriptBasic itself a module may alter the core behavior of ScriptBasic. ' 'For this reason each interpreter has its own copy of T. 'This means that if an interpreter alters the table it has no effect on another interpreter 'running in the same process in anther thread. ' 'This is fine so far. How about modules that run asynchronous threads? For example the very first 'interpter thread that uses the module T starts in the initialization a thread that later 'deletes all sessions that time out. This thread lives a long life. ' 'The thread that starts the worker thread is an interpreter thread and has its own copy of the T. 'The thread started asynchronous however should not use this T because the table is purged 'from memory when the interpreter instance it blelonged to finishes. ' 'To have T for worker threads there is a need for a program object that is not purged 'from memory so long as long the process is alive. Fortunately there is such an object: the 'configuration program object. Configuration is usually read only once by multi-thread implementations 'and the same configuration information is shared by the serveral threads. The same way the 'several program objects may share a T. ' 'The difference is that configuration is NOT altered by the interpreter or by any module in any way 'but T may. Thus each execution object has two pointers: T and T. While T points to 'the support table that belongs to the interpreter instance the secondpointer T points to 'a T that is global for the whole process and is permanent. This T is to be used by worker threads 'and should not be altered by the module without really good reason. ' 'Thus: Don't call this function for normal program objects! For usualy program objects module 'interface is automatically initialized when the first module function is called. Call this function 'to initialize a T for a pseudo program object that is never executed but rather used to inherit this 'T for worker threads. ' 'int scriba_InitModuleInterface(pSbProgram pProgram); DECLARE FUNCTION scriba_InitModuleInterface ALIAS "scriba_InitModuleInterface" (BYVAL pSbProgram AS DWORD) AS LONG 'INHERIT MODULE INTERFACE 'Inherit the support function table (T) from another program object. ' 'Note that the program object is going to initialize its own T the normal 'way. The inherited T will only be used by worker threads that live a long 'life and may exist when the initiating interpreter thread already exists. ' 'For further information please read the description of the function R. 'int scriba_InheritModuleInterface(pSbProgram pProgram, pSbProgram pFrom); DECLARE FUNCTION scriba_InheritModuleInterface ALIAS "scriba_InheritModuleInterface" (BYVAL pSbProgram AS DWORD, BYVAL pFrom AS DWORD) AS LONG 'INHERIT EXECUTE OBJECT ' 'int scriba_InheritExecuteObject(pSbProgram pProgram, pSbProgram pFrom); DECLARE FUNCTION scriba_InheritExecuteObject ALIAS "scriba_InheritExecuteObject" (BYVAL pSbProgram AS DWORD, BYVAL pFrom AS DWORD) AS LONG 'SET PROCESS OBJECT 'Use this program in multi-thread environment to tell the actual interpreter 'which object is the process level pseudo object that ' '=itemize '=item holds the shared (among interpreter thread objects) configuration 'information (see R) '=item holds the process level module interface (see R) '=item holds the list of loaded modules that are not unloaded by the thread loaded the module '=noitemize ' 'If the embeddingprogram calls this function there is no need to call R 'and R. This function call does all those tasks and also other things. 'int scriba_SetProcessSbObject(pSbProgram pProgram, pSbProgram pProcessObject); DECLARE FUNCTION scriba_SetProcessSbObject ALIAS "scriba_SetProcessSbObject" (BYVAL pSbProgram AS DWORD, BYVAL pProcessObject AS DWORD ) AS LONG 'SHUTDOWN MT MODULES 'A multi threaded application should call this function for the process SB object 'when the process finishes. Calling this function will call each of the shutdown 'functions of those external modules that decided to keep in memory and export 'the shutdown function named T. This allows these modules to gracefully 'shut down their operation. As an example cached data can be written to disk, or 'database connections can be closed. 'int scriba_ShutdownMtModules(pSbProgram pProgram); DECLARE FUNCTION scriba_ShutdownMtModules ALIAS "scriba_ShutdownMtModules" (BYVAL pSbProgram AS DWORD) AS LONG 'SET CGI FLAG ' 'You can call this function to tell the reporting subsystem that 'this code runs in a CGI environment and therefore it should format 'error messages according to the CGI standard sending to the 'standard output including HTTP headers and HTML code pieces. 'void scriba_SetCgiFlag(pSbProgram pProgram); DECLARE SUB scriba_SetCgiFlag ALIAS "scriba_SetCgiFlag" (BYVAL pSbProgram AS DWORD) 'SET REPORT FUNCTION 'This function should be used to set the report function for a program. The report function 'is used to send info, warning, error, fatal and internal error messages to the user. ' 'In case you want to implement a specific report function see the sample implementation in the 'file T. The documentation of the function T describes not only the details 'of the sample implementation but also the implementation requests for other reporting functions. 'void scriba_SetReportFunction(pSbProgram pProgram, void *fpReportFunction); DECLARE SUB scriba_SetReportFunction ALIAS "scriba_SetReportFunction" (BYVAL pSbProgram AS DWORD, BYVAL fpReportFunction AS DWORD) 'SET REPORT POINTER 'This pointer will be passed to the reporting function. The default 'reporting uses this pointer as a T pointer. The default value 'for this pointer is T. ' 'Other implementations of the reporting function may use this pointer 'according their needs. For example the WIN32 IIS ISAPI implementation 'uses this pointer to point to the extension controll block structure. 'void scriba_SetReportPointer(pSbProgram pProgram, void *pReportPointer); DECLARE SUB scriba_SetReportPointer ALIAS "scriba_SetReportPointer" (BYVAL pSbProgram AS DWORD, pReportPointer AS DWORD) 'SET STDIN 'You can call this function to define a special standard input function. This 'pointer should point to a function that accepts a T pointer 'as argument. Whenever the ScriptBasic program tries to read from the 'standard input it calls this function pasing the embedder pointer as 'argument. ' 'If the T function is not defined or the parameter is T 'the interpreter will read the normal T stream. 'void scriba_SetStdin alias "" (pSbProgram pProgram, void *fpStdinFunction); DECLARE SUB scriba_SetStdin ALIAS "scriba_SetStdin" (BYVAL pSbProgram AS DWORD, BYVAL fpStdinFunction AS DWORD) 'SET STDOUT 'You can call this function to define a special standard output function. This 'pointer should point to a function that accepts a T<(char, void *)> arguments. 'Whenever the ScriptBasic program tries to send a character to the standard output 'it calls this function. The first parameter is the character to write, the second 'is the embedder pointer. ' 'If the standard output function is not defined or the parameter is T 'the interpreter will write the normal T stream. 'void scriba_SetStdout(pSbProgram pProgram, void *fpStdoutFunction); DECLARE SUB scriba_SetStdout ALIAS "scriba_SetStdout" (BYVAL pSbProgram AS DWORD, BYVAL fpStdoutFunction AS DWORD) 'SET EMBED POINTER 'This function should be used to set the embed pointer. ' 'The embed pointer is a pointer that is not used by ScriptBasic itself. This 'pointer is remembered by ScriptBasic and is passed to call-back functions. 'Like the standard input, output and environment functions that the embedding 'application may provide this pointer is also available to external modules implemented 'in C or other compiled language in DLL or SO files. ' 'The embedder pointer should usually point to the T of the thread local data. 'For example the Windows NT IIS variation of ScriptBasic sets this variable to point to 'the extension control block. ' 'If this pointer is not set ScriptBasic will pass T pointer to the extensions and 'to the call-back function. 'void scriba_SetEmbedPointer(pSbProgram pProgram, void *pEmbedder); DECLARE SUB scriba_SetEmbedPointer ALIAS "scriba_SetEmbedPointer" (BYVAL pSbProgram AS DWORD, BYVAL pEmbedder AS DWORD) 'SET ENVIRONMENT 'You can call this function to define a special environment query function. This 'pointer should point to a function that accepts a T<(void *, char *, long )> arguments. ' 'Whenever the ScriptBasic program tries to get the value of an enviroment variable 'it calls this function. The first argument is the embedder pointer. ' 'The second argument is the name of the environment variable to retrieve or T. ' 'The third argument is either zero or is the serial number of the environment variable. ' 'ScriptBasic never calls this function with both specifying the environment variable name 'and the serial number. ' 'The return value of the function should either be T or should point to a string that 'holds the zero character terminated value of the environment variable. This string is not 'changed by ScriptBasic. ' 'If the special environment function is not defined or is T ScriptBasic uses the 'usual environment of the process calling the system functionT. ' 'For a good example of a self-written environment function see the source of the Eszter SB Engine 'that alters the environment function so that the ScriptBasic programs feel as if they were executed in a 'real CGI environment. 'void scriba_SetEnvironment(pSbProgram pProgram, void *fpEnvirFunction); DECLARE SUB scriba_SetEnvironment ALIAS "scriba_SetEnvironment" (BYVAL pSbProgram AS DWORD, BYVAL pEnvirFunction AS DWORD) 'LOAD BINARY PROGRAM WITH OFFSET 'Use this function to load ScriptBasic program from a file that is already compiled into 'internal form, and the content of the program is starting on T ' 'The return value is the number of errors (hopefully zero) during program load. ' 'Before calling this function the function R should have been called specifying the 'file name. 'int scriba_LoadBinaryProgramWithOffset(pSbProgram pProgram, byval lOffset as long, long lEOFfset); DECLARE FUNCTION scriba_LoadBinaryProgramWithOffset ALIAS "scriba_LoadBinaryProgramWithOffset" (BYVAL pSbProgram AS DWORD, BYVAL lOffset AS LONG , BYVAL lEOFfset AS LONG) AS LONG 'LOAD BINARY PROGRAM 'Use this function to load ScriptBasic program from a file that is already compiled into 'internal form. ' 'The return value is the number of errors (hopefully zero) during program load. 'int scriba_LoadBinaryProgram(pSbProgram pProgram); DECLARE FUNCTION scriba_LoadBinaryProgram ALIAS "scriba_LoadBinaryProgram" (BYVAL pSbProgram AS DWORD) AS LONG 'INHERIT BINARY PROGRAM 'The function inherits the binary code from the program object T. 'In server type applications the compiled binary code of a BASIC program may 'be kept in memory. To do this a pseudo program object should be created that 'loads the binary code and is not destroyed. ' 'The program object used to execute the code should inherit the binary code from 'this pseudo object calling this function. This is similar to the configuration 'inheritance. 'int scriba_InheritBinaryProgram(pSbProgram pProgram, pSbProgram pFrom); DECLARE FUNCTION scriba_InheritBinaryProgram ALIAS "scriba_InheritBinaryProgram" (BYVAL pSbProgram AS DWORD, BYVAL pFrom AS DWORD) AS LONG 'LOAD INTERNAL PREPROCESSOR 'This function can be used by embedding applications to load an 'internal preprocessor into the interpereter. Note that preprocessors 'are usually loaded by the reader module when a T statement 'is found. However some preprocessors in some variation of the interpreter 'may be loaded due to configuration or command line option and not 'because the source requests it. ' 'The preprocessors that are requested to be loaded because the source 'contains a T line usually implement special language 'fetures. The preprocessors that are loaded independent of the source 'because command line option or some other information tells the variation 'to call this function are usually debuggers, profilers. ' '(To be honest, by the time I write it there is no any internal preprocessors 'developed except the test one, but the statement above will become true.) ' 'The first argument is the program object. If the program object does not 'have a preprocessor object the time it is called the preprocessor object is 'created and initiated. ' 'The second argument is the array of names of the preprocessor as it is present 'in the configuration file. This is not the name of the DLL/SO file, but 'rather the symbolic name, which is associated with the file. The final element 'of the array has to be T. ' 'The return value is zero or the error code. 'int scriba_LoadInternalPreprocessor(pSbProgram pProgram, char *ppszPreprocessorName[]); DECLARE FUNCTION scriba_LoadInternalPreprocessor ALIAS "scriba_LoadInternalPreprocessor" (BYVAL pSbProgram AS DWORD, ppszPreprocessorName AS DWORD) AS LONG 'READ SOURCE 'Loads the source code of a ScriptBasic program from a text file. ' 'The return code is the number of errors happened during read. ' 'B This function only reads the source. Does not compile it. 'You will usually need R that does reading, analyzing, building 'and all memory releases leaving finally a ready-to-run code in memory. ' 'Before calling this function the function R should have been called specifying the 'file name. ' 'int scriba_ReadSource(pSbProgram pProgram); DECLARE FUNCTION scriba_ReadSource ALIAS "scriba_ReadSource" (BYVAL pSbProgram AS DWORD) AS LONG 'DO LEXICAL ANALYSIS 'This function performs lexical analysis after the source file has beed read. ' 'This function is rarely needeed by applicationdevelopers. See R 'instead. ' 'See also R, R, 'R, R. ' 'int scriba_DoLexicalAnalysis(pSbProgram pProgram); DECLARE FUNCTION scriba_DoLexicalAnalysis ALIAS "scriba_DoLexicalAnalysis" (BYVAL pSbProgram AS DWORD) AS LONG 'DO SYNTAX ANALYSIS 'This function performs syntax analysis after the lexical analysis has been finished. ' 'This function is rarely needeed by applicationdevelopers. See R 'instead. ' 'See also R, R, 'R, R. ' 'int scriba_DoSyntaxAnalysis(pSbProgram pProgram); DECLARE FUNCTION scriba_DoSyntaxAnalysis ALIAS "scriba_DoSyntaxAnalysis" (BYVAL pSbProgram AS DWORD) AS LONG 'BUILD CODE 'This function builds the finall ready-to-run code after the syntax 'analisys has been finished. ' 'This function is rarely needeed by applicationdevelopers. See R 'instead. ' 'See also R, R, 'R, R. ' 'int scriba_BuildCode(pSbProgram pProgram); DECLARE FUNCTION scriba_BuildCode ALIAS "scriba_BuildCode" (BYVAL pSbProgram AS DWORD) AS LONG 'IS FILE BINARY FORMAT 'This function decides if a file is a correct binary format ScriptBasic 'code file and returns true if it is binary. If the file is a ScriptBasic 'source file or an older version binary of ScriptBasic or any other file 'it returns zero. ' 'This function just calls the function T 'int scriba_IsFileBinaryFormat(pSbProgram pProgram); DECLARE FUNCTION scriba_IsFileBinaryFormat ALIAS "scriba_IsFileBinaryFormat" (BYVAL pSbProgram AS DWORD) AS LONG 'GET CACHE FILENAME 'Calculate the name of the cache file for the given source file name and 'store the calculated file name in the program object. ' 'The program returns zero or the error code. It returns T if there 'is no cache directory configured. ' 'The code uses a local buffer of length 256 bytes. The full cached file name should 'fit into this otherwise the program will return T. ' 'The code does not check if there exists an appropriate cache directory or file. It 'just calculates the file name. ' 'int scriba_GetCacheFileName(pSbProgram pProgram); DECLARE FUNCTION scriba_GetCacheFileName ALIAS "scriba_GetCacheFileName" (BYVAL pSbProgram AS DWORD) AS LONG 'USE CACHE FILE 'Call this function to test that the cache file is usable. This function 'calls the function R to calculate the cache file name. ' 'If '=itemize '=item the cache file exists '=item is newer than the source file set by R '=item is a correct ScriptBasic binary file '=noitemize 'then this function alters the source file name property (T) 'of the program object so that the call to R will try to 'load the cache file. 'The function returns zero or the error code. The function returns T 'in case the cache file is old, or not valid. Therefore returning a positive value 'does not neccessarily mean a hard error. 'int scriba_UseCacheFile(pSbProgram pProgram); DECLARE FUNCTION scriba_UseCacheFile ALIAS "scriba_UseCacheFile" (BYVAL pSbProgram AS DWORD) AS LONG 'SAVE CACHE FILE 'Call this function to generate a cache file after 'a successful program compilation. ' 'The function returns zero (T) if there was no error. 'This does not mean that the cache file was saved. If there is no cache 'directory configured doing nothing is success. ' 'Returning any positive error code means that ScriptBasic tried to write a 'cache file but it could not. ' 'int scriba_SaveCacheFile(pSbProgram pProgram); DECLARE FUNCTION scriba_SaveCacheFile ALIAS "scriba_SaveCacheFile" (BYVAL pSbProgram AS DWORD) AS LONG 'RUN EXTERNAL PREPROCESSOR 'This function should be called to execute external preprocessors. ' 'This function does almost nothing else but calls the function 'T. ' ' 'The argument T should point to a string array. This string array 'should contain the configured names of the preprocessors that are applied one after the 'other in the order they are listed in the array. ' 'Note that this array should contain the symbolic names of the preprocessors. The actual 'preprocessor executable programs, or command lines are defined in the configuration 'file. ' 'After calling this function the source file name property of the program object (T) 'is also modified so that it points to the result of the preprocessor. This means that after the 'successful return of this function the application may immediately call R. ' 'If there is any error during the preprocessor execution the function returns some error code '(returned by T) otherwise the return value is zero. ' 'int scriba_RunExternalPreprocessor(pSbProgram pProgram, char **ppszArgPreprocessor); DECLARE FUNCTION scriba_RunExternalPreprocessor ALIAS "scriba_RunExternalPreprocessor" (BYVAL pSbProgram AS DWORD, ppszArgPreprocessor AS DWORD) AS LONG 'SAVE CODE 'Call this function to save the compiled byte code of the program 'into a specific file. This function is called by the function R. ' 'The function does nothing else, but calls T. ' 'The return code is zero or the error code returned by T. ' 'int scriba_SaveCode(pSbProgram pProgram, char *pszCodeFileName); DECLARE FUNCTION scriba_SaveCode ALIAS "scriba_SaveCode" (BYVAL pSbProgram AS DWORD, pszCodeFileName AS ASCIIZ) AS LONG 'void scriba_SaveCCode(pSbProgram pProgram, char *pszCodeFileName); DECLARE SUB scriba_SaveCCode ALIAS "scriba_SaveCCode" (BYVAL pSbProgram AS DWORD, pszCodeFileName AS ASCIIZ) 'void scriba_SaveECode(pSbProgram pProgram, char *pszInterpreter, char *pszCodeFileName); DECLARE SUB scriba_SaveECode ALIAS "scriba_SaveECode" (BYVAL pSbProgram AS DWORD, pszInterpreter AS ASCIIZ, pszCodeFileName AS ASCIIZ) 'LOAD SOURCE PROGRAM 'Call this function to load a BASIC program from its source format after 'optionally checking that there is no available cache file and after 'executing all required preprocessors. This function calls 'R, R, R, R, 'and also releases the memory that was needed only for code building 'calling R, R, R. ' 'After the successful completion of this program the BASIC program is in 'the memory in the ready-to-run state. ' 'Before calling this function the function R should have been called specifying the 'file name. ' 'The return value is zero (T) or the error code returned by the 'underlying layer that has detected the error. ' 'int scriba_LoadSourceProgram(pSbProgram pProgram); DECLARE FUNCTION scriba_LoadSourceProgram ALIAS "scriba_LoadSourceProgram" (BYVAL pSbProgram AS DWORD) AS LONG 'LOAD PROGRAM STRING 'Use this function to convert a string containing a BASIC program 'that is already in memory to ready-to-run binary format. This function 'is same as R except that this function reads the source 'code from a string instead of a file. ' 'The argument T is the program object. The argument T 'is the BASIC program itself in text format. Because the source code may 'contain ZCHAR just for any chance the caller has to provide the number of 'characters in the buffer via the argument T. In case the 'source program is zero terminated the caller can simply say 'T to give this argument. ' 'Before calling this function the function R may be called. Altough 'the source code is read from memory and thus there is no source file the 'BASIC program may use the command T or T that includes 'another source file after reading the code. If the program does so the reader 'functions need to know the actual file name of the source code to find 'the file to be included. To help this process the caller using this function 'may set the file name calling R. However that file is never used 'and need not even exist. It is used only to calculate the path of included files 'that are specified using relative path. ' 'The return value is zero (T) or the error code returned by the 'underlying layer that has detected the error. ' 'int scriba_LoadProgramString(pSbProgram pProgram, char *pszSourceCode, unsigned long cbSourceCode); DECLARE FUNCTION scriba_LoadProgramString ALIAS "scriba_LoadProgramString" (BYVAL pSbProgram AS DWORD, pszSourceCode AS ASCIIZ, BYVAL cbSourceCode AS DWORD) AS LONG 'RUN 'Call this function to execute a program. Note that you can call this function 'many times. Repetitive execution of the same program will execute the 'ScriptBasic code again and again with the global variables keeping their values. ' 'If you want to reset the global variables you have to call R. ' 'There is no way to keep the value of the local variables. ' 'The argument T is the command part that is passed to the 'BASIC program. ' 'The return value is zero in case of success or the error code returned by the underlying 'execution layers. ' 'Note that you can not call BASIC subroutines or functions without initializations that 'T performs. You also can not access global variables. Therefore you either have 'to call T or its brother R that performs the initializations without execution. ' 'You also have to call R if you want to execute a program with some global variables 'having preset values that you want to set from the embedding C program. In that case you 'have to call R then one or more times R and finally T. ' 'int scriba_Run(pSbProgram pProgram, char *pszCommandLineArgument); DECLARE FUNCTION scriba_Run ALIAS "scriba_Run" (BYVAL pSbProgram AS DWORD, pszCommandLineArgument AS ASCIIZ) AS LONG 'NO RUN 'In case the embedding program want to set global variables and 'execute subroutines without or before starting the main program it has to call this 'function first. It does all the initializations that are done by 'R except that it does not actually execute the program. ' 'After calling this function the main program may access global variables 'and call BASIC functions. ' 'See also R. ' 'int scriba_NoRun(pSbProgram pProgram); DECLARE FUNCTION scriba_NoRun ALIAS "scriba_NoRun" (BYVAL pSbProgram AS DWORD) AS LONG 'RESET VARIABLES 'Call this function if you want to execute a program object that was already executed 'but you do not want the global variables to keep their value they had when 'the last execution of the BASIC code finished. ' 'Global variables in ScriptBasic are guaranteed to be T before they get any other 'value and some programs depend on this. ' ' 'See also R, R, R. 'void scriba_ResetVariables(pSbProgram pProgram); DECLARE SUB scriba_ResetVariables ALIAS "scriba_ResetVariables" (BYVAL pSbProgram AS DWORD) 'CALL 'This function can be used to call a function or subroutine. This function does not 'get any arguments and does not provide any return value. ' 'The return value is zero or the error code returned by the interpreter. ' 'B ' 'The argument T should be the node index of the subroutine or function that 'we want to execute. This can be retrieved using the function R if the 'name of the function or subroutine is know. Another method is that the BASIC program 'stored this value in some global variables. BASIC programs can access this information 'calling the BASIC function T. ' 'int scriba_Call(pSbProgram pProgram, unsigned long lEntryNode); DECLARE FUNCTION scriba_Call ALIAS "scriba_Call" (BYVAL pSbProgram AS DWORD, BYVAL lEntryNode AS DWORD) AS LONG 'CALL ARG 'This function can be used to call a function or subroutine with arguments passed by value. 'Neither the return value of the SUB nor the modified argument variables are not accessible 'via this function. T is a simple interface to call a ScriptBasic subroutine or 'function with argument. ' ' 'Arguments ' '=itemize '=item T is the class variable. '=item T is the start node of the SUB. (See R note on how to get the entry node value.) '=item T is a format string that defines the rest of the areguments '=noitemize ' 'The format string is case insensitive. The characters T, T, T, T and T have meaning. 'All other characters are ignored. The format characters define the type of the arguments 'from left to right. ' '=itemize '=item T means to pass an T to the SUB. This format character is exceptional that it does not 'consume any function argument. '=item T means that the next argument has to be T and it is passed to the BASIC SUB as an integer. '=item T means that the next argument has to be T and it is passed to the BASIC SUB as a real. '=item T means that the next argument has to be T and it is passed to the BASIC SUB as a string. '=item T means that the next two arguments has to be T and T. 'The T defines the length of the T. '=noitemize ' 'Note that this SUB calling function is a simple interface and has no access to the modified values of the argument 'after the call or the return value. ' 'If you need any of the functionalities that are not implemented in this function call a more sophisticated 'function. ' 'Example: '=verbatim ' ' iErrorCode = scriba_CallArg(&MyProgram,lEntry,"i i s d",13,22,"My string.",54.12); ' '=noverbatim ' 'int scriba_CallArg(pSbProgram pProgram, unsigned long lEntryNode, char *pszFormat, ...); DECLARE FUNCTION scriba_CallArg ALIAS "scriba_CallArg" (BYVAL pSbProgram AS DWORD, BYVAL lEntryNode AS DWORD, pszFormat AS ASCIIZ, BYVAL nl AS DWORD) AS LONG 'DESTROY SB ARGS 'This function can be used to release the memory used by arguments created by the 'function R. ' 'Arguments: '=itemize '=item T class variable '=item T pointer returned by R '=item T the number of arguments pointed by T '=noitemize ' 'void scriba_DestroySbArgs(pSbProgram pProgram, pSbData Args, unsigned long cArgs); DECLARE SUB scriba_DestroySbArgs ALIAS "scriba_DestroySbArgs" (BYVAL pSbProgram AS DWORD, Args AS SbData, BYVAL cArgs AS DWORD) 'NEW SB ARGS 'Whenever you want to handle the variable values that are returned by the scriba subroutine 'you have to call R. This function needs the arguments passed in an array of T type. ' 'This function is a usefuly tool to convert C variables to an array of T ' 'The arguments passed are ' '=itemize '=item T is the class variable '=item T is the format string '=noitemize ' 'The format string is case insensitive. The characters T, T, T, T and T have meaning. 'All other characters are ignored. The format characters define the type of the arguments 'from left to right. ' '=itemize '=item T means to pass an T to the SUB. This format character is exceptional that it does not 'consume any function argument. '=item T means that the next argument has to be T and it is passed to the BASIC SUB as an integer. '=item T means that the next argument has to be T and it is passed to the BASIC SUB as a real. '=item T means that the next argument has to be T and it is passed to the BASIC SUB as a string. '=item T means that the next two arguments has to be T and T. 'The T defines the leng of the T. '=noitemize ' 'Example: ' '=verbatim ' 'pSbData MyArgs; ' ' ' MyArgs = scriba_NewSbArgs(pProgram,"i i r s b",13,14,3.14,"string",2,"two character string"); ' if( MyArgs == NULL )error("memory alloc"); ' ' scriba_CallArgEx(pProgram,lEntry,NULL,5,MyArgs); ' '=noverbatim ' 'This example passes five arguments to the ScriptBasic subroutine. Note that the last one is only 'two character string, the rest of the characters are ignored. ' 'pSbData scriba_NewSbArgs(pSbProgram pProgram, char *pszFormat, ...); DECLARE FUNCTION scriba_NewSbArgs ALIAS "scriba_NewSbArgs" (BYVAL pSbProgram AS DWORD, pszFormat AS ASCIIZ) AS DWORD 'CALL ARG EX 'This is the most sophisticated function of the ones that call a ScriptBasic subroutine. 'This function is capable handling parameters to scriba subroutines, and returning the 'modified argument variables and the return value. ' 'The arguments: '=itemize '=item T is the program object pointer. '=item T is the entry node index where the BASIC subroutine or function starts ' (See R note on how to get the entry node value.) '=item T is the return value of the function or subroutine '=item T is the number of argments passed to the function '=item T argument data array '=noitemize ' 'int scriba_CallArgEx(pSbProgram pProgram, unsigned long lEntryNode, pSbData ReturnValue, unsigned long cArgs, pSbData Args); DECLARE FUNCTION scriba_CallArgEx ALIAS "scriba_CallArgEx" (BYVAL pSbProgram AS DWORD, BYVAL lEntryNode AS DWORD, ReturnValue AS SbData, BYVAL cArgs AS DWORD, Args AS SbData) AS LONG 'LOOKUP FUNCTION BY NAME 'This function should be used to get the entry point of a function 'knowing the name of the function. The entry point should not be treated as a 'numerical value rather as a handle and to pass it to functions like 'R. ' 'The return value of the function is the entry node index of the function named or 'zero if the function is not present in the program. ' ' 'long scriba_LookupFunctionByName alias "" (pSbProgram pProgram, char *pszFunctionName); DECLARE FUNCTION scriba_LookupFunctionByName ALIAS "scriba_LookupFunctionByName" (BYVAL pSbProgram AS DWORD, pszFunctionName AS ASCIIZ) AS LONG 'LOOKUP VARIABLE BY NAME 'This function can be used to get the serial number of a global variable 'knowing the name of the variable. ' 'Note that all variables belong to a name space. Therefore if you want to 'retrieve the global variable T you have to name it T. ' ' 'The return value is the serial number of the global avriable or zero if 'there is no variable with that name. ' 'Note that the second argument, the name of the global variable, is not 'going under the usual name space manipulation. You have to specify the 'variable name together with the name space. For example the variable T will 'not be found, but the variable T will be. ' 'long scriba_LookupVariableByName(pSbProgram pProgram, char *pszVariableName); DECLARE FUNCTION scriba_LookupVariableByName ALIAS "scriba_LookupVariableByName" (BYVAL pSbProgram AS DWORD, pszVariableName AS ASCIIZ) AS LONG 'GET VARIABLE TYPE 'Get the type of the value that a variable is currently holding. This 'value can be ' '=itemize '=item T '=item T '=item T '=item T '=noitemize ' 'The argument T should be the serial number of 'the variable as returned by R. ' 'If there is no variable for the specified serian mumber (T is not positive 'or larger than the number of variables) the function returns T. ' 'long scriba_GetVariableType(pSbProgram pProgram, long lSerial); DECLARE FUNCTION scriba_GetVariableType ALIAS "scriba_GetVariableType" (BYVAL pSbProgram AS DWORD, BYVAL lSerial AS LONG) AS LONG 'GET VARIABLE 'This function retrieves the value of a variable. 'A new T object is created and the pointer to it 'is returned in T. This memory space is automatically 'reclaimed when the program object is destroyed or the function 'T can be called. ' 'The argument T should be the serial number of the global variable 'as returned by R. ' 'The funtion returns T on success, ' 'T if the data cannot be created or ' 'T if the parameter T is invalid. ' 'int scriba_GetVariable(pSbProgram pProgram, long lSerial, pSbData *pVariable); DECLARE FUNCTION scriba_GetVariable ALIAS "scriba_GetVariable" (BYVAL pSbProgram AS DWORD, BYVAL lSerial AS LONG, pVariable AS SbData) AS LONG 'SET VARIABLE 'This function sets the value of a global BASIC variable. You can call this function after 'executing the program before it is reexecuted or after successfull call to R. ' 'The argument T should be the serial number of the global variable 'as returned by R. ' 'The argument T should be one of the followings: ' '=itemize '=item T '=item T '=item T '=item T '=item T '=noitemize ' 'The function uses one of the arguments T, T or T and 'the other two are ignored based on the value of the argument T. ' 'If the value of the argument T is T all initialization arguments are ignored and the 'global variable will get the value T. ' 'If the value of the argument T is T the argument T will be used and the global 'variable will be double holding the value. ' 'If the value of the argument T is T the argument T will be used and the global 'variable will be long holding the value. ' 'If the value of the argument T is T the argument T 'will be used and the global variable will be long holding the value. The length of the string 'should in this case be specified by the variable T. ' 'If the value of the argument T is T the argument T 'will be used and the global variable will be long holding the value. The length of the string 'is automatically calculated and the value passed in the variable T is ignored. In this case the 'string T should be zero character terminated. ' 'The funtion returns T on success, ' 'T if the data cannot be created or ' 'T if the parameter T is invalid. ' 'int scriba_SetVariable(pSbProgram pProgram, long lSerial, int type, long lSetValue, double dSetValue, char *pszSetValue, unsigned long size); DECLARE FUNCTION scriba_SetVariable ALIAS "scriba_SetVariable" (BYVAL pSbProgram AS DWORD, BYVAL lSerial AS LONG, BYVAL TYPE AS LONG, BYVAL lSetValue AS LONG, BYVAL dSetValue AS DOUBLE, pszSetValue AS ASCIIZ, BYVAL SIZE AS DWORD) AS _ LONG 'INIT STATIC MODULES 'This function calls the initialization functions of the modules that are statically linked 'into the interpreter. This is essential to call this fucntion from the embedding T program 'in a variation that has one or more external modules staticallyl linked. If this function is not 'called the module initialization will not be called, because the module is never actually loaded and 'thus the operating system does not call the T or T<_init> function. ' 'The function has to be called before the first interpreter thread starts. In case of a single 'thread variation this means that the function has to be called before the BASIC program starts. ' 'The function does not take any argument and does not return any value. ' 'void scriba_InitStaticModules(void); DECLARE SUB scriba_InitStaticModules ALIAS "scriba_InitStaticModules" () 'FINISH STATIC MODULES 'This function calls the finalization functions of the modules that are statically linked 'to the interpreter. Such a function for a dynamically loaded module is started by the operating 'system. Because the sttaically linked modules are not loaded the T<_fini> function is not called 'by the UNIX loader and similarly the function T is not called by Windows NT. Because some 'modules depend on the execution of this function this function has to be called after the last 'interpreter thread has finished. ' 'void scriba_FinishStaticModules(void); DECLARE SUB scriba_FinishStaticModules ALIAS "scriba_FinishStaticModules" ()