#include "ep.h"
#include "epmacro.h"
int
EvalDirect (
register
req * r,
SV * pArg,
int
numArgs,
SV ** pArgs)
{
epTHX_
dSP;
SV * pSVErr ;
int
num ;
int
n ;
tainted = 0 ;
PUSHMARK(sp);
for
(num = 0; num < numArgs; num++)
XPUSHs(pArgs [num]) ;
PUTBACK;
#if PERL_VERSION >= 14
n = perl_eval_sv(pArg, G_SCALAR);
#else
n = perl_eval_sv(pArg, G_SCALAR | G_KEEPERR);
#endif
SPAGAIN;
if
(n > 0)
pSVErr = POPs;
PUTBACK;
tainted = 0 ;
pSVErr = ERRSV ;
if
(SvTRUE (pSVErr))
{
STRLEN l ;
char
* p = SvPV (pSVErr, l) ;
if
(l >
sizeof
(r -> errdat1) - 1)
l =
sizeof
(r -> errdat1) - 1 ;
strncpy
(r -> errdat1, p, l) ;
if
(l > 0 && r -> errdat1[l-1] ==
'\n'
)
l-- ;
r -> errdat1[l] =
'\0'
;
if
(SvROK (pSVErr))
{
if
(r -> pErrSV)
SvREFCNT_dec(r -> pErrSV) ;
r -> pErrSV = newRV (SvRV(pSVErr)) ;
}
sv_setpv(pSVErr,
""
);
return
rcEvalErr ;
}
return
ok ;
}
int
EvalConfig (
tApp * a,
SV * pSV,
int
numArgs,
SV ** pArgs,
const
char
* sContext,
CV ** pCV)
{
char
* s =
"Needs CodeRef"
;
#ifdef PERL_IMPLICIT_CONTEXT
pTHX = a?a -> pPerlTHX:PERL_GET_THX;
#endif
dSP;
EPENTRY (EvalConfig) ;
tainted = 0 ;
*pCV = NULL ;
if
(SvPOK (pSV))
{
STRLEN l ;
s = SvPV (pSV, l) ;
if
(
strncmp
(s,
"sub "
, 4) == 0)
{
SV * pSVErr ;
SV * pRV = NULL ;
int
n ;
n = perl_eval_sv (pSV, G_EVAL | G_SCALAR) ;
tainted = 0 ;
SPAGAIN;
if
(n > 0)
pRV = POPs;
PUTBACK;
tainted = 0 ;
if
(n > 0 && SvROK (pRV))
{
*pCV = (CV *)SvRV (pRV) ;
SvREFCNT_inc (*pCV) ;
}
pSVErr = ERRSV ;
if
(SvTRUE (pSVErr))
{
STRLEN l ;
char
* p = SvPV (pSVErr, l) ;
LogErrorParam (a, rcEvalErr, p, sContext) ;
sv_setpv(pSVErr,
""
);
*pCV = NULL ;
return
rcEvalErr ;
}
}
else
{
*pCV = perl_get_cv (s, 0) ;
SvREFCNT_inc (*pCV) ;
}
}
else
{
if
(SvROK (pSV))
{
*pCV = (CV *)SvRV (pSV) ;
}
}
if
(!*pCV || SvTYPE (*pCV) != SVt_PVCV)
{
*pCV = NULL ;
LogErrorParam (a, rcEvalErr, s, sContext) ;
return
rcEvalErr ;
}
#ifdef DMALLOC
AddDMallocMagic (*pCV, s?s:
"EvalConfig"
, __FILE__, __LINE__) ;
#endif
return
ok ;
}
int
EvalRegEx (
tApp * a,
char
* sRegex,
const
char
* sContext,
CV ** ppCV)
{
epaTHX_
SV * pSV ;
char
* p ;
STRLEN l ;
SV * pRV = NULL ;
SV * pSVErr ;
char
c ;
int
n ;
dSP ;
if
(sRegex[0] ==
'!'
)
{
c =
'!'
;
while
(
isspace
(*sRegex))
sRegex++ ;
}
else
c =
'='
;
tainted = 0 ;
pSV = newSVpvf (
"package Embperl::Regex ; sub { $_[0] %c~ m{%s} }"
, c, sRegex) ;
newSVpvf2(pSV) ;
n = perl_eval_sv (pSV, G_EVAL | G_SCALAR) ;
SvREFCNT_dec(pSV);
tainted = 0 ;
SPAGAIN;
if
(n > 0)
pRV = POPs;
PUTBACK;
pSVErr = ERRSV ;
if
(SvTRUE (pSVErr))
{
p = SvPV (pSVErr, l) ;
LogErrorParam (a, rcEvalErr, p, sContext) ;
sv_setpv(pSVErr,
""
);
*ppCV = NULL ;
return
rcEvalErr ;
}
if
(n > 0 && SvROK (pRV))
{
*ppCV = (CV *)SvRV (pRV) ;
SvREFCNT_inc (*ppCV) ;
#ifdef DMALLOC
AddDMallocMagic (*ppCV, sRegex?sRegex:
"EvalRegEx"
, __FILE__, __LINE__) ;
#endif
}
else
*ppCV = NULL ;
return
ok ;
}
static
int
EvalAll (
register
req * r,
const
char
* sArg,
int
flags,
const
char
* sName,
SV ** pRet)
{
epTHX_
static
char
sFormat [] =
"package %s ; %s sub %s { \n#line %d \"%s\"\n%s\n} %s%s"
;
static
char
sFormatStrict [] =
"package %s ; %s use strict ; sub %s {\n#line %d \"%s\"\n%s\n} %s%s"
;
static
char
sFormatArray [] =
"package %s ; %s sub %s { \n#line %d \"%s\"\n[%s]\n} %s%s"
;
static
char
sFormatStrictArray [] =
"package %s ; %s use strict ; sub %s {\n#line %d \"%s\"\n[%s]\n} %s%s"
;
SV * pSVCmd ;
SV * pSVErr ;
int
n ;
char
* sRef =
""
;
char
* use_utf8 =
""
;
dSP;
EPENTRY (EvalAll) ;
GetLineNo (r) ;
if
(r -> Component.Config.bDebug & dbgDefEval)
lprintf (r -> pApp,
"[%d]DEF: Line %d: %s\n"
, r -> pThread -> nPid, r -> Component.nSourceline, sArg?sArg:
"<unknown>"
) ;
tainted = 0 ;
if
(!sName)
sName =
""
;
if
(*sName)
sRef =
"; \\&"
;
if
(
strcmp
(r -> Component.Config.sInputCharset,
"utf8"
) == 0)
use_utf8 =
"use utf8;"
;
if
(r -> Component.bStrict)
if
((flags & G_ARRAY) != G_SCALAR)
pSVCmd = newSVpvf(sFormatStrictArray, r -> Component.sEvalPackage, use_utf8, sName, r -> Component.nSourceline, r -> Component.sSourcefile, sArg, sRef, sName) ;
else
pSVCmd = newSVpvf(sFormatStrict, r -> Component.sEvalPackage, use_utf8, sName, r -> Component.nSourceline, r -> Component.sSourcefile, sArg, sRef, sName) ;
else
if
((flags & G_ARRAY) != G_SCALAR)
pSVCmd = newSVpvf(sFormatArray, r -> Component.sEvalPackage, use_utf8, sName, r -> Component.nSourceline, r -> Component.sSourcefile, sArg, sRef, sName) ;
else
pSVCmd = newSVpvf(sFormat, r -> Component.sEvalPackage, use_utf8, sName, r -> Component.nSourceline, r -> Component.sSourcefile, sArg, sRef, sName) ;
newSVpvf2(pSVCmd) ;
PUSHMARK(sp);
#if PERL_VERSION >= 14
n = perl_eval_sv(pSVCmd, G_SCALAR);
#else
n = perl_eval_sv(pSVCmd, G_SCALAR | G_KEEPERR);
#endif
SvREFCNT_dec(pSVCmd);
tainted = 0 ;
SPAGAIN;
if
(n > 0)
*pRet = POPs;
else
*pRet = NULL ;
PUTBACK;
if
(r -> Component.Config.bDebug & dbgMem)
lprintf (r -> pApp,
"[%d]SVs: %d\n"
, r -> pThread -> nPid, sv_count) ;
pSVErr = ERRSV ;
if
(SvTRUE (pSVErr) || (n == 0 && (flags & G_DISCARD) == 0))
{
STRLEN l ;
char
* p = SvPV (pSVErr, l) ;
if
(l >
sizeof
(r -> errdat1) - 1)
l =
sizeof
(r -> errdat1) - 1 ;
strncpy
(r -> errdat1, p, l) ;
if
(l > 0 && r -> errdat1[l-1] ==
'\n'
)
l-- ;
r -> errdat1[l] =
'\0'
;
*pRet = newSVpv (r -> errdat1, 0) ;
sv_setpv(pSVErr,
""
);
return
rcEvalErr ;
}
return
ok ;
}
int
CallCV (
register
req * r,
const
char
* sArg,
CV * pSub,
int
flags,
SV ** pRet)
{
epTHX_
int
num ;
#ifdef TABUSED
int
nCountUsed = r -> TableStack.State.nCountUsed ;
int
nRowUsed = r -> TableStack.State.nRowUsed ;
int
nColUsed = r -> TableStack.State.nColUsed ;
#endif
SV * pSVErr ;
dSP;
if
(r -> Component.pImportStash)
{
*pRet = NULL ;
return
ok ;
}
EPENTRY (CallCV) ;
if
(r -> Component.Config.bDebug & dbgEval)
lprintf (r -> pApp,
"[%d]EVAL< %s\n"
, r -> pThread -> nPid, sArg?sArg:
"<unknown>"
) ;
tainted = 0 ;
ENTER ;
SAVETMPS ;
PUSHMARK(sp);
num = perl_call_sv ((SV *)pSub, flags | G_EVAL | G_NOARGS) ;
tainted = 0 ;
SPAGAIN;
if
(r -> Component.Config.bDebug & dbgMem)
lprintf (r -> pApp,
"[%d]SVs: %d\n"
, r -> pThread -> nPid, sv_count) ;
if
(num == 1)
{
*pRet = POPs ;
if
(SvTYPE (*pRet) == SVt_PVMG)
{
SV * pSV = newSVsv (*pRet) ;
*pRet = pSV ;
}
else
SvREFCNT_inc (*pRet) ;
if
(r -> Component.Config.bDebug & dbgEval)
{
if
(SvOK (*pRet))
lprintf (r -> pApp,
"[%d]EVAL> %s\n"
, r -> pThread -> nPid, SvPV (*pRet, na)) ;
else
lprintf (r -> pApp,
"[%d]EVAL> <undefined>\n"
, r -> pThread -> nPid) ;
}
#ifdef TABUSED
if
((nCountUsed != r -> TableStack.State.nCountUsed ||
nColUsed != r -> TableStack.State.nColUsed ||
nRowUsed != r -> TableStack.State.nRowUsed) &&
!SvOK (*pRet))
{
r -> TableStack.State.nResult = 0 ;
SvREFCNT_dec (*pRet) ;
*pRet = newSVpv(
""
, 0) ;
}
if
((r -> Component.Config.bDebug & dbgTab) &&
(r -> TableStack.State.nCountUsed ||
r -> TableStack.State.nColUsed ||
r -> TableStack.State.nRowUsed))
lprintf (r -> pApp,
"[%d]TAB: nResult = %d\n"
, r -> pThread -> nPid, r -> TableStack.State.nResult) ;
#ifdef DMALLOC
AddDMallocMagic (*pRet, sArg?sArg:
"CallCV"
, __FILE__, __LINE__) ;
#endif
#endif
}
else
if
(num == 0)
{
*pRet = NULL ;
if
(r -> Component.Config.bDebug & dbgEval)
lprintf (r -> pApp,
"[%d]EVAL> <NULL>\n"
, r -> pThread -> nPid) ;
}
else
{
*pRet = &sv_undef ;
if
(r -> Component.Config.bDebug & dbgEval)
lprintf (r -> pApp,
"[%d]EVAL> returns %d args instead of one\n"
, r -> pThread -> nPid, num) ;
}
PUTBACK;
FREETMPS ;
LEAVE ;
if
(r -> bExit || r -> Component.bExit)
{
if
(*pRet)
SvREFCNT_dec (*pRet) ;
*pRet = NULL ;
if
(r -> Component.Config.bDebug & dbgEval)
lprintf (r -> pApp,
"[%d]EVAL> exit passed through\n"
, r -> pThread -> nPid) ;
return
rcExit ;
}
pSVErr = ERRSV ;
if
(SvTRUE (pSVErr))
{
STRLEN l ;
char
* p ;
p = SvPV (pSVErr, l) ;
if
(p && l > 14 &&
strncmp
(p,
">embperl_exit<"
, 14) == 0)
{
tDomTree * pDomTree = DomTree_self (r -> Component.xCurrDomTree) ;
tIndex n = ArrayGetSize (r -> pApp, pDomTree -> pCheckpoints) ;
if
(n > 2)
DomTree_checkpoint (r, n-1) ;
if
(r -> Component.Config.bDebug & dbgEval)
lprintf (r -> pApp,
"[%d]EVAL> exit called\n"
, r -> pThread -> nPid) ;
sv_setpv(pSVErr,
""
);
r -> Component.Config.bOptions |= optNoUncloseWarn ;
r -> bExit = 1 ;
return
rcExit ;
}
if
(l >
sizeof
(r -> errdat1) - 1)
l =
sizeof
(r -> errdat1) - 1 ;
strncpy
(r -> errdat1, p, l) ;
if
(l > 0 && r -> errdat1[l-1] ==
'\n'
)
l-- ;
r -> errdat1[l] =
'\0'
;
if
(SvROK (pSVErr))
{
if
(r -> pErrSV)
SvREFCNT_dec(r -> pErrSV) ;
r -> pErrSV = newRV (SvRV(pSVErr)) ;
}
LogError (r, rcEvalErr) ;
sv_setpv(pSVErr,
""
);
return
rcEvalErr ;
}
return
ok ;
}
int
EvalOnly (
register
req * r,
const
char
* sArg,
SV ** ppSV,
int
flags,
const
char
* sName)
{
int
rc ;
SV * pSub ;
epTHX_
EPENTRY (EvalOnly) ;
r -> lastwarn[0] =
'\0'
;
rc = EvalAll (r, sArg, flags, sName, &pSub) ;
if
(rc == ok && (flags & G_DISCARD))
{
if
(pSub)
SvREFCNT_dec (pSub) ;
return
ok ;
}
if
(ppSV && *ppSV)
SvREFCNT_dec (*ppSV) ;
if
(rc == ok && pSub != NULL && SvROK (pSub))
{
*ppSV = SvRV(pSub) ;
SvREFCNT_inc (*ppSV) ;
}
else
{
if
(pSub != NULL && SvTYPE (pSub) == SVt_PV)
{
*ppSV = pSub ;
pSub = NULL ;
}
else
if
(r -> lastwarn[0] !=
'\0'
)
{
*ppSV = newSVpv (r -> lastwarn, 0) ;
}
else
{
*ppSV = newSVpv (
"Compile Error"
, 0) ;
}
if
(pSub)
SvREFCNT_dec (pSub) ;
r -> bError = 1 ;
return
rc ;
}
return
ok ;
}
#if 0
static
int
EvalAndCall (
register
req * r,
const
char
* sArg,
SV ** ppSV,
int
flags,
SV ** pRet)
{
int
rc ;
epTHX_
EPENTRY (EvalAndCall) ;
if
((rc = EvalOnly (r, sArg, ppSV, flags,
""
)) != ok)
{
*pRet = NULL ;
return
rc ;
}
if
(*ppSV && SvTYPE (*ppSV) == SVt_PVCV)
{
return
CallCV (r, sArg, (CV *)*ppSV, flags, pRet) ;
}
*pRet = NULL ;
r -> bError = 1 ;
if
(ppSV && *ppSV)
SvREFCNT_dec (*ppSV) ;
if
(r -> lastwarn[0] !=
'\0'
)
{
*ppSV = newSVpv (r -> lastwarn, 0) ;
}
else
{
*ppSV = newSVpv (
"Compile Error"
, 0) ;
}
return
rcEvalErr ;
}
#endif
int
CallStoredCV (
register
req * r,
const
char
* sArg,
CV * pSub,
int
numArgs,
SV ** pArgs,
int
flags,
SV ** pRet)
{
epTHX_
int
num ;
SV * pSVErr ;
dSP;
EPENTRY (CallCV) ;
if
(r -> Component.Config.bDebug & dbgEval)
lprintf (r -> pApp,
"[%d]EVAL< %s\n"
, r -> pThread -> nPid, sArg?sArg:
"<unknown>"
) ;
tainted = 0 ;
ENTER ;
SAVETMPS ;
PUSHMARK(sp);
for
(num = 0; num < numArgs; num++)
XPUSHs(pArgs [num]) ;
PUTBACK;
num = perl_call_sv ((SV *)pSub, flags | G_EVAL | (numArgs?0:G_NOARGS)) ;
tainted = 0 ;
SPAGAIN;
if
(r -> Component.Config.bDebug & dbgMem)
lprintf (r -> pApp,
"[%d]SVs: %d\n"
, r -> pThread -> nPid, sv_count) ;
if
(num == 1)
{
*pRet = POPs ;
if
(SvTYPE (*pRet) == SVt_PVMG)
{
SV * pSV = newSVsv (*pRet) ;
*pRet = pSV ;
}
else
SvREFCNT_inc (*pRet) ;
if
(r -> Component.Config.bDebug & dbgEval)
{
if
(SvOK (*pRet))
lprintf (r -> pApp,
"[%d]EVAL> %s\n"
, r -> pThread -> nPid, SvPV (*pRet, na)) ;
else
lprintf (r -> pApp,
"[%d]EVAL> <undefined>\n"
, r -> pThread -> nPid) ;
}
#ifdef DMALLOC
AddDMallocMagic (*pRet, sArg?sArg:
"CallStoredCV"
, __FILE__, __LINE__) ;
#endif
}
else
if
(num == 0)
{
*pRet = NULL ;
if
(r -> Component.Config.bDebug & dbgEval)
lprintf (r -> pApp,
"[%d]EVAL> <NULL>\n"
, r -> pThread -> nPid) ;
}
else
{
*pRet = &sv_undef ;
if
(r -> Component.Config.bDebug & dbgEval)
lprintf (r -> pApp,
"[%d]EVAL> returns %d args instead of one\n"
, r -> pThread -> nPid, num) ;
}
PUTBACK;
FREETMPS ;
LEAVE ;
pSVErr = ERRSV ;
if
(SvTRUE (pSVErr))
{
STRLEN l ;
char
* p ;
p = SvPV (pSVErr, l) ;
if
(p && l > 14 &&
strncmp
(p,
">embperl_exit<"
, 14) == 0)
{
tDomTree * pDomTree = DomTree_self (r -> Component.xCurrDomTree) ;
tIndex n = ArrayGetSize (r -> pApp, pDomTree -> pCheckpoints) ;
if
(n > 2)
DomTree_checkpoint (r, n-1) ;
p = SvPV(ERRSV, l) ;
if
(l > 0 &&
strncmp
(p,
">embperl_exit< request "
, 23) == 0)
r -> bExit = 1 ;
if
(r -> Component.Config.bDebug & dbgEval)
lprintf (r -> pApp,
"[%d]EVAL> %s exit called (%s)\n"
, r -> pThread -> nPid, r -> bExit?
"request"
:
"component"
, p?p:
""
) ;
sv_setpv(pSVErr,
""
);
r -> Component.Config.bOptions |= optNoUncloseWarn ;
r -> Component.bExit = 1 ;
return
rcExit ;
}
if
(l >
sizeof
(r -> errdat1) - 1)
l =
sizeof
(r -> errdat1) - 1 ;
strncpy
(r -> errdat1, p, l) ;
if
(l > 0 && r -> errdat1[l-1] ==
'\n'
)
l-- ;
r -> errdat1[l] =
'\0'
;
if
(SvROK (pSVErr))
{
if
(r -> pErrSV)
SvREFCNT_dec(r -> pErrSV) ;
r -> pErrSV = newRV (SvRV(pSVErr)) ;
}
LogError (r, rcEvalErr) ;
sv_setpv(pSVErr,
""
);
return
rcEvalErr ;
}
return
ok ;
}
#if 0
#ifdef EP2
int
EvalStore (
register
req * r,
const
char
* sArg,
int
nFilepos,
SV ** pRet)
{
int
rc ;
SV ** ppSV ;
epTHX_
EPENTRY (Eval) ;
*pRet = NULL ;
ppSV = hv_fetch(r -> Buf.pFile -> pCacheHash, (
char
*)&nFilepos,
sizeof
(nFilepos), 1) ;
if
(ppSV == NULL)
{
strcpy
(r -> errdat1,
"CacheHash in EvalStore"
) ;
return
rcHashError ;
}
if
(*ppSV != NULL && SvTYPE (*ppSV) == SVt_PV)
{
strncpy
(r -> errdat1, SvPV(*ppSV, na),
sizeof
(r -> errdat1) - 1) ;
LogError (r, rcEvalErr) ;
return
rcEvalErr ;
}
lprintf (r -> pApp,
"CV ppSV=%s type=%d\n"
, *ppSV?
"ok"
:
"NULL"
, *ppSV?SvTYPE (*ppSV):0) ;
if
(*ppSV == NULL || SvTYPE (*ppSV) != SVt_PVCV)
{
if
((rc = EvalOnly (r, sArg, ppSV, G_SCALAR,
""
)) != ok)
{
*pRet = NULL ;
return
rc ;
}
*pRet = *ppSV ;
return
ok ;
}
*pRet = *ppSV ;
r -> numCacheHits++ ;
return
ok ;
}
#endif /* EP2 */
int
Eval (
register
req * r,
const
char
* sArg,
int
nFilepos,
SV ** pRet)
{
SV ** ppSV ;
epTHX_
EPENTRY (Eval) ;
*pRet = NULL ;
ppSV = hv_fetch(r -> Buf.pFile -> pCacheHash, (
char
*)&nFilepos,
sizeof
(nFilepos), 1) ;
if
(ppSV == NULL)
{
strcpy
(r -> errdat1,
"CacheHash in Eval"
) ;
return
rcHashError ;
}
if
(*ppSV != NULL && SvTYPE (*ppSV) == SVt_PV)
{
strncpy
(r -> errdat1, SvPV(*ppSV, na),
sizeof
(r -> errdat1) - 1) ;
LogError (r, rcEvalErr) ;
return
rcEvalErr ;
}
if
(*ppSV == NULL || SvTYPE (*ppSV) != SVt_PVCV)
return
EvalAndCall (r, sArg, ppSV, G_SCALAR, pRet) ;
r -> numCacheHits++ ;
return
CallCV (r, sArg, (CV *)*ppSV, G_SCALAR, pRet) ;
}
int
EvalTransFlags (
register
req * r,
char
* sArg,
int
nFilepos,
int
flags,
SV ** pRet)
{
SV ** ppSV ;
epTHX_
EPENTRY (EvalTrans) ;
*pRet = NULL ;
ppSV = hv_fetch(r -> Buf.pFile -> pCacheHash, (
char
*)&nFilepos,
sizeof
(nFilepos), 1) ;
if
(ppSV == NULL)
{
strcpy
(r -> errdat1,
"CacheHash in EvalTransFlags"
) ;
return
rcHashError ;
}
if
(*ppSV != NULL && SvTYPE (*ppSV) == SVt_PV)
{
strncpy
(r -> errdat1, SvPV(*ppSV, na),
sizeof
(r -> errdat1) - 1) ;
LogError (r, rcEvalErr) ;
return
rcEvalErr ;
}
if
(*ppSV == NULL || SvTYPE (*ppSV) != SVt_PVCV)
{
TransHtml (r, sArg, 0) ;
return
EvalAndCall (r, sArg, ppSV, flags, pRet) ;
}
r -> numCacheHits++ ;
return
CallCV (r, sArg, (CV *)*ppSV, flags, pRet) ;
}
int
EvalTrans (
register
req * r,
char
* sArg,
int
nFilepos,
SV ** pRet)
{
return
EvalTransFlags (r, sArg, nFilepos, G_SCALAR, pRet) ;
}
int
EvalTransOnFirstCall (
register
req * r,
char
* sArg,
int
nFilepos,
SV ** pRet)
{
SV ** ppSV ;
epTHX_
EPENTRY (EvalTrans) ;
*pRet = NULL ;
ppSV = hv_fetch(r -> Buf.pFile -> pCacheHash, (
char
*)&nFilepos,
sizeof
(nFilepos), 1) ;
if
(ppSV == NULL)
{
strcpy
(r -> errdat1,
"CacheHash in EvalTransOnFirstCall"
) ;
return
rcHashError ;
}
if
(*ppSV != NULL && SvTYPE (*ppSV) == SVt_PV)
{
strncpy
(r -> errdat1, SvPV(*ppSV, na),
sizeof
(r -> errdat1) - 1) ;
LogError (r, rcEvalErr) ;
return
rcEvalErr ;
}
if
(*ppSV == NULL || SvTYPE (*ppSV) != SVt_PVCV)
{
int
rc ;
HV * pImportStash = r -> Component.pImportStash ;
r -> Component.pImportStash = NULL ;
TransHtml (r, sArg, 0) ;
rc = EvalAndCall (r, sArg, ppSV, G_SCALAR, pRet) ;
r -> Component.pImportStash = pImportStash ;
return
rc ;
}
r -> numCacheHits++ ;
return
ok ;
}
int
EvalSub (
register
req * r,
const
char
* sArg,
int
nFilepos,
const
char
* sName)
{
int
rc ;
SV ** ppSV ;
epTHX_
EPENTRY (EvalSub) ;
ppSV = hv_fetch(r -> Buf.pFile -> pCacheHash, (
char
*)&nFilepos,
sizeof
(nFilepos), 1) ;
if
(ppSV == NULL)
{
strcpy
(r -> errdat1,
"CacheHash in EvalSub"
) ;
return
rcHashError ;
}
if
(*ppSV != NULL && SvTYPE (*ppSV) == SVt_PV)
{
strncpy
(r -> errdat1, SvPV(*ppSV, na),
sizeof
(r -> errdat1) - 1) ;
LogError (r, rcEvalErr) ;
return
rcEvalErr ;
}
if
(*ppSV == NULL || SvTYPE (*ppSV) != SVt_PVCV)
{
char
endc ;
int
len =
strlen
(sName) ;
while
(len > 0 &&
isspace
(sName[len-1]))
len-- ;
endc = sName[len] ;
((
char
*)sName)[len] =
'\0'
;
if
((rc = EvalOnly (r, sArg, ppSV, 0, sName)) != ok)
{
((
char
*)sName)[len] = endc ;
return
rc ;
}
if
(r -> Component.pImportStash && *ppSV && SvTYPE (*ppSV) == SVt_PVCV)
{
hv_store (r -> Component.pExportHash, (
char
*)sName, len, newRV_inc(*ppSV), 0) ;
if
(r -> Component.Config.bDebug & dbgImport)
lprintf (r -> pApp,
"[%d]IMP: %s -> %s (%x)\n"
, r -> pThread -> nPid, sName, HvNAME (r -> Component.pImportStash), *ppSV) ;
}
((
char
*)sName)[len] = endc ;
return
ok ;
}
r -> numCacheHits++ ;
return
ok ;
}
int
EvalNum (
register
req * r,
char
* sArg,
int
nFilepos,
int
* pNum)
{
SV * pRet ;
int
n ;
epTHX_
EPENTRY (EvalNum) ;
n = Eval (r, sArg, nFilepos, &pRet) ;
if
(pRet)
{
*pNum = SvIV (pRet) ;
SvREFCNT_dec (pRet) ;
}
else
*pNum = 0 ;
return
ok ;
}
int
EvalBool (
register
req * r,
char
* sArg,
int
nFilepos,
int
* pTrue)
{
SV * pRet ;
int
rc ;
epTHX_
EPENTRY (EvalNum) ;
rc = Eval (r, sArg, nFilepos, &pRet) ;
if
(pRet)
{
*pTrue = SvTRUE (pRet) ;
SvREFCNT_dec (pRet) ;
}
else
*pTrue = 0 ;
return
rc ;
}
int
EvalMain (
register
req * r)
{
int
rc ;
long
nFilepos = -1 ;
char
* sProg =
""
;
SV ** ppSV ;
SV * pRet ;
int
flags = G_SCALAR ;
epTHX_
ppSV = hv_fetch(r -> Buf.pFile -> pCacheHash, (
char
*)&nFilepos,
sizeof
(nFilepos), 1) ;
if
(ppSV == NULL)
{
strcpy
(r -> errdat1,
"CacheHash in EvalMain"
) ;
return
rcHashError ;
}
if
(*ppSV != NULL && SvTYPE (*ppSV) == SVt_PV)
{
strncpy
(r -> errdat1, SvPV(*ppSV, na),
sizeof
(r -> errdat1) - 1) ;
LogError (r, rcEvalErr) ;
return
rcEvalErr ;
}
if
(*ppSV == NULL || SvTYPE (*ppSV) != SVt_PVCV)
{
char
* pStart = r -> Component.pBuf ;
char
* pEnd = r -> Component.pEndPos ;
char
* pOpenBracket = r -> pConf -> pOpenBracket ;
char
* pCloseBracket = r -> pConf -> pCloseBracket ;
int
lenOpenBracket =
strlen
(pOpenBracket) ;
int
lenCloseBracket =
strlen
(pCloseBracket) ;
char
* pOpen ;
char
* pClose ;
char
buf [256] ;
int
nBlockNo = 1 ;
if
(r -> sSubName && *(r -> sSubName))
{
int
nPos = GetSubTextPos (r, r -> sSubName) ;
if
(!nPos || pStart + nPos > pEnd || nPos < 0)
{
strncpy
(r -> errdat1, r -> sSubName,
sizeof
(r -> errdat1) - 1) ;
return
rcSubNotFound ;
}
pStart += nPos ;
}
pOpen = pStart - 1 ;
do
pOpen =
strstr
(pOpen + 1, pOpenBracket) ;
while
(pOpen && pOpen > pStart && pOpen[-1] ==
'['
) ;
if
(!pOpen)
{
ProcessBlock (r, pStart - r -> Component.pBuf, r -> Component.pEndPos - r -> Component.pBuf, 1) ;
return
ok ;
}
OutputToMemBuf (r, NULL, r -> Component.pEndPos - r -> Component.pBuf) ;
while
(pStart)
{
pClose = NULL ;
if
(pOpen)
{
if
((pClose =
strstr
(pOpen + lenOpenBracket, pCloseBracket)) == NULL)
{
strncpy
(r -> errdat1, pCloseBracket,
sizeof
(r -> errdat1) - 1) ;
return
rcMissingRight ;
}
*pOpen =
'\0'
;
}
else
pOpen = pEnd ;
sprintf
(buf,
"\n$___b=$_[0] -> ProcessBlock (%d,%d,%d);\ngoto \"b$___b\";\nb%d:;\n"
, pStart - r -> Component.pBuf, pOpen - pStart, nBlockNo, nBlockNo) ;
oputs (r, buf) ;
nBlockNo++ ;
if
(pClose)
{
owrite (r, pOpen + lenOpenBracket, pClose - (pOpen + lenOpenBracket)) ;
pStart = pClose + lenCloseBracket ;
while
(
isspace
(*pStart))
pStart++ ;
pOpen = pStart - 1 ;
do
pOpen =
strstr
(pOpen + 1, pOpenBracket) ;
while
(pOpen && pOpen > pStart && pOpen[-1] ==
'['
) ;
}
else
{
pStart = NULL ;
}
}
oputs (r,
"\nb0:\n\0"
) ;
sProg = OutputToStd (r) ;
if
(sProg == NULL)
return
rcOutOfMemory ;
TransHtml (r, sProg, 0) ;
if
((rc = EvalAndCall (r, sProg, ppSV, flags, &pRet)) != ok)
return
rc ;
return
ok ;
}
r -> numCacheHits++ ;
if
((rc = CallCV (r, sProg, (CV *)*ppSV, flags, &pRet)) != ok)
return
rc ;
return
ok ;
}
#endif