(* * <COPYRIGHT> * Copyright 2002 Joachim Schrod Network and Publication Consultance GmbH, * Gerd Stolpmann * * <GPL> * This file is part of WDialog. * * WDialog is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * WDialog is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with WDialog; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * </> *) (* $Id: stubs.ml,v 3.4 2002-02-28 22:55:10 stolpmann Exp $ * ---------------------------------------------------------------------- * *) open Wd_types;; open Perlvalues;; (* NOTE: We still use the old names here. The term "uiobject" has the * same meaning as "dialog". *) (* Perl reference counters: The procedure call conventions are as follows: * * - Arguments: It is the responsibility of the callee to increase the * counter if another reference to the value is created. If you simply * read the value of the argument, it is not necessary to increase the * counter. If you put the value into a variable that survives the call, * the counter must be increased. This is also necessary if you simply return * the argument to the caller. * It is the responsibility of the caller to decrease the counter if * the reference is freed. * - Result values: It is the responsibility of the caller to decrease the * counter if the referencing variable is freed. * It is the responsibility of the callee to increase the counter if * values are extracted from variables that survive the call. * Note: the newSV* functions create new values with a counter of 1, so * if you pass them back as result you need not to first increase the * counter. *) let empty_universe() = new Wd_universe.universe (new Wd_application.application (new Pxp_dtd.dtd (new Pxp_types.drop_warnings) `Enc_iso88591 )) ;; let global_universe = ref (empty_universe()) ;; (* The universe the Perl script uses. It will be initialized later *) let global_universe_ready = ref false;; (* Will be set to [true] when [global_universe] is initialized *) let global_universe_deferred_registrations = ref [] ;; (* Deferred [register] invocations for [global_universe] *) let check_init() = (* Call this function every time you access [global_universe] *) if not !global_universe_ready then failwith "WDialog is not yet initialized" ;; let global_env = ref None ;; (* The environment of the current CGI request. This variable is initialized * by the class [special_universe] below. Okay, it's a trick. *) let get_global_env() = match !global_env with None -> assert false | Some e -> e ;; let global_cgi = ref None ;; (* The current CGI activation *) class special_universe app = object inherit Wd_universe.universe app as super method create env name = global_env := Some env; super # create env name end ;; let uiobjects_list = ref [];; let uiobjects_array = ref None;; let uiobjects_number = ref 0;; let uiobjects_offset = ref 0;; (* The dialog objects that are referenced by Perl code. As reference * an int is used. uiobjects_number contains the next free int. * uiobjects_array contains the same as uiobjects_list, or None, * if it is not yet initialized. *) let get_uiobj k = (* Get the uiobject for an ID *) begin match !uiobjects_array with None -> uiobjects_array := Some(Array.of_list(List.rev !uiobjects_list)) | Some a -> () end; begin match !uiobjects_array with None -> assert false | Some a -> let n = k - !uiobjects_offset in if n >= 0 && n < Array.length a then fst(a.(n)) else assert false end ;; let get_perlobj obj = (* Get the Perl object of an uiobject, or raise Not_found *) List.assoc obj !uiobjects_list ;; class perl_uiobject init_prepare_closure_sv init_handle_closure_sv init_self_sv universe name env = object (self) inherit Wd_dialog.dialog universe name env val prepare_closure_sv = (init_prepare_closure_sv : scalar_value) val handle_closure_sv = (init_handle_closure_sv : scalar_value) val self_sv = (init_self_sv : scalar_value) method prepare_page() = pl_callback_1arg_noresult prepare_closure_sv self_sv; method handle() = let sv = pl_callback_1arg_scalar handle_closure_sv self_sv in (* The return value is either 'undef' or the ID of the next object *) if x_sviok sv then begin let k = x_sviv sv in let obj' = get_uiobj k in svREFCNT_dec sv; raise (Change_dialog obj') end (* WDialog never calls the [copy] method, so nobody calls it, so it is * not necessary to redefine it here. (We would have to copy the Perl * object, too.) *) method copy = assert false end ;; let make_string_sv s = newSVpvn s (String.length s) ;; let dest_string_sv sv = fst(x_svpv sv) ;; let array_of_av av = let l = av_len av + 1 in let init_sv = newSViv 0 in let a = Array.create l init_sv in for k = 0 to l-1 do a.(k) <- match av_fetch av k 0 with None -> assert false | Some x -> x done; svREFCNT_dec init_sv; a ;; let obj_id x = string_of_int (Obj.obj ( Obj.field (Obj.repr x) 1 ) : int) ;; let finalize_sv sv = (* DEBUG *) (* ( match svREFCNT sv with 0 -> prerr_endline ("Finalize: refcnt already 0 ???"); | 1 -> prerr_endline ("Finalize: expected"); | n -> prerr_endline ("Finalize: refcnt = " ^ string_of_int n) ); *) svREFCNT_dec sv ;; let perl_universe_register name_sv prepare_closure_sv handle_closure_sv create_closure_sv = (* Increment the ref counters because we store these values permanently in OCaml objects. * The finalisers will decrement the counters automatically if the values are no longer * reachable from OCaml. *) ignore(svREFCNT_inc(prepare_closure_sv)); ignore(svREFCNT_inc(handle_closure_sv)); ignore(svREFCNT_inc(create_closure_sv)); Gc.finalise finalize_sv prepare_closure_sv; Gc.finalise finalize_sv handle_closure_sv; Gc.finalise finalize_sv create_closure_sv; let name, _ = x_svpv name_sv in let obj_creator universe name env = let id = !uiobjects_number in incr uiobjects_number; let id_sv = newSViv id in let self_sv = pl_callback_1arg_scalar create_closure_sv id_sv in svREFCNT_dec id_sv; Gc.finalise finalize_sv self_sv; let obj = new perl_uiobject prepare_closure_sv handle_closure_sv self_sv universe name env in uiobjects_list := (obj,self_sv) :: !uiobjects_list; uiobjects_array := None; obj in (* If [global_universe] is not yet initialized, simply put the arguments of [register] * into [global_universe_deferred_registrations] - these [register] calls will be done * later. This makes it possible that Perl code can register dialogs before the rest * of the module is initialized. *) if !global_universe_ready then !global_universe # register name obj_creator else global_universe_deferred_registrations := (name, obj_creator) :: !global_universe_deferred_registrations; newSViv 1 ;; let perl_universe_create name_sv = check_init(); let name, _ = x_svpv name_sv in let obj = !global_universe # create (get_global_env()) name in let sv = try get_perlobj obj with Not_found -> failwith("WDialog(perl_universe_create): Cannot return the perl object of a non-Perl dialog object") in (* Because this sv is just another pointer, increment the counter *) ignore(svREFCNT_inc(sv)); sv ;; let perl_uiobject_name descr_sv = let obj = get_uiobj (x_sviv descr_sv) in make_string_sv(obj # name) ;; let perl_uiobject_page_name descr_sv = let obj = get_uiobj (x_sviv descr_sv) in make_string_sv(obj # page_name) ;; let perl_uiobject_next_page descr_sv = let obj = get_uiobj (x_sviv descr_sv) in make_string_sv(obj # next_page) ;; let perl_uiobject_set_next_page descr_sv pg_sv = let obj = get_uiobj (x_sviv descr_sv) in let pg, _ = x_svpv pg_sv in obj # set_next_page pg; newSViv 1 ;; let av_make_dec elements = (* Because av_make copies the passed array of elements * the counter of the elements should be decremented *) let av = av_make (Array.length elements) elements in Array.iter (fun el -> ignore(svREFCNT_dec el)) elements; av ;; let perl_uiobject_page_names descr_sv = let obj = get_uiobj (x_sviv descr_sv) in let l = obj # page_names in let a = Array.of_list l in let av = av_make_dec (Array.map make_string_sv a) in newRV_noinc_from_av av ;; let perl_uiobject_variable descr_sv name_sv = let rec make_UI_Variable v = match v with String_value s -> let a = [| make_string_sv "UI::Variable::String"; make_string_sv s |] in newRV_noinc_from_av (av_make_dec a) | Enum_value l -> let a = Array.of_list ((make_string_sv "UI::Variable::Enum") :: (List.map make_string_sv l)) in newRV_noinc_from_av (av_make_dec a) | Dyn_enum_value l -> let l' = List.map (fun (intern,extern) -> let intern' = make_string_sv intern in let extern' = make_string_sv extern in newRV_noinc_from_av (av_make_dec [| intern'; extern' |])) l in let a = Array.of_list ((make_string_sv "UI::Variable::DynEnum") :: l') in newRV_noinc_from_av (av_make_dec a) | Dialog_value None -> let a = [| make_string_sv "UI::Variable::Dialog"; x_sv_undef(); |] in newRV_noinc_from_av (av_make_dec a) | Dialog_value (Some obj) -> let obj_sv = try get_perlobj obj with Not_found -> failwith("WDialog(perl_uiobject_variablt): Cannot return the perl object of a non-Perl dialog object") in ignore(svREFCNT_inc(obj_sv)); let a = [| make_string_sv "UI::Variable::Dialog"; obj_sv |] in newRV_noinc_from_av (av_make_dec a) | Alist_value l -> let l' = List.map (fun (key,value) -> let key' = make_string_sv key in let value' = make_UI_Variable value in newRV_noinc_from_av (av_make_dec [| key'; value' |])) l in let a = Array.of_list ((make_string_sv "UI::Variable::Alist") :: l') in newRV_noinc_from_av (av_make_dec a) | _ -> failwith "perl_uiobject_variable" in let obj = get_uiobj (x_sviv descr_sv) in let name, _ = x_svpv name_sv in make_UI_Variable (obj # variable name) ;; let perl_uiobject_string_variable descr_sv name_sv = let obj = get_uiobj (x_sviv descr_sv) in let name, _ = x_svpv name_sv in make_string_sv(obj # string_variable name) ;; (* Get variables of other types: * There is no real advantage for special stubs; use the general-purpose * perl_uiobject_variable instead. *) let perl_uiobject_set_variable descr_sv name_sv repr_sv = let rec mkvalue r_sv = let get av n = let l = av_len av in if n < 0 or n > l then failwith "perl_uiobject_set_variable" else match av_fetch av n 0 with None -> failwith "perl_uiobject_set_variable" | Some x -> x in let av = x_AvRV r_sv in let sv = get av 0 in let kind = x_sviv sv in if kind < 0 or kind > 4 then failwith "perl_uiobject_set_variable"; match kind with 0 -> (* String *) let rv = get av 1 in String_value (dest_string_sv (x_SvRV rv)) | 1 -> (* Enum *) let av1 = x_AvRV(get av 1) in let a = array_of_av av1 in Enum_value (List.map dest_string_sv (Array.to_list a)) | 2 -> (* DynEnum *) let av1 = x_AvRV(get av 1) in let a = array_of_av av1 in Dyn_enum_value (List.map (fun pair_rv -> let pair_av = x_AvRV pair_rv in dest_string_sv (get pair_av 0), dest_string_sv (get pair_av 1)) (Array.to_list a)) | 3 -> (* Dialog *) let sv = get av 1 in if x_sviok sv then begin let id = x_sviv sv in Dialog_value (Some (get_uiobj id)) end else Dialog_value None | 4 -> (* Alist *) let av1 = x_AvRV(get av 1) in let a = array_of_av av1 in Alist_value (List.map (fun pair_rv -> let pair_av = x_AvRV pair_rv in dest_string_sv (get pair_av 0), mkvalue (get pair_av 1)) (Array.to_list a)) | _ -> assert false in let obj = get_uiobj (x_sviv descr_sv) in let name, _ = x_svpv name_sv in let v = try mkvalue repr_sv with Not_found -> failwith "perl_uiobject_set_variable" in obj # set_variable name v; newSViv 1 ;; let perl_uiobject_unset_variable descr_sv name_sv = let obj = get_uiobj (x_sviv descr_sv) in let name, _ = x_svpv name_sv in obj # unset_variable name; newSViv 1 ;; let perl_uiobject_set_string_variable descr_sv name_sv value_sv = let obj = get_uiobj (x_sviv descr_sv) in let name, _ = x_svpv name_sv in let value, _ = x_svpv value_sv in obj # set_variable name (String_value value); newSViv 1 ;; let perl_uiobject_event descr_sv = let obj = get_uiobj (x_sviv descr_sv) in let e = obj # event in let a = match e with Button s -> [| "BUTTON"; s |] | Indexed_button(s,idx) -> [| "INDEXED_BUTTON"; s; idx |] | Image_button(s,x,y) -> [| "IMAGE_BUTTON"; s; string_of_int x; string_of_int y |] | Indexed_image_button(s,idx,x,y) -> [| "INDEXED_IMAGE_BUTTON"; s; idx; string_of_int x; string_of_int y |] | No_event -> [| "NO_EVENT" |] | Popup_request s -> [| "POPUP_REQUEST"; s |] in let av = av_make_dec (Array.map make_string_sv a) in newRV_noinc_from_av av ;; let perl_uiobject_set_event descr_sv e_sv = let obj = get_uiobj (x_sviv descr_sv) in let av = x_AvRV e_sv in let a = Array.map dest_string_sv (array_of_av av) in begin match a with [| "BUTTON"; s |] -> obj # set_event (Button s) | [| "INDEXED_BUTTON"; s; idx |] -> obj # set_event (Indexed_button(s,idx)); | [| "IMAGE_BUTTON"; s; x; y |] -> obj # set_event (Image_button(s,int_of_string x,int_of_string y)); | [| "INDEXED_IMAGE_BUTTON"; s; idx; x; y |] -> obj # set_event (Indexed_image_button (s,idx,int_of_string x,int_of_string y)); | [| "NO_EVENT" |] -> obj # set_event No_event; | [| "POPUP_REQUEST"; s |] -> obj # set_event (Popup_request s); | _ -> failwith "perl_uiobject_set_event" end; newSViv 1 ;; let perl_uiobject_init descr_sv page_sv = let obj = get_uiobj (x_sviv descr_sv) in let page, _ = x_svpv page_sv in obj # init page; newSViv 1 ;; let perl_uiobject_upload_filename descr_sv name_sv = let obj = get_uiobj (x_sviv descr_sv) in let name = dest_string_sv name_sv in try let argopt = obj # lookup_uploaded_file name in (* or raise Not_found *) match argopt with None -> make_string_sv "" | Some arg -> begin match arg # filename with None -> make_string_sv "" | Some x -> make_string_sv x end with Not_found -> make_string_sv "" ;; let perl_uiobject_upload_mimetype descr_sv name_sv = let obj = get_uiobj (x_sviv descr_sv) in let name = dest_string_sv name_sv in try let argopt = obj # lookup_uploaded_file name in (* or raise Not_found *) match argopt with None -> make_string_sv "" | Some arg -> make_string_sv (arg # content_type) with Not_found -> make_string_sv "" ;; let perl_uiobject_upload_sysname descr_sv name_sv = let obj = get_uiobj (x_sviv descr_sv) in let name = dest_string_sv name_sv in try let argopt = obj # lookup_uploaded_file name in (* or raise Not_found *) match argopt with None -> make_string_sv "" | Some arg -> begin match arg # store with `Memory -> make_string_sv "" | `File x -> make_string_sv x end with Not_found -> make_string_sv "" ;; (* ---------------------------------------------------------------------- *) type tt = Tree of Wd_template.tree | Tmpl of Wd_template.template ;; let tt_list = ref [];; let tt_array = ref None;; let tt_number = ref 0;; let tt_offset = ref 0 let perl_template_get name_sv = check_init(); let name = dest_string_sv name_sv in let tmpl = Wd_template.get (!global_universe#application) name in tt_list := (Tmpl tmpl) :: !tt_list; tt_array := None; let k = !tt_number in incr tt_number; newSViv k ;; let new_tree tr = tt_list := (Tree tr) :: !tt_list; tt_array := None; let k = !tt_number in incr tt_number; k ;; let get_tt k = begin match !tt_array with None -> tt_array := Some(Array.of_list(List.rev !tt_list)) | Some a -> () end; begin match !tt_array with None -> assert false | Some a -> let n = k - !tt_offset in if n >= 0 && n < Array.length a then a.(n) else assert false end ;; (* CHANGE: new descr_sv *) let perl_template_apply descr_sv tt_id_sv params_rv = let obj = get_uiobj (x_sviv descr_sv) in let tt = get_tt (x_sviv tt_id_sv) in match tt with Tmpl tmpl -> if x_svrok params_rv = 0 then failwith "perl_template_apply"; let hv = x_HvRV params_rv in let params = ref [] in ignore(hv_iterinit hv); begin try while true do let he = hv_iternext hv in (* or raise Not_found *) let key,_ = hv_iterkey he in let rv = hv_iterval hv he in if x_svrok rv = 0 then failwith "perl_template_apply"; let id = x_sviv (x_SvRV rv) in let tt_el = get_tt id in match tt_el with Tmpl _ -> failwith "perl_template_apply"; | Tree tr -> params := (key, tr) :: !params done with Not_found -> () end; let result = Wd_template.apply obj tmpl !params in let k = new_tree result in newSViv k | Tree _ -> failwith "perl_template_apply" ;; let perl_template_concat sep_sv args_rv = check_init(); let sep_tt = get_tt (x_sviv sep_sv) in if x_svrok args_rv = 0 then failwith "perl_template_concat"; let args_a = array_of_av (x_AvRV args_rv) in let args = List.map (fun rv -> if x_svrok rv = 0 then failwith "perl_template_apply"; let id = x_sviv (x_SvRV rv) in let tt = get_tt id in match tt with Tmpl _ -> failwith "perl_template_concat" | Tree tr -> tr ) (Array.to_list args_a) in match sep_tt with Tmpl _ -> failwith "perl_template_concat" | Tree tr -> let result = Wd_template.concat (!global_universe#application) tr args in let k = new_tree result in newSViv k ;; let perl_template_empty dummy = check_init(); let result = Wd_template.empty (!global_universe#application) in let k = new_tree result in newSViv k ;; let perl_template_text sv = check_init(); let result = Wd_template.text (!global_universe#application) (dest_string_sv sv) in let k = new_tree result in newSViv k ;; let perl_template_html sv = check_init(); let result = Wd_template.html (!global_universe#application) (dest_string_sv sv) in let k = new_tree result in newSViv k ;; let perl_template_to_string descr_sv tr_sv = let obj = get_uiobj (x_sviv descr_sv) in let tt = get_tt (x_sviv tr_sv) in match tt with Tmpl _ -> failwith "perl_template_to_string" | Tree tr -> let s = Wd_template.to_string obj tr in make_string_sv s ;; (* ---------------------------------------------------------------------- *) let perl_cgi_param sv = let name = dest_string_sv sv in try let value = match !global_cgi with None -> failwith "perl_cgi_param: CGI parameters not available" | Some cgi -> (cgi # argument name) # value in make_string_sv value with Not_found -> (* x_sv_undef() *) make_string_sv "" (* TODO: Cannot return undef *) ;; let collect_arguments = ref [];; let use_collected_arguments = ref false;; let perl_cgi_add_param name_sv value_sv = let name = dest_string_sv name_sv in let value = dest_string_sv value_sv in collect_arguments := new Netcgi.simple_argument ~ro:true name value :: !collect_arguments; newSViv 1 ;; let perl_cgi_add_upload name_sv filename_sv mimetype_sv sysname_sv = let name = dest_string_sv name_sv in let filename = dest_string_sv filename_sv in let mimetype = dest_string_sv mimetype_sv in let sysname = dest_string_sv sysname_sv in let qfn_buffer = Buffer.create 128 in let qfn_ch = new Netchannels.output_buffer qfn_buffer in Mimestring.write_value qfn_ch [ Mimestring.QString filename ]; let hdr = [ "Content-Type", mimetype; "Content-Disposition", ("form-data; filename=" ^ Buffer.contents qfn_buffer) ] in collect_arguments := new Netcgi.mime_argument ~work_around_backslash_bug:false name (new Netmime.basic_mime_header ~ro:true hdr, `Body (new Netmime.file_mime_body ~ro:true sysname)) :: !collect_arguments; newSViv 1 ;; let perl_cgi_set _ = use_collected_arguments := true; (* this will remind us to use collect_arguments *) newSViv 1 ;; (* ---------------------------------------------------------------------- *) let perl_reset dummy_sv = (* Forget the connections to Perl objects: *) uiobjects_offset := !uiobjects_number; uiobjects_list := []; uiobjects_array := None; tt_offset := !tt_number; tt_list := []; tt_array := None; collect_arguments := []; use_collected_arguments := false; global_universe_ready := false; global_universe := empty_universe(); global_universe_deferred_registrations := []; global_env := None; global_cgi := None; (* DEBUG *) (* Gc.full_major(); (* Output statistics: *) Gc.print_stat stdout; *) newSViv 1 ;; let perl_setup uifile_sv = (* Set the ui file to parse, i.e. set global_universe *) let uifile = dest_string_sv uifile_sv in let app = if Filename.check_suffix uifile ".ui" then Wd_transform.parse_uiapplication uifile else if Filename.check_suffix uifile ".ui.bin" then Wd_transform.load_uiapplication uifile else failwith "perl_setup"; in global_universe_ready := true; global_universe := new special_universe app; (* Use special_universe such that global_env will be initialized *) (* Do now the deferred registrations: *) List.iter (fun (name, create) -> !global_universe # register name create ) (List.rev !global_universe_deferred_registrations); global_universe_deferred_registrations := []; newSViv 1 ;; let processing name header = `Automatic ;; (* Use the MIME header to decide whether to use `Memory or `File, * but not the parameter name *) (* let upload = "upload_" in let l = String.length upload in if String.length name >= l && String.sub name 0 l = upload then `File else `Memory ;; *) let operating_type = Netcgi.buffered_transactional_optype;; let process_request (cgi:Netcgi_types.cgi_activation) error_closure_sv self_url_sv nocache_sv = check_init(); let no_cache = x_sviv nocache_sv <> 0 in let self_url = dest_string_sv self_url_sv in let error_page estring = let sv = pl_callback_1arg_scalar error_closure_sv (make_string_sv estring) in let out = dest_string_sv sv in svREFCNT_dec sv; out in begin try global_cgi := Some cgi; let cache = match cgi # request_method with `GET -> `No_cache | `POST -> if no_cache then `No_cache else `Unspecified | _ -> assert false in cgi # set_header (*~fields:header*) ~cache (); Wd_cycle.process_request ~self_url !global_universe cgi; with exc -> cgi # output # rollback_work(); cgi # set_header ~cache:`No_cache (); let s = error_page (Printexc.to_string exc) in cgi # output # output_string s; end; cgi # output # commit_work(); cgi # finalize() ;; let special_env() = let env = new Netcgi_env.custom_environment() in env # set_output_ch (new Netchannels.output_channel stdout); env # set_input_state `Received_body; env # setup_finished(); (env :> Netcgi_env.cgi_environment) ;; let perl_process_request error_closure_sv self_url_sv nocache_sv = let cgi = if !use_collected_arguments then let env = special_env() in new Netcgi.custom_activation ~env ~args:!collect_arguments ~meth:`POST ~operating_type () else new Netcgi.std_activation ~processing ~operating_type () in process_request cgi error_closure_sv self_url_sv nocache_sv; newSViv 1 ;; class my_output buf : Netchannels.trans_out_obj_channel = object inherit Netchannels.output_buffer buf val buf = buf method commit_work() = () method rollback_work() = Buffer.clear buf end ;; let perl_process_request_noprint error_closure_sv self_url_sv dummy_sv = let buf = Buffer.create 65536 in let operating_type = `Transactional (fun _ _ -> new my_output buf) in let cgi = if !use_collected_arguments then let env = special_env() in new Netcgi.custom_activation ~env ~args:!collect_arguments ~meth:`POST ~operating_type () else new Netcgi.std_activation ~processing ~operating_type () in cgi # environment # set_output_state `Sent_header; (* This prevents that netcgi sends the header *) process_request cgi error_closure_sv self_url_sv dummy_sv; make_string_sv (Buffer.contents buf) ;; (* ---------------------------------------------------------------------- *) let r1 name (f : scalar_value -> scalar_value) = Callback.register name f;; let r2 name (f : scalar_value -> scalar_value -> scalar_value) = Callback.register name f;; let r3 name (f : scalar_value -> scalar_value -> scalar_value -> scalar_value) = Callback.register name f;; let r4 name (f : scalar_value -> scalar_value -> scalar_value -> scalar_value -> scalar_value ) = Callback.register name f;; let r5 name (f : scalar_value -> scalar_value -> scalar_value -> scalar_value -> scalar_value -> scalar_value ) = Callback.register name f;; r1 "perl_caml_reset" perl_reset; r1 "perl_setup" perl_setup; r3 "perl_process_request" perl_process_request; (* CHANGED *) r3 "perl_process_request_noprint" perl_process_request_noprint; (* CHANGED *) r1 "perl_uiobject_name" perl_uiobject_name;; r1 "perl_uiobject_page_name" perl_uiobject_page_name;; r1 "perl_uiobject_page_names" perl_uiobject_page_names;; r1 "perl_uiobject_next_page" perl_uiobject_next_page;; r2 "perl_uiobject_set_next_page" perl_uiobject_set_next_page;; r2 "perl_uiobject_variable" perl_uiobject_variable;; r2 "perl_uiobject_string_variable" perl_uiobject_string_variable;; r3 "perl_uiobject_set_variable" perl_uiobject_set_variable;; r3 "perl_uiobject_set_string_variable" perl_uiobject_set_string_variable;; r2 "perl_uiobject_unset_variable" perl_uiobject_unset_variable;; r1 "perl_uiobject_event" perl_uiobject_event;; r2 "perl_uiobject_set_event" perl_uiobject_set_event;; r2 "perl_uiobject_init" perl_uiobject_init;; r2 "perl_uiobject_upload_filename" perl_uiobject_upload_filename;; r2 "perl_uiobject_upload_mimetype" perl_uiobject_upload_mimetype;; r2 "perl_uiobject_upload_sysname" perl_uiobject_upload_sysname;; r4 "perl_universe_register" perl_universe_register; (* CHANGED *) r1 "perl_universe_create" perl_universe_create;; (* CHANGED *) r1 "perl_template_get" perl_template_get;; r3 "perl_template_apply" perl_template_apply;; (* CHANGED *) r2 "perl_template_concat" perl_template_concat;; r1 "perl_template_empty" perl_template_empty;; r1 "perl_template_text" perl_template_text;; r1 "perl_template_html" perl_template_html;; r2 "perl_template_to_string" perl_template_to_string;; r1 "perl_cgi_param" perl_cgi_param;; r2 "perl_cgi_add_param" perl_cgi_add_param;; r4 "perl_cgi_add_upload" perl_cgi_add_upload;; r1 "perl_cgi_set" perl_cgi_set;; (* ====================================================================== * History: * * $Log: stubs.ml,v $ * Revision 3.4 2002-02-28 22:55:10 stolpmann * New: global_cgi stores the CGI activation object. * * Revision 3.3 2002/02/28 18:50:44 stolpmann * Continued with perlapi (lots of bugfixes) * * Revision 3.2 2002/02/14 16:24:13 stolpmann * Added copyright notice * * Revision 3.1 2002/02/12 23:11:25 stolpmann * Initial revision at sourceforge * * Revision 1.8 2002/01/22 17:35:32 gerd * Fixed a lot of memory leaks. * * Revision 1.7 2002/01/21 14:25:36 gerd * Changed for upcoming WDialog 2 * * Revision 1.6 2000/12/21 15:03:26 gerd * Updated to support the Popup_request parameter. * * Revision 1.5 2000/12/06 17:53:36 gerd * Updated. * * Revision 1.4 2000/12/04 18:28:31 gerd * Added the Popup_request event. * * Revision 1.3 2000/09/21 15:12:30 gerd * Updated for O'Caml 3 and PXP * * Revision 1.2 2000/04/17 10:12:55 gerd * Improved file upload. * Furthermore, the traditional CGI.pm package can be used, * if the user prefers this. * * Revision 1.1 2000/04/13 17:42:53 gerd * Initial revision. * * *)