The Perl and Raku Conference 2025: Greenville, South Carolina - June 27-29 Learn more

/*###################################################################################
#
# Embperl - Copyright (c) 1997-2001 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: epdat.h,v 1.37 2001/11/02 10:03:48 richter Exp $
#
###################################################################################*/
#ifdef EP2
/*-----------------------------------------------------------------*/
/* */
/* 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 */
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 */
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 */
} 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 * 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
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 * sSessionID ; /* stores session name and id for status session data */
#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 */
#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 <TABLE> */
int nTabMaxRow ; /* maximum rows for next table (only takes affect after next <TABLE> */
int nTabMaxCol ; /* maximum columns for next table (only takes affect after next <TABLE> */
/* --- Escaping --- */
struct tCharTrans * pCurrEscape ; /* pointer to current escape table */
struct tCharTrans * pNextEscape ; /* pointer to next escape table (after end of block) */
int nEscMode ; /* escape mode set by the user */
int nCurrEscMode ; /* current active escape mode */
int bEscModeSet ; /* escape mode already set in this block */
int bEscInUrl ; /* we are inside an url */
/* --- memory management --- */
size_t nAllocSize ; /* Alloced memory for debugging */
/* --- buffering output */
struct tBuf * pFirstBuf ; /* First buffer */
struct tBuf * pLastBuf ; /* Last written buffer */
struct tBuf * pFreeBuf ; /* List of unused buffers */
struct tBuf * pLastFreeBuf ; /* End of list of unused buffers */
char * pMemBuf ; /* temporary output */
char * pMemBufPtr ; /* temporary output */
size_t nMemBufSize ; /* size of pMemBuf */
size_t nMemBufSizeFree;/* remaining space in pMemBuf */
int nMarker ; /* Makers for rollback output */
/* --- i/o filehandles --- */
#ifdef PerlIO
PerlIO * ifd ; /* input file */
PerlIO * ofd ; /* output file */
PerlIO * lfd ; /* log file */
#else
FILE * ifd ; /* input file */
FILE * ofd ; /* output file */
FILE * lfd ; /* log file */
#endif
SV * ofdobj ; /* perl object that is tied to stdout, if any */
SV * ifdobj ; /* perl object that is tied to stdin, if any */
long nLogFileStartPos ; /* file position of logfile, when logfile started */
char * sOutputfile ; /* name of output file */
bool bAppendToMainReq ; /* append output to main request */
bool bDisableOutput ; /* no output is generated */
SV * pOutData ;
SV * pInData ;
/* ------------------------ */
tReq * pNext ; /* Next free one */
tReq * pLastReq ; /* Request from which this one is called */
/* ------------------------ */
/* --- keep track of errors --- */
bool bError ; /* Error has occured somewhere */
I32 nLastErrFill ; /* last size of error array */
int bLastErrState ; /* last state of error flag */
AV * pErrArray ; /* Errors to show on Error response */
AV * pErrFill ; /* AvFILL of pErrArray, index is nMarker */
AV * pErrState ; /* bError, index is nMarker */
/* Everything after here will not automaticly set to zero */
int zeroend ;
char errdat1 [ERRDATLEN] ; /* Additional error information */
char errdat2 [ERRDATLEN] ;
char lastwarn [ERRDATLEN] ; /* last warning */
/* --- Embperl special hashs/arrays --- */
HV * pEnvHash ; /* environement from CGI Script */
HV * pFormHash ; /* Formular data */
HV * pFormSplitHash ; /* Formular data split up at \t */
HV * pInputHash ; /* Data of input fields */
AV * pFormArray ; /* Fieldnames */
HV * pUserHash ; /* Session User data */
HV * pStateHash ; /* Session State data */
HV * pModHash ; /* Module data */
HV * pHeaderHash ;/* http headers */
#ifdef EP2
AV * pDomTreeAV ; /* holds all DomTrees alocated during the request */
AV * pCleanupAV ; /* set all sv's that are conatined in that array to undef after the whole request */
#endif
/* --- for statistics --- */
clock_t startclock ;
I32 stsv_count ;
I32 stsv_objcount ;
I32 lstsv_count ;
I32 lstsv_objcount ;
int numEvals ;
int numCacheHits ;
/* --- more infos for eval --- */
int bStrict ; /* aply use strict in each eval */
char op_mask_buf[MAXO + 100]; /* save buffer for opcode mask - maxo shouldn't differ from MAXO but leave room anyway (see BOOT:) */
HV * pImportStash ; /* stash for package, where new macros should be imported */
#ifdef EP2
char * * pProg ; /* pointer into currently compiled code */
char * pProgRun ; /* pointer into currently compiled run code */
char * pProgDef ; /* pointer into currently compiled define code */
SV * pCodeSV ; /* contains currently compiled line */
#endif
} ;
#define EPMAINSUB "_ep_main"