X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=perl_c.c;h=dc5b93b27b45f349ca5fbf2ba26841830874046a;hb=60e320772abf3bdd6402ed4fb5513bbe50540d1b;hp=bf7858035e9fd02d55681ba8d478c6b287e549fd;hpb=9e543055271a1ec799d56f507ab048c78d3d7a88;p=perl4caml.git diff --git a/perl_c.c b/perl_c.c index bf78580..dc5b93b 100644 --- a/perl_c.c +++ b/perl_c.c @@ -1,6 +1,6 @@ /* Interface to Perl from OCaml. * Copyright (C) 2003 Merjis Ltd. - * $Id: perl_c.c,v 1.5 2003-10-14 16:05:21 rich Exp $ + * $Id: perl_c.c,v 1.12 2003-11-19 16:28:22 rich Exp $ */ #include @@ -20,6 +20,10 @@ */ #define off64_t __off64_t +/* XXX This is required by Perl >= 5.8.2. */ +#define __USE_GNU +#include + #include #include @@ -42,32 +46,32 @@ static value unoption (value option, value deflt); #define Sv_val(svv) (Voidptr_val (SV, (svv))) #define Val_av(av) (Val_voidptr ((av))) #define Av_val(avv) (Voidptr_val (AV, (avv))) +#define Val_hv(hv) (Val_voidptr ((hv))) +#define Hv_val(hvv) (Voidptr_val (HV, (hvv))) -static void -xs_init (pTHX) +CAMLprim value +perl4caml_init (value unit) { - char *file = __FILE__; - EXTERN_C void boot_DynaLoader (pTHX_ CV* cv); - - newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); + CAMLparam1 (unit); + PERL_SYS_INIT3 (NULL, NULL, NULL); + CAMLreturn (Val_unit); } CAMLprim value -perl4caml_init (value unit) +perl4caml_current_interpreter (value unit) { - static char *argv[] = { "", "-w", "-e", "0" }; - int argc = sizeof argv / sizeof argv[0]; - - PERL_SYS_INIT3 (NULL, NULL, NULL); + CAMLparam1 (unit); + if (my_perl == 0) raise_not_found (); + CAMLreturn (Val_perl (my_perl)); +} - /* Create a default interpreter. */ - my_perl = perl_alloc (); - perl_construct (my_perl); - PL_exit_flags |= PERL_EXIT_DESTRUCT_END; - perl_parse (my_perl, xs_init, argc, argv, NULL); - /*perl_run (my_perl);*/ +static void +xs_init (pTHX) +{ + char *file = __FILE__; + EXTERN_C void boot_DynaLoader (pTHX_ CV* cv); - return Val_unit; + newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); } CAMLprim value @@ -77,12 +81,12 @@ perl4caml_create (value optargs, value unit) CAMLlocal1 (args); int argc, i; char **argv; - static char *no_args[] = { "", "-e", "0" }; + static char *no_args[] = { "", "-w", "-e", "0" }; /* Arguments given? */ if (optargs == Val_int (0)) /* "None" */ { - argc = 3; + argc = 4; argv = no_args; } else /* "Some args" where args is a string array. */ @@ -103,17 +107,16 @@ perl4caml_create (value optargs, value unit) } CAMLprim value -perl4caml_destroy (value unit) +perl4caml_destroy (value plv) { - CAMLparam1 (unit); + CAMLparam1 (plv); + PerlInterpreter *pl = Perl_val (plv); - perl_destruct (my_perl); - perl_free (my_perl); + perl_destruct (pl); + perl_free (pl); - /* Force a segfault if someone tries to use a Perl function without - * creating another interpreter first. - */ - my_perl = 0; + /* Current interpreter? */ + if (my_perl == pl) my_perl = 0; CAMLreturn (Val_unit); } @@ -192,18 +195,10 @@ perl4caml_sv_is_true (value svv) } CAMLprim value -perl4caml_sv_is_undef (value svv) -{ - CAMLparam1 (svv); - SV *sv = Sv_val (svv); - CAMLreturn (sv == &PL_sv_undef ? Val_true : Val_false); -} - -CAMLprim value perl4caml_sv_undef (value unit) { CAMLparam1 (unit); - CAMLreturn (Val_sv (&PL_sv_undef)); + CAMLreturn (Val_sv (newSV (0))); } CAMLprim value @@ -242,6 +237,36 @@ perl4caml_sv_type (value svv) } CAMLprim value +perl4caml_scalarref (value svv) +{ + CAMLparam1 (svv); + CAMLlocal1 (rsvv); + SV *sv = Sv_val (svv); + rsvv = Val_sv (newRV_inc (sv)); + CAMLreturn (rsvv); +} + +CAMLprim value +perl4caml_arrayref (value avv) +{ + CAMLparam1 (avv); + CAMLlocal1 (rsvv); + AV *av = Av_val (avv); + rsvv = Val_sv (newRV_inc ((SV *) av)); + CAMLreturn (rsvv); +} + +CAMLprim value +perl4caml_hashref (value hvv) +{ + CAMLparam1 (hvv); + CAMLlocal1 (rsvv); + HV *hv = Hv_val (hvv); + rsvv = Val_sv (newRV_inc ((SV *) hv)); + CAMLreturn (rsvv); +} + +CAMLprim value perl4caml_deref (value svv) { CAMLparam1 (svv); @@ -284,6 +309,25 @@ perl4caml_deref_array (value svv) } CAMLprim value +perl4caml_deref_hash (value svv) +{ + CAMLparam1 (svv); + CAMLlocal1 (rhvv); + SV *sv = Sv_val (svv); + + if (SvTYPE (sv) != SVt_RV) + invalid_argument ("deref_array: SV is not a reference"); + switch (SvTYPE (SvRV (sv))) { + case SVt_PVHV: + break; + default: + invalid_argument ("deref_array: SV is not a reference to a hash"); + } + rhvv = Val_hv ((HV *) SvRV (sv)); + CAMLreturn (rhvv); +} + +CAMLprim value perl4caml_av_empty (value unit) { CAMLparam1 (unit); @@ -422,6 +466,72 @@ perl4caml_av_extend (value avv, value i) } CAMLprim value +perl4caml_hv_empty (value unit) +{ + CAMLparam1 (unit); + HV *hv = newHV (); + CAMLreturn (Val_hv (hv)); +} + +CAMLprim value +perl4caml_hv_set (value hvv, value key, value svv) +{ + CAMLparam3 (hvv, key, svv); + HV *hv = Hv_val (hvv); + SV *sv = Sv_val (svv); + SvREFCNT_inc (sv); + if (hv_store (hv, String_val (key), string_length (key), sv, 0) == 0) + SvREFCNT_dec (sv); + CAMLreturn (Val_unit); +} + +CAMLprim value +perl4caml_hv_get (value hvv, value key) +{ + CAMLparam2 (hvv, key); + HV *hv = Hv_val (hvv); + SV **svp = hv_fetch (hv, String_val (key), string_length (key), 0); + if (svp == 0) raise_not_found (); + CAMLreturn (Val_sv (*svp)); +} + +CAMLprim value +perl4caml_hv_exists (value hvv, value key) +{ + CAMLparam2 (hvv, key); + HV *hv = Hv_val (hvv); + bool r = hv_exists (hv, String_val (key), string_length (key)); + CAMLreturn (r ? Val_true : Val_false); +} + +CAMLprim value +perl4caml_hv_delete (value hvv, value key) +{ + CAMLparam2 (hvv, key); + HV *hv = Hv_val (hvv); + hv_delete (hv, String_val (key), string_length (key), G_DISCARD); + CAMLreturn (Val_unit); +} + +CAMLprim value +perl4caml_hv_clear (value hvv) +{ + CAMLparam1 (hvv); + HV *hv = Hv_val (hvv); + hv_clear (hv); + CAMLreturn (Val_unit); +} + +CAMLprim value +perl4caml_hv_undef (value hvv) +{ + CAMLparam1 (hvv); + HV *hv = Hv_val (hvv); + hv_undef (hv); + CAMLreturn (Val_unit); +} + +CAMLprim value perl4caml_get_sv (value optcreate, value name) { CAMLparam2 (optcreate, name); @@ -449,6 +559,20 @@ perl4caml_get_av (value optcreate, value name) CAMLreturn (Val_av (av)); } +CAMLprim value +perl4caml_get_hv (value optcreate, value name) +{ + CAMLparam2 (optcreate, name); + CAMLlocal1 (create); + HV *hv; + + create = unoption (optcreate, Val_false); + hv = get_hv (String_val (name), create == Val_true ? TRUE : FALSE); + if (hv == NULL) raise_not_found (); + + CAMLreturn (Val_hv (hv)); +} + static inline void check_perl_failure () { @@ -627,7 +751,7 @@ perl4caml_call_void (value optsv, value optfnname, value arglist) else if (optfnname != Val_int (0)) { fnname = unoption (optfnname, Val_false); - count = call_pv (String_val (fnname), G_EVAL|G_VOID); + count = call_pv (String_val (fnname), G_EVAL|G_VOID|G_DISCARD); } else { @@ -638,7 +762,7 @@ perl4caml_call_void (value optsv, value optfnname, value arglist) SPAGAIN; - assert (count == 0); /* Pretty sure it should never be anything else. */ + assert (count == 0); /* Restore the stack. */ PUTBACK; @@ -795,11 +919,11 @@ perl4caml_call_method_void (value ref, value name, value arglist) PUTBACK; - count = call_method (String_val (name), G_EVAL|G_VOID); + count = call_method (String_val (name), G_EVAL|G_VOID|G_DISCARD); SPAGAIN; - assert (count == 0); /* Pretty sure it should never be anything else. */ + assert (count == 0); /* Restore the stack. */ PUTBACK; @@ -937,11 +1061,11 @@ perl4caml_call_class_method_void (value classname, value name, value arglist) PUTBACK; - count = call_method (String_val (name), G_EVAL|G_VOID); + count = call_method (String_val (name), G_EVAL|G_VOID|G_DISCARD); SPAGAIN; - assert (count == 0); /* Pretty sure it should never be anything else. */ + assert (count == 0); /* Restore the stack. */ PUTBACK;