/*################################################################################### # # Embperl - Copyright (c) 1997-2004 Gerald Richter / ECOS # # You may distribute under the terms of either the GNU General Public # License or the Artistic License, as specified in the Perl README file. # For use with Apache httpd and mod_perl, see also Apache copyright. # # THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED # WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. # # $Id$ # ###################################################################################*/ #ifdef EP2 struct tCacheItem ; /*-----------------------------------------------------------------*/ /* */ /* cache Options */ /* */ /*-----------------------------------------------------------------*/ typedef enum tCacheOptions { ckoptCarryOver = 1, /* use result from CacheKeyCV of preivious step if any */ ckoptPathInfo = 2, /* include the PathInfo into CacheKey */ ckoptQueryInfo = 4, /* include the QueryInfo into CacheKey */ ckoptDontCachePost = 8, /* don't cache POST requests */ ckoptDefault = 15 /* default is all options set */ } tCacheOptions ; /*-----------------------------------------------------------------*/ /* */ /* Processor */ /* */ /*-----------------------------------------------------------------*/ typedef struct tProcessor { int nProcessorNo ; const char * sName ; int (* pPreCompiler) (/*in*/ tReq * r, /*in*/ struct tProcessor * pProcessor, /*in*/ tDomTree ** ppDomTree, /*in*/ SV ** ppPreCompResult, /*out*/ SV ** ppCompResult) ; int (* pCompiler) (/*in*/ tReq * r, /*in*/ struct tProcessor * pProcessor, /*in*/ tDomTree ** ppDomTree, /*in*/ SV ** ppPreCompResult, /*out*/ SV ** ppCompResult) ; int (* pPreExecuter) (/*in*/ tReq * r, /*in*/ struct tProcessor * pProcessor, /*in*/ tDomTree ** pDomTree, /*in*/ SV ** ppPreCompResult, /*in*/ SV ** ppCompResult) ; int (* pExecuter) (/*in*/ tReq * r, /*in*/ struct tProcessor * pProcessor, /*in*/ tDomTree ** pDomTree, /*in*/ SV ** ppPreCompResult, /*in*/ SV ** ppCompResult, /*out*/ SV ** ppExecResult) ; const char * sCacheKey ; /* literal to add to key for cache */ CV * pCacheKeyCV ; /* CV to call and add result to key for cache */ tCacheOptions bCacheKeyOptions ; double nOutputExpiresIn ; CV * pOutputExpiresCV ; struct tProcessor * pNext ; } tProcessor ; /*-----------------------------------------------------------------*/ /* */ /* RequestPhases */ /* */ /*-----------------------------------------------------------------*/ typedef enum { phInit, phParse, phCompile, phRunAfterCompile, phPerlCompile, phRun, phTerm } tPhase ; /*-----------------------------------------------------------------*/ /* */ /* Parser data structures */ /* */ /*-----------------------------------------------------------------*/ typedef unsigned char tCharMap [256/(sizeof(unsigned char)*8)] ; struct tToken { const char * sText ; /* string of token (MUST be first item!) */ const char * sName ; /* name of token (only for description) */ int nTextLen ; /* len of string */ const char * sEndText ; /* string which ends the block */ const char * sNodeName; /* name of the node to create */ int nNodeName ; /* index in string table of node name */ tNodeType nNodeType ; /* type of the node that should be created */ tNodeType nCDataType ;/* type for sub nodes that contains text */ tNodeType nForceType ;/* force this type for sub nodes */ int bUnescape ; /* translate input? */ int bAddFlags ; /* add flags to node */ int bRemoveSpaces ; /* 1 remove spaces before tag, 2 remove after */ unsigned char * pContains ; /* chars that could be contained in the string */ int bInsideMustExist ; /* if inside definition doesn't exists, ignore whole tag */ int bMatchAll ; /* match any start text */ int bDontEat ; /* don't eat the characters when parsing this token (look ahead) */ int bExitInside ;/* when this tag is found exit the inside table */ struct tTokenTable * pFollowedBy;/* table of tokens that can follow this one */ struct tTokenTable * pInside ; /* table of tokens that can apear inside this one */ struct tToken * pStartTag ; /* token that contains definition for the start of the current token */ struct tToken * pEndTag ; /* token that contains definition for the end of the current token */ const char * sParseTimePerlCode ; /* perl code that is executed when this token is parsed, %% is replaced by the value of the current attribute */ } ; struct tTokenTable { void * pCompilerInfo ; /* stores tables of the compiler , must be first item */ const char * sName ; /* name of syntax */ const char * sRootNode ; /* name of root node */ tCharMap cStartChars ; /* for every vaild start char there is one bit set */ tCharMap cAllChars ; /* for every vaild char there is one bit set */ struct tToken * pTokens ; /* table with all tokens */ int numTokens ; /* number of tokens in above table */ int bLSearch ; /* when set perform a linear, instead of a binary search */ int nDefNodeType ; /* either ntypCDATA or ntypText */ struct tToken * pContainsToken ;/* pointer to the token that has a pContains defined (could be only one per table) */ } ; typedef struct tTokenTable tTokenTable ; #else typedef void * tTokenTable ; #endif /*-----------------------------------------------------------------*/ /* */ /* Per (directory) configuration data */ /* */ /*-----------------------------------------------------------------*/ typedef struct tConf { HV * pReqParameter ; /* parameters passed to this request */ int bDebug ; /* Debugging options */ int bOptions ; /* Options */ char * sPackage ; /* Packagename */ char * sLogFilename ; /* name of logfile */ char * sVirtLogURI ; /* uri for access virtual log file */ SV * pOpcodeMask ; /* Opcode mask (if any) */ int nEscMode ; /* default escape mode */ char * sCookieName ; /* Name to use for cookie */ char * sCookieExpires ; /* cookie expiration time */ char * sCookieDomain ; /* domain patter for which the cookie should be returned */ char * sCookiePath ; /* path to which cookie should be returned */ char cMultFieldSep ; char * pOpenBracket ; char * pCloseBracket ; #ifdef EP2 bool bEP1Compat ; /* run in Embperl 1.x compatible mode */ tProcessor ** pProcessor ; /* [array] processors used to process the file */ char * sCacheKey ; /* Key used to store expires setting */ CV * pCacheKeyCV ; /* CV to call and add result to key for cache */ tCacheOptions bCacheKeyOptions ; double nExpiresIn ; /* Data expiers at */ CV * pExpiresCV ; /* sub that is called to determinate expiration */ char * sRecipe ; /* name of recipe used to process the current file */ #endif char * sPath ; /* file search path */ char * sReqFilename ; /* filename of original request */ int nSessionMode ; /* session mode */ } tConf ; /*-----------------------------------------------------------------*/ /* */ /* Per sourcefile data */ /* */ /*-----------------------------------------------------------------*/ typedef struct tFile { char * sSourcefile ; /* Name of sourcefile */ double mtime ; /* last modification time of file */ size_t nFilesize ; /* size of File */ SV * pBufSV ; /* SV that contains the file content */ bool bKeep ; /* set true if you want to keep file in memory */ HV * pCacheHash ; /* Hash containing CVs to precompiled subs */ char * sMainSub ; /* Name of sub to call */ char * sCurrPackage ; /* Package of file */ STRLEN nCurrPackage ; /* Package of file (length) */ HV * pExportHash ; /* exportable Macros */ int nFirstLine ; /* First line number of sourcefile */ struct tFile * pNext2Free ; /* Next file that has to be freed after the request */ } tFile ; /*-----------------------------------------------------------------*/ /* */ /* Per sourcebuffer data */ /* */ /*-----------------------------------------------------------------*/ typedef struct tSrcBuf { tFile * pFile ; /* pointer source file/package specific data */ char * pBuf ; /* Buffer which holds the html source file */ char * pCurrPos ; /* Current position in html file */ char * pCurrStart ; /* Current start position of html tag / eval expression */ char * pEndPos ; /* end of html file */ int nBlockNo ; /* Block number where we are currently */ char * pCurrTag ; /* Current start position of html tag */ int nSourceline ; /* Currentline in sourcefile */ char * pSourcelinePos ; /* Positon of nSourceline in sourcefile */ char * pLineNoCurrPos ; /* save pCurrPos for line no calculation */ char * sEvalPackage ; /* Package for eval (normaly same sCurrPackage, differs when running in a safe namespace */ STRLEN nEvalPackage ; /* Package for eval (length) */ } tSrcBuf ; /*-----------------------------------------------------------------*/ /* */ /* Commandtypes */ /* */ /*-----------------------------------------------------------------*/ enum tCmdType { cmdNorm = 1, cmdIf = 2, cmdEndif = 4, cmdWhile = 8, cmdTable = 16, cmdTablerow = 32, cmdTextarea = 64, cmdDo = 128, cmdForeach = 256, cmdSub = 512, cmdAll = 1023 } ; enum tCmdNo { cnNop, cnTable, cnTr, cnDir, cnMenu, cnOl, cnUl, cnDl, cnSelect, cnDo, cnForeach } ; /*-----------------------------------------------------------------*/ /* */ /* Commands */ /* */ /*-----------------------------------------------------------------*/ typedef struct tCmd { const char * sCmdName ; /* Commandname */ int ( *pProc)(/*i/o*/ register req * r, /*in*/ const char * sArg) ; /* pointer to the procedure */ bool bPush ; /* Push current state? */ bool bPop ; /* Pop last state? */ enum tCmdType nCmdType ; /* Type of the command */ bool bScanArg ; /* is it nessesary to scan the command arg */ bool bSaveArg ; /* is it nessesary to save the command arg for later use */ enum tCmdNo nCmdNo ; /* number of command to catch mismatch in start/end */ int bDisableOption ; /* option bit which disables this cmd */ bool bHtml ; /* this is an html tag */ } tCmd ; /*-----------------------------------------------------------------*/ /* */ /* Command/HTML-Stack */ /* */ /*-----------------------------------------------------------------*/ typedef struct tStackEntry { enum tCmdType nCmdType ; /* Type of the command which the pushed the entry on the stack */ char * pStart ; /* Startposition for loops */ int nBlockNo ; /* Block number where the startposition is */ long bProcessCmds ; /* Process corresponding cmds */ int nResult ; /* Result of Command which starts the block */ char * sArg ; /* Argument of Command which starts the block */ SV * pSV ; /* Additional Data */ SV * pSV2 ; /* Additional Data */ struct tBuf * pBuf; /* Output buf for table rollback */ struct tCmd * pCmd ; /* pointer to command infos */ struct tStackEntry * pNext ; /* pointer to next one on stack/free list */ } tStackEntry ; /*-----------------------------------------------------------------*/ /* */ /* Table-Stack */ /* */ /*-----------------------------------------------------------------*/ typedef struct tTableStackEntry { int nResult ; /* Result of Command which starts the block */ int nCount ; /* Count for tables, lists etc */ int nCountUsed ; /* Count for tables, lists is used in Table */ int nRow ; /* Row Count for tables, lists etc */ int nRowUsed ; /* Row Count for tables, lists is used in Table */ int nCol ; /* Column Count for tables, lists etc */ int nColUsed ; /* Column Count for tables, lists is used in Table */ int nMaxRow ; /* maximum rows */ int nMaxCol ; /* maximum columns */ int nTabMode; /* table mode */ int bHead ; /* this row contains a heading */ int bRowHead ; /* the entire row is made of th tags */ struct tTableStackEntry * pNext ; /* pointer to next one on stack/free list */ } tTableStackEntry ; /*-----------------------------------------------------------------*/ /* */ /* Stack-Pointer */ /* */ /*-----------------------------------------------------------------*/ typedef struct tStackPointer { struct tStackEntry * pStack ; /* pointer to stacked entrys */ struct tStackEntry * pStackFree ; /* pointer to currently unused entrys */ struct tStackEntry State ; /* top of stack */ } tStackPointer ; typedef struct tTableStackPointer { struct tTableStackEntry * pStack ; /* pointer to stacked entrys */ struct tTableStackEntry * pStackFree ; /* pointer to currently unused entrys */ struct tTableStackEntry State ; /* top of stack */ } tTableStackPointer ; /*-----------------------------------------------------------------*/ /* */ /* Per request data */ /* */ /*-----------------------------------------------------------------*/ #define ERRDATLEN 1024 #ifdef WIN32 #define pid_t int #endif struct tReq { SV * pReqSV ; /* The perl reference to this request structure */ #ifdef APACHE request_rec * pApacheReq ; /* apache request record */ SV * pApacheReqSV ; #endif SV * pApplication ; /* application object */ pid_t nPid ; /* process/thread id */ tConf * pConf ; /* pointer to configuration data */ bool bReqRunning ; /* we are inside of a request */ int bDebug ; /* Debugging options */ int bOptions ; /* Options */ int nIOType ; bool bSubReq ; /* This is a sub request (called inside an Embperl page) */ char * sSubName ; /* subroutine to call */ int nSessionMgnt ; /* how to retrieve the session id */ int nInsideSub ; /* Are we inside of a sub? */ int bExit ; /* We should exit the page */ int nPathNdx ; /* gives the index in the path where the current file is found */ char sCWD[PATH_MAX] ; /**< Current working directory */ char sResetDir[PATH_MAX] ; /**< Reset directory to */ #ifdef WIN32 char nResetDrive ; /**< Reset drive to */ #endif int nRequestCount ; /**< increments by one on each request */ time_t nRequestTime ; /**< time when request starts */ char * sSessionID ; /* stores session name and id for status session data */ bool bIsFormHashSetup ; /* Formular data has been read */ #ifdef EP2 bool bEP1Compat ; /* run in Embperl 1.x compatible mode */ tPhase nPhase ; /* which phase of the request we are in */ char * sPathInfo ; char * sQueryInfo ; /* --- DomTree ---*/ tNode xDocument ; /* Document node */ tNode xCurrNode ; /* node that was last executed */ tRepeatLevel nCurrRepeatLevel ; /* repeat level for node that was last executed */ tIndex nCurrCheckpoint ; /* next checkpoint that should be passed if execution order is unchanged (i.e. no loop/if) */ tIndex xCurrDomTree ; /* DomTree we are currently working on */ tIndex xSourceDomTree ;/* DomTree which contains the source */ struct tCacheItem * pOutputCache ; /* Cache which hold the final output */ SV * pOutputSV ; /* set if output is text and not a tree */ #endif struct tTokenTable * pTokenTable ; /* holds the current syntax */ /* --- Source in memory --- */ tSrcBuf Buf ; /* Buffer */ tSrcBuf * pBufStack ; /* pointer to buffer stack */ tSrcBuf * pBufStackFree ; /* pointer to buffer stack free list*/ tFile * pFiles2Free ; /* files that has to be freed after the request (only valid in main request) */ /* --- command handling --- */ tCmd * pCurrCmd ; /* Current cmd which is excuted */ /* --- Stacks --- */ tStackPointer CmdStack ; /* Stack for if, while, etc. */ tStackPointer HtmlStack ; /* Stack for table etc. */ tTableStackPointer TableStack ; /* Stack for table */ /* --- Tablehandling --- */ int nTabMode ; /* mode for next table (only takes affect after next