1 / 81

Running Away to C

Running Away to C. XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li. You’re here because…. You know some Perl You recognise some C But fear it a little You’re an evil brigand You know it’s warmer in here. Stack. Stack. Stack. Stack. Stack. Stack. Stack.

najila
Télécharger la présentation

Running Away to C

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Running Away to C XS – More faff than fear London Perl Workshop – Dec 04Alex Goughalex@earth.li

  2. You’re here because… • You know some Perl • You recognise some C • But fear it a little • You’re an evil brigand • You know it’s warmer in here

  3. Stack

  4. Stack

  5. Stack

  6. Stack

  7. Stack

  8. Stack

  9. Stack

  10. Stack

  11. Stack

  12. Stack

  13. Stack

  14. Stack

  15. Stack

  16. Stack

  17. Stack

  18. Stack Functions dSP; Declare stack varsPUSHMARK(SP) start of argumentsEXTEND make spaceXPUSHstuff push stuff, making spacePUSHstuff push stuff, need spacePUTBACK done adding arguments . . . Make a call . . .SPAGAIN refresh our stackret = POPstuff grab stuff from stackPUTBACK we’re done grabbing stuff

  19. Scope • Start and end a scope • Tell Perl we’re creating temporary stuff • Tell Perl when we’re done with it

  20. Scope Functions ENTER Opening brace {SAVETMPS start making temps . . . Call function . . .FREETMPS done with my temps LEAVE Closing brace }

  21. Scalars $thing = 12 12.3 “harry” \ @array \ %hash \ $thing bless(\$object) *FILE qr{.*} {code}

  22. Scalar Functions I SV* get_sv(char* name, I32 create)SV* sv = get_sv(“bar”, TRUE) SV* newSVx sv = newSViv(12) newSVnv(12.3) newSVpv(“honk”, 0) -> “honk” newSVpv(“honk”, 2) -> “ho”IV intv = SvIV(sv)NV fltv = SvNV(sv)char* foo = SvPV(sv)sv_setpv(sv, “honk”); sv_setiv(sv, 12)

  23. Scalar Functions I SV* get_sv(char* name, I32 create)SV* sv = get_sv(“bar”, TRUE) SV* newSVx sv = newSViv(12) newSVnv(12.3) newSVpv(“honk”, 0) -> “honk” newSVpv(“honk”, 2) -> “ho”IV intv = SvIV(sv)NV fltv = SvNV(sv)char* foo = SvPV(sv)sv_setpv(sv, “honk”); sv_setiv(sv, 12)

  24. Scalar Functions I SV* get_sv(char* name, I32 create)SV* sv = get_sv(“bar”, TRUE) SV* newSVx sv = newSViv(12) newSVnv(12.3) newSVpv(“honk”, 0) -> “honk” newSVpv(“honk”, 2) -> “ho”IV intv = SvIV(sv)NV fltv = SvNV(sv)char* foo = SvPV(sv)sv_setpv(sv, “honk”); sv_setiv(sv, 12)

  25. Scalar Functions I SV* get_sv(char* name, I32 create)SV* sv = get_sv(“bar”, TRUE) SV* newSVx sv = newSViv(12) newSVnv(12.3) newSVpv(“honk”, 0) -> “honk” newSVpv(“honk”, 2) -> “ho”IV intv = SvIV(sv)NV fltv = SvNV(sv)char* foo = SvPV(sv)sv_setpv(sv, “honk”); sv_setiv(sv, 12)

  26. Scalar Functions II SV* refsv = newRV_inc(sv) “refsv = \ sv” SV* sv = SvRV(refsv) “sv = $ { refsv }”I32 cnt = REFCNT(sv) REFCNT_inc(sv) REFCNT_dec(sv)SV *sv = sv_2mortal(newSViv(12)) sv_free(sv) sv_{catpv catsv cmp dec eq inc isa len . . . }

  27. Scalar Functions II SV* refsv = newRV_inc(sv) “refsv = \ sv” SV* sv = SvRV(refsv) “sv = $ { refsv }”I32 cnt = REFCNT(sv) REFCNT_inc(sv) REFCNT_dec(sv)SV *sv = sv_2mortal(newSViv(12)) sv_free(sv) sv_{catpv catsv cmp dec eq inc isa len . . . }

  28. Scalar Functions II SV* refsv = newRV_inc(sv) “refsv = \ sv” SV* sv = SvRV(refsv) “sv = $ { refsv }”I32 cnt = REFCNT(sv) REFCNT_inc(sv) REFCNT_dec(sv)SV *sv = sv_2mortal(newSViv(12)) sv_free(sv) sv_{catpv catsv cmp dec eq inc isa len . . . }

  29. Scalar Functions II SV* refsv = newRV_inc(sv) “refsv = \ sv” SV* sv = SvRV(refsv) “sv = $ { refsv }”I32 cnt = REFCNT(sv) REFCNT_inc(sv) REFCNT_dec(sv)SV *sv = sv_2mortal(newSViv(12)) sv_free(sv) sv_{catpv catsv cmp dec eq inc isa len . . . }

  30. A Puzzle • Find the longest set of three words that when listed form three letter words down all columns. padsareatend

  31. Array Functions AV *av = get_av(“ARGV”, TRUE)SV** ret = av_store(av, 12, sv) SV** ret = av_fetch(av, 12, sv, lval) SV* sv = av_pop(av) av_shift(av) void av_push(av, sv) av_unshift(av, 3) [3 undefs] I32 len = av_len(av)

  32. Hash Functions HV *hv = get_hv(“hash”, TRUE) BOOL hv_exists(hv, “key”, 3) SV** sv = hv_fetch(hv, “key”, 3, lval) SV** sv = hv_store(hv, “key”, 3, sv, 0) Or you can play with HE (Hash Entries)

  33. Function Functions CV* cv = get_cv(“subname”, TRUE) call_pv(“subname”, context) call_sv(sv, context) Context: G_VOID } G_SCALAR } context G_ARRAY } G_NOARGS no arguments G_DISCARD “no return values” G_EVAL catch die in eval { } G_KEEPERR .. and be nice to $@

  34. Objects, globs, whatever • Maybe you’ll need them • Maybe you won’t • See perlapi, perlcall, perlguts

  35. Embedding • You have some C • You want to add a bit of Perl • Config file dabbling • Scripting engine • Hook into Efficient / Legacy code • Prototype features

  36. Config Parsing • Flexible configuration framework • C side factored into:void get_config(char* key, char* dst, int len); • Let Perl provide the intelligence • (We provide the glue)

  37. Perl • A big C program • A really tiny main() • Constructs an intepreter • Tells it to parse your script • Tells it to run your script • Jumps between C and Perl a lot • Cleans up (sort of) • Exits

  38. Config Parsing use strict; my %config = (); sub init { my($file) = @_; … # fill in %config } sub get_value { my($key) = @_; return $config{$key} || “”; }

  39. #include "EXTERN.h" #include "Perl.h" static PerlInterpreter *g_perl_interp; int main(int argc, char** argv, char** env) { char *config_pl[] = {“config.pl”, 0}; PERL_SYS_INIT3(&argc,&argv,&env); g_perl_interp = perl_alloc(); perl_construct(g_perl_interp); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_parse(g_perl_interp, NULL, 1, config_pl, env); perl_run(g_perl_interp); do_program_stuff(. . .); perl_destruct(g_perl_interp); perl_free(g_perl_interp); PERL_SYS_TERM() }

  40. #include "EXTERN.h" #include "Perl.h" static PerlInterpreter *g_perl_interp; int main(int argc, char** argv, char** env) { char *config_pl[] = {“config.pl”, 0}; PERL_SYS_INIT3(&argc,&argv,&env); g_perl_interp = perl_alloc(); perl_construct(g_perl_interp); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_parse(g_perl_interp, NULL, 1, config_pl, env); perl_run(g_perl_interp); do_program_stuff(. . .); perl_destruct(g_perl_interp); perl_free(g_perl_interp); PERL_SYS_TERM() }

  41. #include "EXTERN.h" #include "Perl.h" static PerlInterpreter *g_perl_interp; int main(int argc, char** argv, char** env) { char *config_pl[] = {“config.pl”, 0}; PERL_SYS_INIT3(&argc,&argv,&env); g_perl_interp = perl_alloc(); perl_construct(g_perl_interp); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_parse(g_perl_interp, NULL, 1, config_pl, env); perl_run(g_perl_interp); do_program_stuff(. . .); perl_destruct(g_perl_interp); perl_free(g_perl_interp); PERL_SYS_TERM() }

  42. #include "EXTERN.h" #include "Perl.h" static PerlInterpreter *g_perl_interp; int main(int argc, char** argv, char** env) { char *config_pl[] = {“config.pl”, 0}; PERL_SYS_INIT3(&argc,&argv,&env); g_perl_interp = perl_alloc(); perl_construct(g_perl_interp); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_parse(g_perl_interp, NULL, 1, config_pl, env); perl_run(g_perl_interp); do_program_stuff(. . .); perl_destruct(g_perl_interp); perl_free(g_perl_interp); PERL_SYS_TERM() }

  43. #include "EXTERN.h" #include "Perl.h" static PerlInterpreter *g_perl_interp; int main(int argc, char** argv, char** env) { char *config_pl[] = {“config.pl”, 0}; PERL_SYS_INIT3(&argc,&argv,&env); g_perl_interp = perl_alloc(); perl_construct(g_perl_interp); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_parse(g_perl_interp, NULL, 1, config_pl, env); perl_run(g_perl_interp); do_program_stuff(. . .); perl_destruct(g_perl_interp); perl_free(g_perl_interp); PERL_SYS_TERM() }

  44. #include "EXTERN.h" #include "Perl.h" static PerlInterpreter *g_perl_interp; int main(int argc, char** argv, char** env) { char *config_pl[] = {“config.pl”, 0}; PERL_SYS_INIT3(&argc,&argv,&env); g_perl_interp = perl_alloc(); perl_construct(g_perl_interp); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_parse(g_perl_interp, NULL, 1, config_pl, env); perl_run(g_perl_interp); do_program_stuff(. . .); perl_destruct(g_perl_interp); perl_free(g_perl_interp); PERL_SYS_TERM() }

  45. void get_config(char* key, char* dst) {dSP; SV *ret = NULL; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSVpv(key))); PUTBACK; call_pv("get_value", G_SCALAR); SPAGAIN; ret = POPs; strcpy(dst, SvPV); PUTBACK; FREETMPS; LEAVE;}

  46. void get_config(char* key, char* dst) {dSP; SV *ret = NULL;ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSVpv(key))); PUTBACK; call_pv("get_value", G_SCALAR); SPAGAIN; ret = POPs; strcpy(dst, SvPV); PUTBACK; FREETMPS; LEAVE;}

  47. void get_config(char* key, char* dst) {dSP; SV *ret = NULL; ENTER; SAVETMPS; PUSHMARK(SP);XPUSHs(sv_2mortal(newSVpv(key))); PUTBACK; call_pv("get_value", G_SCALAR); SPAGAIN; ret = POPs; strcpy(dst, SvPV); PUTBACK; FREETMPS; LEAVE;}

  48. void get_config(char* key, char* dst) {dSP; SV *ret = NULL; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSVpv(key)));PUTBACK;call_pv("get_value", G_SCALAR); SPAGAIN; ret = POPs; strcpy(dst, SvPV); PUTBACK; FREETMPS; LEAVE;}

  49. void get_config(char* key, char* dst) {dSP; SV *ret = NULL; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSVpv(key))); PUTBACK; call_pv("get_value", G_SCALAR); SPAGAIN; ret = POPs; strcpy(dst, SvPV); PUTBACK; FREETMPS; LEAVE;}

  50. void get_config(char* key, char* dst) {dSP; SV *ret = NULL; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSVpv(key))); PUTBACK; call_pv("get_value", G_SCALAR); SPAGAIN;ret = POPs; strcpy(dst, SvPV); PUTBACK; FREETMPS; LEAVE;}

More Related