Ok, having just sent this last post i've now found an answer. Thanks for your help by the way.
If anyone wants to do something similar in the future this is what i've done: I looked at the Perl source for the implementation of Perl_eval_pv (aliased to eval_pv) and noticed that eval_sv is called without the G_KEEPERR flag. Implementing my own version of eval_pv with this flag included and some extra checks before I then call the anonymous sub works exactly the way i wanted. PS. I've just noticed in my very last source example i had the error $i+$+ instead of $i$++...oops - should have copied and pasted rather re-typed. -----Original Message----- From: rwilding [mailto:[EMAIL PROTECTED]] Sent: Monday, January 27, 2003 11:08 AM To: 'Nick Ing-Simmons' Cc: '[EMAIL PROTECTED]' Subject: RE: Embedded perl question 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/
