Hi Nick, Thanks for the reply.
My understanding of the $@/ERRSV is that it will return output generated by
"die" statements in the eval expression and not those produced when PERL
compiles the expression. I had a play with what you suggested and this is
what i've found:
A small perl script like this (notice the intentional error "$i$++" in the
for loop:
@out=eval"sub{my \$i;my
\@out;for(\$i=0;\$i<16;\$i$++){\$out[\$i]=\$i+4;}return \@out;}";
if($@)
{
print "ERROR::::::::::",$@,"\n"
}
print @out,"\n";
Produces this output:
ERROR::::::::::syntax error at (eval 1) line 1, near "+)"
Which is what i want, the following C code however does not:
SV* cvrv=eval_pv("sub{my $i;my
@out;for($i=0;$i<16;$i$++){$out[$i]=$i+4;}return $out;}",false); #<== have
also tried true here!
if(SvTRUE(ERRSV))
{
printf("%s\n",SvPV_nolen(ERRSV));
}
Perhaps a fairer comparison is to have an internal eval inside the c
eval_pv, ie:
SV* cvrv=eval_pv("$out=eval\"sub{my \\$i;my
\\@out;for(\\$i=0;\\$i<16;\\$i+$+){\\$out[\\$i]=\\$i+4;}return
\\@out;}\";return $out;",false);
This correctly generates a pointer to the anonymous sub but again if I
include a syntax error as above the error is not passed back in ERRSV.
I have noted that eval_pv unlike call_pv/call_sv does not provide any means
of how to treat the error (eg . G_KEEPERR) - perhaps this has something to
do with it?
This is beginning to drive me mad!
Any more ideas would be very much appreciated!
-----Original Message-----
From: Nick Ing-Simmons [mailto:[EMAIL PROTECTED]]
Sent: Sunday, January 26, 2003 5:36 PM
To: [EMAIL PROTECTED]
Cc: '[EMAIL PROTECTED]'
Subject: Re: Embedded perl question
Rwilding <[EMAIL PROTECTED]> writes:
>Hi,
>
>I hope this post is in the right place, I couldn't find an embedded perl
>list but my question is also related to xs. If anyone knows a more
>appropriate list could they please let me know? Thanks.
>
>I'm embedding PERL into my C++ app to act as a scripting interface for
>users. callbacks to the internal C/C++ routines are via XS. In some cases
I
>also use the PERL instance to evaluate expressions entered by the user and
>this is where i'm experiencing a problem:
>
>As per the perlcall docs I generate a pointer to an anonymous sub routine
>using
>
> 'SV *cvrv = eval_pv("......",TRUE)'
>
>Then mess with the stack before "call_sv(cvrv,G_ARRAY)" and then more
>messing with the stack to get the result.
>
>This all works fine until the user enters an invalid expression which i
then
>attempt to compile. I couldn't find any docs describing how to handle this
>but I've found (through playing with the debugger) that "cvrv->sv_any" will
>be NULL if the compilation fails.
>Firstly is this the best (only?) way to
>extract success/fail info (it's undocumented and therefore i dont want my
>code to break with an updates etc) and secondly how can i return the useful
>compilation error message from the PERL interpreter? (i.e. "Scalar found
>where.....")
It it not the best or only way.
The best way is to realise that the eval_pv is doing the save as perl's
eval ""; You can test for success by doing the C equivalent of perl's
if ($@) { print $@; }
$@ is tested commonly enough in the core for there to be a handy
C macro for it: ERRSV so you get what you want with:
if (SvTRUE(ERRSV))
{
char *error_message = SvPV_nolen(ERRSV);
}
>
>I've looked through perlguts, perlapi and perlcall - any other ideas????
>
ERRSV is meantioned in perlcall.pod and perlembed.pod as the equivalent
of testing $@ - perhaps what is not clear is that eval_pv() is like eval "".
--
Nick Ing-Simmons
http://www.ni-s.u-net.com/