310 likes | 409 Views
ScriptBasic Preprocesszor , Külső Modulok, API. Peter Verh á s 2002 március 12. Tartalom. Külső és belső preprocesszor Külső modulok ScriptBasic API Minden amiről itt szó van a devguide dokumentációban szerepel részletesen. Mire kell egy preprocesszor. Nyelv kiegészítése
E N D
ScriptBasic Preprocesszor, Külső Modulok, API Peter Verhás 2002 március 12.
Tartalom • Külső és belső preprocesszor • Külső modulok • ScriptBasic API • Minden amiről itt szó van a devguide dokumentációban szerepel részletesen.
Mire kell egy preprocesszor • Nyelv kiegészítése • A nyelv megváltoztatása nélkül • Többféle, egymásnak akár ellentmondó kiegészítés együttélése
PREPROCESSZOR Mit tesz egy preprocesszor? Forrás fájl Generált BASIC fájl
Külső preprocesszor • Külső processz, külön program • Bármilyen nyelven írható • Nem kell ismerni a ScriptBasic belső szerkezetét • Egymás után akár több is alkalmazható • „Lassú” (mert külön processz és fájl kezelés • CPP, m4, jamal
Belső preprocesszor • DLL vagy SO • Szorosan kapcsolódik a ScriptBasic-hez • Processzen belül működik • Beolvasás előtt, után töltődik, és • hozzáfér a belső adatszerkezetekhez • Egyszerre akár több is, párhuzamosan
Belső preprocesszor függvény? int DLL_EXPORT preproc(pPrepext pEXT, long *pCmd, void *p); Argumentumok: • pEXTelőkészített saját Prepext struktúrára mutat (következő dia) • pCmdIN: parancs, OUT: eredmény • P mutató különböző struktúrákhoz
Visszatérési érték *pCMD-ben int DLL_EXPORT preproc(pPrepext pEXT, long *pCmd, void *p); • PreprocessorContinue rendben, többi preprocesszor jön • PreprocessorDonerendben, többi preprocesszor NEM jön • PreprocessorUnloadrendben, preprocesszor kilép return 0; nincs hiba return iErrorCode;
Preprocesszor struct typedef struct _Prepext { long lVersion; Interface verzió, amelyet a ScriptBasic vár void *pPointer; NULL pointer, amelyet a ScriptBasic nem használ semmire void *pMemorySegment; struct _SupportTable *pST; Call-back függvények táblája } Prepext, *pPrepext;
Belépési pontok • PreprocessorLoad • PreprocessorReadStart • PreprocessorReadDone0/1/2/3 • PreprocessorLexInit/Done/element • PreprocessorExStart/StartLine/End/Finish/StartLocal/EndLocal/LineNode • PreprocessorExeStart/Finish/NoRun
Mire mutat p? (példa) • PreprocessorLoad, p = NULL • PreprocessotReadStart,p=pReadObjectpRo • PreprocessorExeStart, p=pExecuteObject pEo
Külső modulok • DLL/SO futási időbeli modulok • Nem kapcsolódnak szorosan a nyelvhez, nem nyelvi elem • Más programozó írja, máskor, máshol, másnak • Például: MySQL, CGI, HASH, MT, NT, UX ScriptBasic interpreter interface MI MI MI MI Modul Modul Modul külső könyvtár
Megoldandó feladatok: • Különböző verziók együttélése • Legalább ne haljon meg! • Modul inicializálás, takarítás • Több modul egyszerre • Egy modul több szálon
Nem megoldandó: • BASIC-ből nem hívható tetszőleges DLL/SO • Csak speciális ScriptBasic modul DLL/SO • Egy modul, egy interpreterben csak egyszer
A feladatok megoldása • Verziók: modul betöltésekor interface verzió tárgyalás • Inicializálás/takarítás: betöltéskor bootmodu, program futás végén végén finimodu • Több modul: modul tábla • Több szál: modul pointer
Külső modulok függvényeinek deklarációja BASIC függvény név declare sub apple alias _ "trial" lib "ext_tial" declare command iff alias _ "iff" lib "ext_tial" ext_tiral.dll modul név C függvény név
Modulokban a függvények implementálása besFUNCTION(apple) ... besEND besCOMMAND(iff) ... besEND_COMMAND A makrók a basext.h függvényben vannak definiálva.
besFUNCTION, besCOMMAND #define besFUNCTION(X) \ DLL_EXPORT int X(pSupportTable pSt, \ void **ppModuleInternal, \ pFixSizeMemoryObject pParameters, \ pFixSizeMemoryObject *pReturnValue){\ ... #define besCOMMAND(x) \ DLL_EXPORT int x(pExecuteObject pEo, \ void **ppModuleInternal){\ ...
Modul felület verzió tárgyalás besVERSION_NEGOTIATE printf("Requested version is %d\n",Version); printf("Variation is: %s\n",pszVariation); printf("Accepted version %d\n",(int)INTERFACE_VERSION); return (int)INTERFACE_VERSION; besEND #define besVERSION_NEGOTIATE \ int DLL_EXPORT versmodu(int Version, \ char *pszVariation, \ void **ppModuleInternal){
Inicializálás, takarítás • besSUB_START • besFUNCTION(bootmodu) • besSUB_FINISH • besFUNCTION(finimodu) Ezek a függvények minden egyes interpreter szálra vannak meghívva.
Tipikus modul csontváz #include "../../basext.h" typedef _ModuleClass { ... } ModuleClass; besVERSION_NEGOTIATE return (int)INTERFACE_VERSION; besEND besSUB_START besMODULEPOINTER = besALLOC(sizeof(ModuleClass)); if( besMODULEPOINTER == NULL )return 0; besEND besSUB_FINISH // erőforrások felszabadítása // memória felszabadul automatikusan besEND besFUNCTION(...) ... besEND besCOMMAND(...) ... besEND_COMMAND
Tipikus modul függvény csontváz (példa: MySQL modul) besFUNCTION(mys_affected_rows) VARIABLE Argument; pmymysqlHANDLE q; pmyOBJECT p; p = (pmyOBJECT)besMODULEPOINTER; Argument = besARGUMENT(1); besDEREFERENCE(Argument); if( ! Argument )return EX_ERROR_TOO_FEW_ARGUMENTS; q = besHandleGetPointer( p->HandleArray, besGETLONGVALUE(Argument)); if( q == NULL )return COMMAND_ERROR_ARGUMENT_RANGE; besALLOC_RETURN_LONG; LONGVALUE(besRETURNVALUE) = (long)mysql_affected_rows(q->hSQL); besEND
(nem 4 jegyű) Függvény Tábla Struct _SupportTable { ScriptBasic long function(...){ ... } } Modul besFUNCTION(XXX) pST->function(...) besEND
Modul lehetőségek • Modul megváltoztathatja a SupportTable tartalmát! • Modul megváltoztathatja a CommandTable tartalmát, de • javasolt (kötelező) előtte a besCOPYCOMMANDTABLE
Többszálú modulok (példa: MT) • Olyan modul, amelyik több interpreter szálat is kiszolgál • Példa: • állapot változók http hitek között • interpreter szálak közötti szinkronizáció Részletesen egy hét múlva
ScriptBasic C API • Objektum orientált magas szintű API • scriba_new(), scriba_destroy() • pSbProgram objektum típus • Minden más függvény ezen az objektumon dolgozik
Feladatok, amiket az API megold • Konfiguráció beolvasás, öröklés • Belső preprocesszor betöltése (ha kell) • Külső preprocesszor futtatása (ha kell) • Program beolvasás/fordítás, vagy bináris betöltés • Bináris program elmentése • Program futtatás/nem futtatás • BASIC függvény meghívása • Globális változó manipulálás
Példa: scribacmd.c1/3 #include <stdio.h> #include <stdlib.h> #include <string.h> #include "../../getopt.h" #include "../../scriba.h" #include "../../basext.h" main(int argc, char *argv[], char *env[])@{ . . . . változó deklaráció . . . . . pSbProgram pProgram; . . . . parancssor értelmezés . . . . pProgram = scriba_new(malloc,free); scriba_LoadConfiguration(pProgram,pszForcedConfigurationFileName);
Példa: scribacmd.c2/3 iError = scriba_LoadInternalPreprocessor(pProgram,pszIPreproc); ... scriba_SetFileName(pProgram,szInputFile); ... if( scriba_UseCacheFile(pProgram) == SCRIBA_ERROR_SUCCESS ){ if( (iError = scriba_LoadBinaryProgram(pProgram)) != 0 ){ ERREXIT; } ... iError=scriba_RunExternalPreprocessor(pProgram,pszEPreproc); if( scriba_LoadSourceProgram(pProgram) )ERREXIT;
Példa: scribacmd.c3/3 if( szOutputFile ){ if( isCoutput ) scriba_SaveCCode(pProgram,szOutputFile); else scriba_SaveCode(pProgram,szOutputFile); if( !execute )exit(0); } if( ! nocache )scriba_SaveCacheFile(pProgram); if( iError=scriba_Run(pProgram,CmdLinBuffer) ){ report_report( ... ); ERREXIT; } scriba_destroy(pProgram);