perl4caml-0.9.5/0000775000076400007640000000000010762251536013013 5ustar rjonesrjonesperl4caml-0.9.5/doc/0000775000076400007640000000000010762251536013560 5ustar rjonesrjonesperl4caml-0.9.5/doc/writing-a-wrapper.html0000644000076400007640000002704310330373422020017 0ustar rjonesrjones Writing a high-level wrapper around a Perl library

Writing a high-level wrapper around a Perl library

This document discusses the theory and practice behind writing a wrapper around a typical object-oriented Perl library. We use Pl_LWP_UserAgent as an example. (This is the high-level wrapper around the LWP::UserAgent library).

Don't worry - writing wrappers is really not very hard at all. I hope that you, the reader, will write some wrappers around your favorite Perl libraries and contribute them back to perl4caml development.

First steps

I'm going to use LWP::UserAgent as my example throughout this document. Substitute that for whatever library you want to wrap up and call from OCaml. First of all make sure you have the library installed and working under Perl, and make sure you have the manual page for that library in front of you:

perldoc LWP::UserAgent

or follow this link.

Understanding what we're doing

The low-level Perl module offers two useful functions and a useful datatype which we'll be using extensively. The useful functions are:

Function name Perl equivalent Description
call_class_method $obj = LWP::UserAgent->new (args...)

Calls a static method or constructor on a class.

call_method $obj->some_method (args...)

Calls an instance method on an object.

The useful datatype is called the Perl.sv (an abstract type), which represents a scalar value in Perl (anything you would normally write in Perl with a $, including numbers, strings, references and blessed objects). To find out more about "SVs" see the perlguts(3) man page.

To see how these three things interact, let's create an LWP::UserAgent object and call a method on it:

# #load "perl4caml.cma";;
# open Perl;;
# let sv = call_class_method "LWP::UserAgent" "new" [];;
val sv : Perl.sv = <abstr>
# let agent = call_method sv "agent" [];;
val agent : Perl.sv = <abstr>
# string_of_sv agent;;
- : string = "libwww-perl/5.69"

Note how the variable sv contains the actual Perl object (an instance of LWP::UserAgent). To be quite clear, this is the equivalent of the following Perl code:

$sv = LWP::UserAgent->new ();
$agent = $sv->agent ();
print $agent;

You could actually just continue to use the low-level interface to access Perl objects directly, but there are three problems with this: firstly it's cumbersome because you have to continually convert to and from SVs; secondly it's not type safe (eg. calling string_of_sv might fail if the SV isn't actually a string); thirdly there are more pleasant ways to present this interface.

Writing a high-level wrapper around these low-level operations is what is described in the rest of this document ...

Classes and constructors

Our general plan, therefore, will be to create an OCaml class corresponding to LWP::UserAgent, which hides the implementation (the sv, the calls to call_method, and the conversion of arguments to and from SVs). We will also need to write one or more constructor function.

We will write at least one method for every method exported by the Perl interface. Sometimes we'll write two methods for each Perl method, as in the case where a Perl method is a "getter/setter":

$ua->agent([$product_id])
   Get/set the product token that is used to identify the user agent
   on the network.  The agent value is sent as the "User-Agent" header
   in the requests.

becomes two methods in the OCaml version:

class lwp_useragent sv = object (self)
  (* ... *)
  method agent : string
  method set_agent : string -> unit
end

We will also write at least one function for every constructor or static function exported from Perl.

The OCaml object itself contains the sv which corresponds to the Perl SV (ie. the actual Perl object).

Here is the shape of our class:

(** Wrapper around Perl [LWP::UserAgent] class.
  *
  * Copyright (C) 20xx your_organisation
  *
  * $ Id $
  *)

open Perl

let _ = eval "use LWP::UserAgent"

class lwp_useragent sv = object (self)

  The methods will go here ...

end

(* The "new" constructor. Note that "new" is a reserved word in OCaml. *)
let new_ ... =
  ...
  let sv = call_class_method "LWP::UserAgent" "new" [args ...] in
  new lwp_useragent sv

Any other static functions will go here ...

Notice a few things here:

  1. There is some ocamldoc describing the class.
  2. We "open Perl" to avoid having to prefix everything with Perl..
  3. We eval "use LWP::UserAgent" when the module is loaded. This is required by Perl.
  4. The sv (scalar value representing the actual object) is passed as a parameter to the class.

Writing methods

Getters and setters

Of all types of methods, getters and setters are the easiest to write. First of all, check the manual page to find out what type the slot is. You'll need to write one get method and one set method. (Rarely you'll find getters and setters which are quasi-polymorphic, for instance they can take a string or an arrayref. You'll need to think more deeply about these, because they require one set method for each type, and the get method can be complicated).

Here's our getter and setter for the agent slot, described above. The agent is a string:

  method agent =
    string_of_sv (call_method sv "agent" [])
  method set_agent v =
    call_method_void sv "agent" [sv_of_string v]

Note:

  1. The get method is just called agent (not "get_agent"). This is the standard for OCaml code.
  2. We use string_of_sv and sv_of_string to convert to and from SVs. This will ensure that the class interface will have the correct type (string), and thus be type safe as far as the calling code is concerned, and also means the caller doesn't need to worry about SVs.
  3. The set method called call_method_void which we haven't seen before. This is exactly the same as call_method except that the method is called in a "void context" - in other words, any return value is thrown away. This is slightly more efficient than ignoring the return value.

Here's another example, with a boolean slot:

  method parse_head =
    bool_of_sv (call_method sv "parse_head" [])
  method set_parse_head v =
    call_method_void sv "parse_head" [sv_of_bool v]

Ordinary methods

Other methods are perhaps simpler to wrap than getters and setters. LWP::UserAgent contains an interesting method called request (which actually runs the request).

What's particularly interesting about this method are the parameter and return value. It takes an HTTP::Request object and returns an HTTP::Response.

I have already wrapped HTTP::Request and HTTP::Response as modules Pl_HTTP_Request and Pl_HTTP_Response respectively. You should go and look at the code in those modules now.

If request requires a parameter, what should that parameter be? Naturally it should be the SV corresponding to the HTTP::Request object. To get this, I provided an #sv method on the http_request class.

And what will request return? Naturally it will return an SV which corresponds to the (newly created inside Perl) HTTP::Response object. We need to wrap this up and create a new OCaml http_response object, containing that SV.

This is what the final method looks like:

  method request (request : http_request) =
    let sv = call_method sv "request" [request#sv] in
    new http_response sv

It's actually not so complicated.

Writing constructors and static functions

Constructors are fairly simple, although the new_ function inside Pl_LWP_UserAgent is complicated by the many optional arguments which LWP::UserAgent->new can take.

Here is the guts, omitting all but one of the optional args:

let new_ ?agent (* ... *) () =
  let args = ref [] in
  let may f = function None -> () | Some v -> f v in
  may (fun v ->
	 args := sv_of_string "agent" :: sv_of_string v :: !args) agent;
(* ... *)
  let sv = call_class_method "LWP::UserAgent" "new" !args in
  new lwp_useragent sv

It works simply enough, first building up a list of svs corresponding to the arguments, then calling call_class_method to create the Perl object, then returning a constructed OCaml lwp_useragent object containing that sv.

Contributing wrappers back to perl4caml

If you write a wrapper for a Perl class, particularly one from CPAN, I urge you to contribute it back to the perl4caml development effort. Your contribution enriches the project as a whole, and makes OCaml more useful too.


Richard W.M. Jones
Last modified: Thu Oct 16 14:39:02 BST 2003 perl4caml-0.9.5/.cvsignore0000644000076400007640000000012710330373424015001 0ustar rjonesrjones*.cmi *.cmo *.cmx *.cma *.cmxa perl4caml-*.tar.gz html META configure-stamp build-stampperl4caml-0.9.5/perl.mli0000644000076400007640000002637010762251735014467 0ustar rjonesrjones(** Interface to Perl from OCaml. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: perl.mli,v 1.16 2008-03-01 13:02:21 rich Exp $ *) type sv (** Perl scalar value. *) type av (** Perl array value. *) type hv (** Perl hash value. *) exception Perl_failure of string (** [die] in Perl code is translated automatically into this exception. *) val int_of_sv : sv -> int (** Convert a Perl [SV] into an integer. Note that OCaml [int]s aren't * large enough to store the full 32 (or 64) bits from a Perl integer, * so you may get a silent overflow. *) val sv_of_int : int -> sv (** Convert an [int] into a Perl [SV]. *) val float_of_sv : sv -> float (** Convert a Perl [SV] into a float. *) val sv_of_float : float -> sv (** Convert a [float] into a Perl [SV]. *) val string_of_sv : sv -> string (** Convert a Perl [SV] into a string. *) val sv_of_string : string -> sv (** Convert a [string] into a Perl [SV]. *) val bool_of_sv : sv -> bool (** Convert an [SV] into a boolean. *) val sv_of_bool : bool -> sv (** Convert a boolean into an [SV]. *) val sv_is_true : sv -> bool (** Return [true] if the [SV] is "true" (in the Perl sense of truth). *) val sv_is_undef : sv -> bool (** Return [true] if the [SV] is undefined (is [undef]). *) val sv_undef : unit -> sv (** Returns [undef]. *) val sv_true : unit -> sv (** Returns an [SV] which is true. *) val sv_false : unit -> sv (** Returns an [SV] which is false. *) val sv_yes : unit -> sv (** Returns Perl's internal [PL_sv_yes]. (There are some unresolved issues * with using this, so use {!Perl.sv_true} instead). *) val sv_no : unit -> sv (** Returns Perl's internal [PL_sv_no]. (There are some unresolved issues * with using this, so use {!Perl.sv_false} instead). *) (* Actually there are many more types defined than this ... *) type sv_t = SVt_NULL | SVt_IV (** Integer scalar. *) | SVt_NV (** Floating point scalar. *) | SVt_PV (** String scalar. *) | SVt_RV (** Reference. *) | SVt_PVAV (** Array. *) | SVt_PVHV (** Hash. *) | SVt_PVCV (** Code. *) | SVt_PVGV (** Glob (possibly a file handle). *) | SVt_PVMG (** Blessed or magical scalar. *) val sv_type : sv -> sv_t (** Return the type of data contained in an [SV]. Somewhat equivalent to * calling Perl's [ref] function. *) val string_of_sv_t : sv_t -> string (** Return a printable string for an [sv_t] ([SV] type). *) val reftype : sv -> sv_t (** The parameter [sv] must be a reference. This convenience function * works out what it is a reference to, either a scalar, array, hash, * code or glob. If the parameter is not a reference, or is a reference * to an unknown type, then this will throw [Invalid_argument]. *) val address_of_sv : sv -> Nativeint.t (** Returns the address of the SV. Useful for debugging since * Perl also prints out addresses on internal errors. *) val address_of_av : av -> Nativeint.t (** Returns the address of the AV. Useful for debugging since * Perl also prints out addresses on internal errors. *) val address_of_hv : hv -> Nativeint.t (** Returns the address of the HV. Useful for debugging since * Perl also prints out addresses on internal errors. *) val scalarref : sv -> sv (** Given a scalar, this returns a reference to the scalar. Note that * because references are [SV]s, this returns [sv]. *) val arrayref : av -> sv (** Given an array, this returns a reference to the array. Note that * because references are [SV]s, this returns [sv]. *) val hashref : hv -> sv (** Given a hash, this returns a reference to the hash. Note that * because references are [SV]s, this returns [sv]. *) val deref : sv -> sv (** The input is a reference to a scalar. This returns the underlying * scalar [SV]. If the input is not a reference to a scalar, throws * [Invalid_argument]. *) val deref_array : sv -> av (** The input is a reference to an array. This returns the underlying * array [AV]. If the input is not a reference to an array, throws * [Invalid_argument]. *) val deref_hash : sv -> hv (** The input is a reference to a hash. This returns the underlying * hash [HV]. If the input is not a reference to a hash, throws * [Invalid_argument]. *) val av_empty : unit -> av (** Create an empty [AV] (array). *) val av_of_sv_list : sv list -> av (** Create an array from a list of [SVs]. *) val av_push : av -> sv -> unit (** Append the [SV] to the end of the array. Same as Perl * [push \@av, $sv]. *) val av_pop : av -> sv (** Remove the [SV] at the end of the array and return it. Same as * Perl [$sv = pop \@av]. *) val av_shift : av -> sv (** Remove the [SV] at the beginning of the array and return it. Same as * Perl [$sv = shift \@av]. *) val av_unshift : av -> sv -> unit (** Prepend the [SV] to the start of the array. Same as Perl * [unshift \@av, $sv]. *) val av_length : av -> int (** Return the length of the [AV]. *) val av_set : av -> int -> sv -> unit (** Replace the i'th element of the [AV] with [SV]. *) val av_get : av -> int -> sv (** Get the i'th element of the [AV]. *) val av_clear : av -> unit (** Remove all elements from the [AV]. Same as Perl [\@av = ()]. *) val av_undef : av -> unit (** Delete the [AV] (and all elements in it). Same as Perl [undef \@av]. *) val av_extend : av -> int -> unit (** Extend the [AV] so it contains at least [n+1] elements. Note that * this apparently just changes the amount of allocated storage. The * extra elements are not visible until you store something in them. *) val av_map : (sv -> 'a) -> av -> 'a list (** Map a function over the elements in the [AV], return a list of the * results. *) val list_of_av : av -> sv list (** Convert an [AV] into a simple list of [SV]s. *) val av_of_string_list : string list -> av (** Build an [AV] from a list of strings. *) val hv_empty : unit -> hv (** Create an empty [HV] (hash). *) val hv_set : hv -> string -> sv -> unit (** Store the given [SV] in the named key in the hash. *) val hv_get : hv -> string -> sv (** Return the [SV] at the key in the hash. Throws [Not_found] if no key. *) val hv_exists : hv -> string -> bool (** Return true if the hash contains the given key. Same as Perl [exists]. *) val hv_delete : hv -> string -> unit (** Delete the given key from the hash. Same as Perl [delete]. *) val hv_clear : hv -> unit (** Remove all elements from the [HV]. Same as Perl [%av = ()]. *) val hv_undef : hv -> unit (** Delete the [HV] (and all elements in it). Same as Perl [undef %hv]. *) val hv_of_assoc : (string * sv) list -> hv (** Create an [HV] directly from an assoc list. Perl hashes cannot * support multiple values attached to the same key, so if you try * to provide an assoc list with multiple identical keys, the results * will be undefined. *) val assoc_of_hv : hv -> (string * sv) list (** Take an [HV] and return an assoc list. *) val hv_keys : hv -> string list (** Return all the keys of an [HV]. *) val hv_values : hv -> sv list (** Return all the values of an [HV]. *) (* The following are the low-level iteration interface to hashes, * which you probably shouldn't use directly. Use {!hv_keys}, * {!assoc_of_hv}, etc. instead. See [perlguts(3)] if you really * want to use this interface. *) type he val hv_iterinit : hv -> Int32.t val hv_iternext : hv -> he val hv_iterkey : he -> string val hv_iterval : hv -> he -> sv val hv_iternextsv : hv -> string * sv val get_sv : ?create:bool -> string -> sv (** Return a scalar value by name. For example, if you have a symbol * called [$a] in Perl, then [get_sv "a"] will return its value. * * If the symbol does not exist, this throws [Not_found]. * * If the optional [?create] argument is set to true and the symbol does * not exist, then Perl will create the symbol (with value [undef]) and * this function will return the [SV] for [undef]. *) val get_av : ?create:bool -> string -> av (** Same as {!Perl.get_sv} except will return and/or create [\@a]. *) val get_hv : ?create:bool -> string -> hv (** Same as {!Perl.get_sv} except will return and/or create [%a]. *) val call : ?sv:sv -> ?fn:string -> sv list -> sv (** Call a Perl function in a scalar context, either by name (using the [?fn] * parameter) or by calling a string/CODEREF (using the [?sv] parameter). * * Returns the Perl [SV] containing the result value. (See * {!Perl.int_of_sv} etc.). * * If the Perl code calls [die] then this will throw [Perl_failure]. *) val call_array : ?sv:sv -> ?fn:string -> sv list -> sv list (** Call a Perl function in an array context, either by name (using the [?fn] * parameter) or by calling a string/CODEREF (using the [?sv] parameter). * * Returns the list of results. * * If the Perl code calls [die] then this will throw [Perl_failure]. *) val call_void : ?sv:sv -> ?fn:string -> sv list -> unit (** Call a Perl function in a void context, either by name (using the [?fn] * parameter) or by calling a string/CODEREF (using the [?sv] parameter). * * Any results are discarded. * * If the Perl code calls [die] then this will throw [Perl_failure]. *) val eval : string -> sv (** This is exactly like the Perl [eval] command. It evaluates a piece of * Perl code (in scalar context) and returns the result (a Perl [SV]). *) val call_method : sv -> string -> sv list -> sv (** [call_method obj name [parameters]] calls the method [name] on the Perl * object [obj] with the given parameters, in a scalar context. Thus this * is equivalent to [$obj->name (parameters)]. * * Returns the Perl [SV] containing the result value. * * If the method calls [die] then this will throw [Perl_failure]. *) val call_method_array : sv -> string -> sv list -> sv list (** Like [call_method], but the method is called in an array context. *) val call_method_void : sv -> string -> sv list -> unit (** Like [call_method], but the method is called in a void context (results * are discarded). *) val call_class_method : string -> string -> sv list -> sv (** [call_class_method classname name [parameters]] calls the static method * [name] in the Perl class [classname] with the given parameters, in a * scalar context. Thus this is equivalent to [$classname->name (parameters)]. * * Returns the Perl [SV] containing the result value. * * If the static method calls [die] then this will throw [Perl_failure]. *) val call_class_method_array : string -> string -> sv list -> sv list (** Like [call_class_method], but the method is called in an array context. *) val call_class_method_void : string -> string -> sv list -> unit (** Like [call_class_method], but the method is called in a void context. *) perl4caml-0.9.5/META.in0000644000076400007640000000021210330373424014052 0ustar rjonesrjonesname="@PACKAGE@" version="@VERSION@" description="Perl bindings for OCaml" archive(byte)="perl4caml.cma" archive(native)="perl4caml.cmxa" perl4caml-0.9.5/COPYING.LIB0000644000076400007640000006344510330373424014455 0ustar rjonesrjonesThis library is distributed under the terms of the GNU LGPL with the OCaml linking exception. ---------------------------------------------------------------------- As a special exception to the GNU Library General Public License, you may link, statically or dynamically, a "work that uses the Library" with a publicly distributed version of the Library to produce an executable file containing portions of the Library, and distribute that executable file under terms of your choice, without any of the additional requirements listed in clause 6 of the GNU Library General Public License. By "a publicly distributed version of the Library", we mean either the unmodified Library as distributed by INRIA, or a modified version of the Library that is distributed under the conditions defined in clause 3 of the GNU Library General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU Library General Public License. ---------------------------------------------------------------------- GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307, USA. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! perl4caml-0.9.5/MANIFEST0000644000076400007640000000216710330373424014140 0ustar rjonesrjones.cvsignore .depend AUTHORS COPYING.LIB Makefile Makefile.config MANIFEST META.in README doc/writing-a-wrapper.html examples/.cvsignore examples/google.ml examples/loadpage.ml examples/parsedate.ml examples/TestClass.pm examples/test.ml examples/test.pl perl.ml perl.mli perl_c.c test/.cvsignore test/001-start.ml test/010-load.ml test/020-eval.ml test/030-call-method.ml test/030-call.ml test/100-sv.ml test/110-av.ml test/120-hv.ml test/130-hv-iter.ml test/140-ref.ml wrappers/.cvsignore wrappers/pl_Data_Dumper.ml wrappers/pl_Date_Calc.ml wrappers/pl_Date_Format.ml wrappers/pl_Date_Parse.ml wrappers/pl_HTML_Element.ml wrappers/pl_HTML_Form.ml wrappers/pl_HTML_Parser.ml wrappers/pl_HTML_TreeBuilder.ml wrappers/pl_HTTP_Cookies.ml wrappers/pl_HTTP_Headers.ml wrappers/pl_HTTP_Message.ml wrappers/pl_HTTP_Request.ml wrappers/pl_HTTP_Request_Common.ml wrappers/pl_HTTP_Response.ml wrappers/pl_LWP_UserAgent.ml wrappers/pl_Net_Google.ml wrappers/pl_Net_Google_Cache.ml wrappers/pl_Net_Google_Response.ml wrappers/pl_Net_Google_Search.ml wrappers/pl_Net_Google_Spelling.ml wrappers/pl_Template.ml wrappers/pl_URI.ml wrappers/pl_WWW_Mechanize.mlperl4caml-0.9.5/test/0000775000076400007640000000000010762251536013772 5ustar rjonesrjonesperl4caml-0.9.5/test/.cvsignore0000644000076400007640000000003510330373423015755 0ustar rjonesrjones*.bc *.opt *.cmi *.cmo *.cmx perl4caml-0.9.5/test/130-hv-iter.ml0000644000076400007640000000177010330373423016175 0ustar rjonesrjones(* Thoroughly test HV iteration functions. * $Id: 130-hv-iter.ml,v 1.1 2005/01/29 12:22:50 rich Exp $ *) open Perl let () = let xs = [ "foo", sv_of_int 1; "bar", sv_of_int 2; "baz", sv_of_int 3; "a", sv_of_int 4 ] in let hv = hv_of_assoc xs in assert (1 = int_of_sv (hv_get hv "foo")); assert (2 = int_of_sv (hv_get hv "bar")); assert (3 = int_of_sv (hv_get hv "baz")); assert (4 = int_of_sv (hv_get hv "a")); assert (not (hv_exists hv "b")); assert (not (hv_exists hv "c")); let keys = List.sort compare (hv_keys hv) in assert (4 = List.length keys); assert (["a"; "bar"; "baz"; "foo"] = keys); let values = List.sort compare (List.map int_of_sv (hv_values hv)) in assert (4 = List.length values); assert ([1; 2; 3; 4] = values); let xs = assoc_of_hv hv in let xs = List.map (fun (k, sv) -> k, int_of_sv sv) xs in let xs = List.sort compare xs in assert (4 = List.length xs); assert ([ "a", 4; "bar", 2; "baz", 3; "foo", 1 ] = xs) ;; Gc.full_major () perl4caml-0.9.5/test/030-call.ml0000644000076400007640000000036510330373423015530 0ustar rjonesrjones(* Basic subroutine call. * $Id: 030-call.ml,v 1.1 2005/01/28 23:09:33 rich Exp $ *) open Perl let () = ignore (eval "sub test { 42 + $_[0] }"); let sv = call ~fn:"test" [sv_of_int 10] in assert (52 = int_of_sv sv);; Gc.full_major () perl4caml-0.9.5/test/001-start.ml0000644000076400007640000000017010330373423015742 0ustar rjonesrjones(* Does nothing - just check the test harness is working. * $Id: 001-start.ml,v 1.1 2005/01/28 23:09:33 rich Exp $ *) perl4caml-0.9.5/test/010-load.ml0000644000076400007640000000043710330373423015532 0ustar rjonesrjones(* Load Perl interpreter. * $Id: 010-load.ml,v 1.1 2005/01/28 23:09:33 rich Exp $ *) open Perl (* The next line does nothing. It just forces OCaml to actually * reference and hence load the Perl module. *) let _ = Perl.int_of_sv;; (* Check for memory errors. *) Gc.full_major () perl4caml-0.9.5/test/030-call-method.ml0000644000076400007640000000052010330373423016777 0ustar rjonesrjones(* Basic constructor and method calls. * $Id: 030-call-method.ml,v 1.1 2005/01/28 23:09:33 rich Exp $ *) open Perl let () = ignore (eval "use IO::File"); let io = call_class_method "IO::File" "new_tmpfile" [] in call_method_void io "print" [ sv_of_string "hello, world" ]; call_method_void io "close" [];; Gc.full_major () perl4caml-0.9.5/test/140-ref.ml0000644000076400007640000000144010330373423015366 0ustar rjonesrjones(* Reference, dereference. * $Id: 140-ref.ml,v 1.2 2005/04/14 13:05:12 rich Exp $ *) open Perl let () = let sv = sv_of_int 42 in let sv = scalarref sv in assert (sv_type sv = SVt_RV); assert (reftype sv = SVt_IV); let sv = deref sv in assert (42 = int_of_sv sv); let av = av_of_string_list [ "foo"; "bar" ] in let sv = arrayref av in assert (sv_type sv = SVt_RV); assert (reftype sv = SVt_PVAV); let av = deref_array sv in assert (2 = av_length av); let hv = hv_empty () in hv_set hv "foo" (sv_of_int 1); hv_set hv "bar" (sv_of_int 2); let sv = hashref hv in assert (sv_type sv = SVt_RV); assert (reftype sv = SVt_PVHV); let hv = deref_hash sv in assert (1 = int_of_sv (hv_get hv "foo")); assert (2 = int_of_sv (hv_get hv "bar")); ;; Gc.full_major () perl4caml-0.9.5/test/110-av.ml0000644000076400007640000000220110330373423015211 0ustar rjonesrjones(* Thoroughly test AV-related functions. * $Id: 110-av.ml,v 1.1 2005/01/28 23:09:33 rich Exp $ *) open Perl let () = let av = av_empty () in assert ([] = list_of_av av); av_push av (sv_of_int 42); av_push av (sv_of_int 84); av_unshift av (sv_of_int 21); av_set av 0 (sv_of_int 11); assert (3 = av_length av); assert (84 = int_of_sv (av_pop av)); assert (2 = av_length av); assert (11 = int_of_sv (av_shift av)); assert (1 = av_length av); assert (42 = int_of_sv (av_pop av)); av_extend av 3; av_set av 0 (sv_of_int 11); av_set av 1 (sv_of_int 22); av_set av 2 (sv_of_int 33); av_set av 3 (sv_of_int 44); assert (4 = av_length av); assert (33 = int_of_sv (av_get av 2)); assert (22 = int_of_sv (av_get av 1)); assert (44 = int_of_sv (av_pop av)); assert (3 = av_length av); assert (33 = int_of_sv (av_pop av)); assert (11 = int_of_sv (av_shift av)); assert (22 = int_of_sv (av_pop av)); assert ([] = list_of_av av); ignore (eval "@a = ( 'foo', 'bar' )"); let av = get_av "a" in assert ("foo" = string_of_sv (av_get av 0)); assert ("bar" = string_of_sv (av_get av 1)); ;; Gc.full_major () perl4caml-0.9.5/test/100-sv.ml0000644000076400007640000000213410330373423015237 0ustar rjonesrjones(* Thoroughly test SV-related functions. * $Id: 100-sv.ml,v 1.1 2005/01/28 23:09:33 rich Exp $ *) open Perl let () = assert (42 = int_of_sv (sv_of_int 42)); assert (42. = float_of_sv (sv_of_float 42.)); assert (true = bool_of_sv (sv_of_bool true)); assert (false = bool_of_sv (sv_of_bool false)); assert ("42" = string_of_sv (sv_of_string "42")); assert ("42" = string_of_sv (sv_of_int 42)); assert ("1" = string_of_sv (sv_of_bool true)); (* assert ("" = string_of_sv (sv_of_bool false)); XXX fails XXX *) assert (sv_is_true (sv_of_bool true)); assert (sv_is_true (sv_true ())); assert (not (sv_is_true (sv_false ()))); assert (sv_is_undef (sv_undef ())); let sv = sv_undef () in assert (sv_type sv = SVt_NULL); let sv = sv_of_int 42 in assert (sv_type sv = SVt_IV); (* let sv = sv_of_float 42.1 in assert (sv_type sv = SVt_NV); XXX fails XXX*) let sv = sv_of_string "42" in assert (sv_type sv = SVt_PV); let sv = eval "\\\"foo\"" in assert (sv_type sv = SVt_RV); ignore (eval "$s = 'foo'"); let sv = get_sv "s" in assert ("foo" = string_of_sv sv); ;; Gc.full_major () perl4caml-0.9.5/test/120-hv.ml0000644000076400007640000000131010330373423015221 0ustar rjonesrjones(* Thoroughly test HV-related functions. * $Id: 120-hv.ml,v 1.1 2005/01/28 23:09:33 rich Exp $ *) open Perl let () = let hv = hv_empty () in hv_set hv "foo" (sv_of_int 1); hv_set hv "bar" (sv_of_int 2); hv_set hv "foo" (sv_of_int 42); assert (42 = int_of_sv (hv_get hv "foo")); assert (2 = int_of_sv (hv_get hv "bar")); assert (hv_exists hv "foo"); assert (not (hv_exists hv "baz")); hv_clear hv; assert (not (hv_exists hv "foo")); assert (not (hv_exists hv "bar")); ignore (eval "%h = ( foo => 1, bar => 2 )"); let hv = get_hv "h" in assert (1 = int_of_sv (hv_get hv "foo")); assert (2 = int_of_sv (hv_get hv "bar")); assert (not (hv_exists hv "baz")); ;; Gc.full_major () perl4caml-0.9.5/test/020-eval.ml0000644000076400007640000000025310330373423015537 0ustar rjonesrjones(* Simple eval. * $Id: 020-eval.ml,v 1.1 2005/01/28 23:09:33 rich Exp $ *) open Perl let () = let sv = eval "2+2" in assert (4 = int_of_sv sv);; Gc.full_major () perl4caml-0.9.5/README0000644000076400007640000000276310330373424013671 0ustar rjonesrjonesperl4caml Copyright (C) 2003 Merjis Ltd. (http://www.merjis.com/) $Id: README,v 1.4 2005/01/28 23:09:31 rich Exp $ perl4caml allows you to use Perl code within Objective CAML (OCaml), thus neatly side-stepping the old problem with OCaml which was that it lacked a comprehensive set of libraries. Well now you can use any part of CPAN in your OCaml code. perl4caml is distributed under the GNU Library General Public License (see file COPYING.LIB for terms and conditions). perl4caml was mainly written by Richard W.M. Jones (rich@annexia.org). See file AUTHORS for other contributors. Installation ------------ (1) You will need the Perl development environment installed. I'm using Perl 5.8.x. It is likely that earlier versions may have small incompatibilities. (2) Edit Makefile.config as necessary. (3) Type 'make'. (4) It's recommended that you run the automatic tests by using 'make test'. You should see 'All tests succeeded.' If not, please report this to me (rich@annexia.org). If Perl gives any warnings, such as 'Attempt to free unreferenced scalar', please also report this. (5) Type 'make install' as root to install. (6) Try some of the examples in the examples/ directory (some of these require that you have certain Perl modules installed). Documentation ------------- See doc/ for some documentation. To build ocamldoc (automatically generated documentation for interfaces) type 'make html'. The output can be found by pointing your browser at 'html/index.html'. perl4caml-0.9.5/wrappers/0000775000076400007640000000000010762251536014656 5ustar rjonesrjonesperl4caml-0.9.5/wrappers/pl_LWP_UserAgent.ml0000644000076400007640000001027510762251735020326 0ustar rjonesrjones(** Wrapper around Perl [LWP::UserAgent] class. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_LWP_UserAgent.ml,v 1.6 2008-03-01 13:02:21 rich Exp $ *) open Perl open Pl_HTTP_Request open Pl_HTTP_Response open Pl_HTTP_Cookies let _ = eval "use LWP::UserAgent" class lwp_useragent sv = object (self) method simple_request (request : http_request) = let sv = call_method sv "simple_request" [request#sv] in new http_response sv method request (request : http_request) = let sv = call_method sv "request" [request#sv] in new http_response sv method agent = string_of_sv (call_method sv "agent" []) method set_agent v = call_method_void sv "agent" [sv_of_string v] method from = string_of_sv (call_method sv "from" []) method set_from v = call_method_void sv "from" [sv_of_string v] method cookie_jar = let sv = call_method sv "cookie_jar" [] in new http_cookies sv method set_cookie_jar (v : http_cookies) = call_method_void sv "cookie_jar" [v#sv] method set_cookie_jar_file filename = let hv = hv_empty () in hv_set hv "file" (sv_of_string filename); call_method_void sv "cookie_jar" [hashref hv] method requests_redirectable = let sv = call_method sv "requests_redirectable" [] in let av = deref_array sv in List.map string_of_sv (list_of_av av) method set_requests_redirectable methods = let av = av_empty () in List.iter (av_push av) (List.map sv_of_string methods); call_method_void sv "requests_redirectable" [arrayref av] method add_requests_redirectable method_ = let sv = call_method sv "requests_redirectable" [] in let av = deref_array sv in av_push av (sv_of_string method_) method timeout = int_of_sv (call_method sv "timeout" []) method set_timeout v = call_method_void sv "timeout" [sv_of_int v] method parse_head = bool_of_sv (call_method sv "parse_head" []) method set_parse_head v = call_method_void sv "parse_head" [sv_of_bool v] method max_size = int_of_sv (call_method sv "max_size" []) method set_max_size v = call_method_void sv "max_size" [sv_of_int v] method env_proxy () = call_method_void sv "env_proxy" [] end (* Note that "new" is a reserved word, so I've appended an _ character. *) let new_ ?agent ?from ?timeout ?use_eval ?parse_head ?max_size ?env_proxy ?keep_alive ?cookie_jar ?cookie_jar_file () = let args = ref [] in let may f = function None -> () | Some v -> f v in may (fun v -> args := sv_of_string "agent" :: sv_of_string v :: !args) agent; may (fun v -> args := sv_of_string "from" :: sv_of_string v :: !args) from; may (fun v -> args := sv_of_string "timeout" :: sv_of_int v :: !args) timeout; may (fun v -> args := sv_of_string "use_eval" :: sv_of_bool v :: !args) use_eval; may (fun v -> args := sv_of_string "parse_head" :: sv_of_bool v :: !args)parse_head; may (fun v -> args := sv_of_string "max_size" :: sv_of_int v :: !args) max_size; may (fun v -> args := sv_of_string "env_proxy" :: sv_of_bool v :: !args) env_proxy; may (fun v -> args := sv_of_string "keep_alive" :: sv_of_int v :: !args) keep_alive; may (fun (v : http_cookies) -> args := sv_of_string "cookie_jar" :: v#sv :: !args) cookie_jar; may (fun v -> let hv = hv_empty () in hv_set hv "file" (sv_of_string v); let sv = hashref hv in args := sv_of_string "cookie_jar" :: sv :: !args) cookie_jar_file; let sv = call_class_method "LWP::UserAgent" "new" !args in new lwp_useragent sv perl4caml-0.9.5/wrappers/.cvsignore0000644000076400007640000000003710330373423016643 0ustar rjonesrjones*.cmi *.cmo *.cmx *.cma *.cmxa perl4caml-0.9.5/wrappers/pl_WWW_Mechanize.ml0000644000076400007640000002001710762251735020351 0ustar rjonesrjones(** Wrapper around Perl [WWW::Mechanize] class. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_WWW_Mechanize.ml,v 1.8 2008-03-01 13:02:21 rich Exp $ *) open Perl open Pl_LWP_UserAgent let _ = eval "use WWW::Mechanize" class www_mechanize sv = object (self) inherit lwp_useragent sv method agent_alias alias = call_method_void sv "agent_alias" [sv_of_string alias] method known_agent_aliases = let svlist = call_method_array sv "known_agent_aliases" [] in List.map string_of_sv svlist method get url = call_method_void sv "get" [sv_of_string url] method reload () = call_method_void sv "reload" [] method back () = call_method_void sv "back" [] method follow_link ?text ?text_regex ?url ?url_regex ?url_abs ?url_abs_regex ?name ?name_regex ?tag ?tag_regex ?n () = let args = ref [] in let add name f = function | None -> () | Some p -> args := sv_of_string name :: f p :: !args in add "text" sv_of_string text; add "text_regex" sv_of_string text_regex; add "url" sv_of_string url; add "url_regex" sv_of_string url_regex; add "url_abs" sv_of_string url_abs; add "url_abs_regex" sv_of_string url_abs_regex; add "name" sv_of_string name; add "name_regex" sv_of_string name_regex; add "tag" sv_of_string tag; add "tag_regex" sv_of_string tag_regex; add "n" sv_of_int n; call_method_void sv "follow_link" !args method forms = let svlist = call_method_array sv "forms" [] in List.map (new Pl_HTML_Form.html_form) svlist method form_number n = let sv = call_method sv "form_number" [sv_of_int n] in new Pl_HTML_Form.html_form sv method form_name name = let sv = call_method sv "form_name" [sv_of_string name] in new Pl_HTML_Form.html_form sv (* XXX There is an arrayref variant of this method, but what * it does is apparently undocumented. *) method field ?n name value = let args = match n with None -> [sv_of_string name; sv_of_string value] | Some n -> [sv_of_string name; sv_of_string value; sv_of_int n] in call_method_void sv "field" args method set_fields fields = let args = ref [] in List.iter (fun (k, v) -> (* Note: reversed k, v because we'll reverse the whole list.*) args := sv_of_string v :: sv_of_string k :: !args) fields; let args = List.rev !args in call_method_void sv "set_fields" args method value ?n name = let args = match n with None -> [sv_of_string name] | Some n -> [sv_of_string name; sv_of_int n] in let sv = call_method sv "value" args in string_of_sv sv (* XXX Doesn't support setting criteria. *) method set_visible names = let names = List.map sv_of_string names in call_method_void sv "set_visible" names method tick ?set name value = let args = match set with None -> [ sv_of_string name; sv_of_string value ] | Some b -> [ sv_of_string name; sv_of_string value; sv_of_bool b ] in call_method_void sv "tick" args method untick name value = call_method_void sv "untick" [ sv_of_string name; sv_of_string value ] method click ?xy button = let args = match xy with None -> [ sv_of_string button ] | Some (x, y) -> [ sv_of_string button; sv_of_int x; sv_of_int y ] in call_method_void sv "click" args method click1 () = call_method_void sv "click" [] method click_button ?name ?number ?value ?xy () = let args = ref [] in let add name f = function | None -> () | Some p -> args := sv_of_string name :: f p :: !args in add "name" sv_of_string name; add "number" sv_of_int number; add "value" sv_of_string value; (match xy with None -> () | Some (x, y) -> args := sv_of_string "x" :: sv_of_int x :: sv_of_string "y" :: sv_of_int y :: !args); call_method_void sv "click" !args method select name value = call_method_void sv "select" [ sv_of_string name; sv_of_string value ] method select_multiple name values = let av = av_empty () in List.iter (av_push av) (List.map sv_of_string values); call_method_void sv "select" [ sv_of_string name; arrayref av ] method submit () = call_method_void sv "submit" [] method submit_form ?form_number ?form_name ?fields ?button ?xy () = let args = ref [] in let add name f = function | None -> () | Some p -> args := sv_of_string name :: f p :: !args in add "form_number" sv_of_int form_number; add "form_name" sv_of_string form_name; (match fields with | None -> () | Some fields -> let hv = hv_empty () in List.iter ( fun (name, value) -> hv_set hv name (sv_of_string value) ) fields; let sv = hashref hv in args := sv_of_string "fields" :: sv :: !args ); add "button" sv_of_string button; (match xy with | None -> () | Some (x, y) -> args := sv_of_string "x" :: sv_of_int x :: sv_of_string "y" :: sv_of_int y :: !args); let sv = call_method sv "submit_form" !args in new Pl_HTTP_Response.http_response sv method success = let sv = call_method sv "success" [] in bool_of_sv sv method uri = let sv = call_method sv "uri" [] in string_of_sv sv method response = let sv = call_method sv "response" [] in new Pl_HTTP_Response.http_response sv method res = let sv = call_method sv "res" [] in new Pl_HTTP_Response.http_response sv method status = let sv = call_method sv "status" [] in int_of_sv sv method ct = let sv = call_method sv "ct" [] in string_of_sv sv method base = let sv = call_method sv "base" [] in string_of_sv sv method content = let sv = call_method sv "content" [] in string_of_sv sv (* method current_forms = *) method links = let svs = call_method_array sv "links" [] in List.map (new www_mechanize_link) svs method is_html = let sv = call_method sv "is_html" [] in bool_of_sv sv method title = let sv = call_method sv "title" [] in string_of_sv sv (* method find_link .... = *) (* method find_all_links .... = *) (* method add_header .... = *) (* method delete_header .... = *) method quiet = let sv = call_method sv "quiet" [] in bool_of_sv sv method set_quiet b = call_method_void sv "quiet" [sv_of_bool b] (* method stack_depth ... = *) method redirect_ok = let sv = call_method sv "redirect_ok" [] in bool_of_sv sv (* method request ... = *) (* method update_html ... = *) end and www_mechanize_link sv = object (self) method sv = sv method url = let sv = call_method sv "url" [] in string_of_sv sv method text = let sv = call_method sv "text" [] in string_of_sv sv method name = let sv = call_method sv "name" [] in string_of_sv sv method tag = let sv = call_method sv "tag" [] in string_of_sv sv method base = let sv = call_method sv "base" [] in string_of_sv sv method url_abs = let sv = call_method sv "url_abs" [] in string_of_sv sv end (* XXX Should be able to pass args to constructor of LWP::UserAgent. *) (* XXX WWW::Mechanize has additional parameters. *) let new_ ?autocheck () = let args = ref [] in let may f = function None -> () | Some v -> f v in may (fun v -> args := sv_of_string "autocheck" :: sv_of_bool v :: !args) autocheck; let sv = call_class_method "WWW::Mechanize" "new" !args in new www_mechanize sv perl4caml-0.9.5/wrappers/pl_Net_Google_Cache.ml0000644000076400007640000000261710762251735021015 0ustar rjonesrjones(** Wrapper around Perl [Net::Google::Cache] class. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_Net_Google_Cache.ml,v 1.4 2008-03-01 13:02:21 rich Exp $ *) open Perl let _ = eval "use Net::Google::Cache" class net_google_cache sv = object (self) method key = string_of_sv (call_method sv "key" []) method set_key v = call_method_void sv "key" [sv_of_string v] method url = string_of_sv (call_method sv "url" []) method set_url v = call_method_void sv "url" [sv_of_string v] method get = let sv = call_method sv "get" [] in if sv_is_undef sv then raise Not_found; string_of_sv sv end (* let new_ = ... *) perl4caml-0.9.5/wrappers/pl_HTML_Parser.ml0000644000076400007640000000240510762251735017763 0ustar rjonesrjones(** Wrapper around Perl [HTML::Parser] class. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_HTML_Parser.ml,v 1.5 2008-03-01 13:02:21 rich Exp $ *) open Perl let _ = eval "use HTML::Parser" class html_parser sv = object (self) method parse_file filename = call_method_void sv "parse_file" [sv_of_string filename] method parse content = call_method_void sv "parse" [sv_of_string content] method eof = call_method_void sv "eof" [] method delete () = call_method_void sv "delete" [] end perl4caml-0.9.5/wrappers/pl_URI.ml0000644000076400007640000000540010762251735016340 0ustar rjonesrjones(** Wrapper around Perl [URI] class. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_URI.ml,v 1.6 2008-03-01 13:02:21 rich Exp $ *) open Perl let _ = eval "use URI" class uri sv = object (self) method sv = sv method scheme = string_of_sv (call_method sv "scheme" []) method set_scheme scheme = call_method_void sv "scheme" [sv_of_string scheme] method opaque = string_of_sv (call_method sv "opaque" []) method set_opaque opaque = call_method_void sv "opaque" [sv_of_string opaque] method path = string_of_sv (call_method sv "path" []) method set_path path = call_method_void sv "path" [sv_of_string path] method fragment = string_of_sv (call_method sv "fragment" []) method set_fragment fragment = call_method_void sv "fragment" [sv_of_string fragment] method set_no_fragment () = call_method_void sv "fragment" [sv_undef ()] method as_string = string_of_sv (call_method sv "as_string" []) method canonical = string_of_sv (call_method sv "canonical" []) method abs base = string_of_sv (call_method sv "abs" [sv_of_string base]) method rel base = string_of_sv (call_method sv "rel" [sv_of_string base]) method host = string_of_sv (call_method sv "host" []) method set_host host = call_method_void sv "host" [sv_of_string host] method port = string_of_sv (call_method sv "port" []) method set_port port = call_method_void sv "port" [sv_of_string port] method host_port = string_of_sv (call_method sv "host_port" []) method set_host_port host_port = call_method_void sv "host_port" [sv_of_string host_port] method default_port = int_of_sv (call_method sv "default_port" []) end let new_ ?scheme str = let args = [sv_of_string str] @ match scheme with None -> [] | Some scheme -> [sv_of_string scheme] in let sv = call_class_method "URI" "new" args in new uri sv let new_abs str base = let sv = call_class_method "URI" "new_abs" [sv_of_string str; sv_of_string base] in new uri sv perl4caml-0.9.5/wrappers/pl_HTTP_Message.ml0000644000076400007640000000230210762251735020122 0ustar rjonesrjones(** Wrapper around Perl [HTTP::Message] class. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_HTTP_Message.ml,v 1.5 2008-03-01 13:02:21 rich Exp $ *) open Perl open Pl_HTTP_Headers let _ = eval "use HTTP::Message" class http_message sv = object (self) inherit http_headers sv method content = string_of_sv (call_method sv "content" []) method set_content content = call_method_void sv "set_content" [sv_of_string content] end perl4caml-0.9.5/wrappers/pl_HTTP_Response.ml0000644000076400007640000000407210762251735020342 0ustar rjonesrjones(** Wrapper around Perl [HTTP::Response] class. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_HTTP_Response.ml,v 1.5 2008-03-01 13:02:21 rich Exp $ *) open Perl open Pl_HTTP_Message open Pl_HTTP_Request let _ = eval "use HTTP::Response" class http_response sv = object (self) inherit http_message sv method code = string_of_sv (call_method sv "code" []) method set_code code = call_method_void sv "code" [sv_of_string code] method message = string_of_sv (call_method sv "message" []) method set_message message = call_method_void sv "message" [sv_of_string message] method request = new http_request (call_method sv "request" []) method set_request (req : http_request) = call_method_void sv "request" [req#sv] method status_line = string_of_sv (call_method sv "status_line" []) method base = string_of_sv (call_method sv "base" []) method as_string = string_of_sv (call_method sv "as_string" []) method is_info = bool_of_sv (call_method sv "is_info" []) method is_success = bool_of_sv (call_method sv "is_success" []) method is_redirect = bool_of_sv (call_method sv "is_redirect" []) method is_error = bool_of_sv (call_method sv "is_error" []) method error_as_HTML = string_of_sv (call_method sv "error_as_HTML" []) end (* let new_ ... *) perl4caml-0.9.5/wrappers/pl_Date_Calc.ml0000644000076400007640000000565310762251735017512 0ustar rjonesrjones(** Wrapper around Perl [Date::Calc] class. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_Date_Calc.ml,v 1.2 2008-03-01 13:02:21 rich Exp $ *) open Perl let _ = eval "use Date::Calc qw()" let days_in_year year month = int_of_sv (call ~fn:"Date::Calc::Days_in_Year" [sv_of_int year; sv_of_int month]) let days_in_month year month = int_of_sv (call ~fn:"Date::Calc::Days_in_Month" [sv_of_int year; sv_of_int month]) let weeks_in_year year = int_of_sv (call ~fn:"Date::Calc::Weeks_in_Year" [sv_of_int year]) let leap_year year = bool_of_sv (call ~fn:"Date::Calc::leap_year" [sv_of_int year]) let check_date year month day = bool_of_sv (call ~fn:"Date::Calc::check_date" [sv_of_int year; sv_of_int month; sv_of_int day]) let check_time hour min sec = bool_of_sv (call ~fn:"Date::Calc::check_time" [sv_of_int hour; sv_of_int min; sv_of_int sec]) let check_business_date year week dow = bool_of_sv (call ~fn:"Date::Calc::check_business_date" [sv_of_int year; sv_of_int week; sv_of_int dow]) let day_of_year year month day = int_of_sv (call ~fn:"Date::Calc::Day_of_Year" [sv_of_int year; sv_of_int month; sv_of_int day]) let date_to_days year month day = int_of_sv (call ~fn:"Date::Calc::Date_to_Days" [sv_of_int year; sv_of_int month; sv_of_int day]) let day_of_week year month day = int_of_sv (call ~fn:"Date::Calc::Day_of_Week" [sv_of_int year; sv_of_int month; sv_of_int day]) let week_number year month day = int_of_sv (call ~fn:"Date::Calc::Week_Number" [sv_of_int year; sv_of_int month; sv_of_int day]) let week_of_year year month day = let r = call_array ~fn:"Date::Calc::Week_of_Year" [sv_of_int year; sv_of_int month; sv_of_int day] in match r with [week; year] -> int_of_sv week, int_of_sv year | _ -> failwith "Pl_Date_Calc: week_of_year: unexpected return value" let monday_of_week week year = let r = call_array ~fn:"Date::Calc::Monday_of_Week" [sv_of_int week; sv_of_int year] in match r with [year; month; day] -> int_of_sv year, int_of_sv month, int_of_sv day | _ -> failwith "Pl_Date_Calc: monday_of_week: unexpected return value" (* at this point I got bored ... - RWMJ *) perl4caml-0.9.5/wrappers/pl_Net_Google_Search.ml0000644000076400007640000000530310762251735021212 0ustar rjonesrjones(** Wrapper around Perl [Net::Google::Search] class. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_Net_Google_Search.ml,v 1.4 2008-03-01 13:02:21 rich Exp $ *) open Perl open Pl_Net_Google_Response let _ = eval "use Net::Google::Search" class net_google_search sv = object (self) method key = string_of_sv (call_method sv "key" []) method set_key v = call_method_void sv "key" [sv_of_string v] method query = string_of_sv (call_method sv "query" []) method set_query v = call_method_void sv "query" [sv_of_string v] method starts_at = int_of_sv (call_method sv "starts_at" []) method set_starts_at v = call_method_void sv "starts_at" [sv_of_int v] method max_results = int_of_sv (call_method sv "max_results" []) method set_max_results v = call_method_void sv "max_results" [sv_of_int v] method restrict types = string_of_sv (call_method sv "restrict" (List.map sv_of_string types)) method filter = bool_of_sv (call_method sv "filter" []) method set_filter v = call_method_void sv "filter" [sv_of_bool v] method safe = bool_of_sv (call_method sv "safe" []) method set_safe v = call_method_void sv "safe" [sv_of_bool v] method lr langs = string_of_sv (call_method sv "lr" (List.map sv_of_string langs)) method ie encs = string_of_sv (call_method sv "ie" (List.map sv_of_string encs)) method oe encs = string_of_sv (call_method sv "oe" (List.map sv_of_string encs)) method return_estimatedTotal = bool_of_sv (call_method sv "return_estimatedTotal" []) method set_return_estimatedTotal v = call_method_void sv "return_estimatedTotal" [sv_of_bool v] method response = let sv = call_method sv "response" [] in let av = deref_array sv in av_map (fun sv -> new net_google_response sv) av method results = let sv = call_method sv "results" [] in let av = deref_array sv in av_map (fun sv -> new net_google_response sv) av end (* let new_ = ... *) perl4caml-0.9.5/wrappers/pl_HTML_Form.ml0000644000076400007640000000375410762251735017442 0ustar rjonesrjones(** Wrapper around Perl [HTML::Form] class. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_HTML_Form.ml,v 1.4 2008-03-01 13:02:21 rich Exp $ *) open Perl open Pl_HTTP_Response let _ = eval "use HTML::Form" class html_form (sv : sv) = object (self) method sv = sv method attr name = let sv = call_method sv "attr" [sv_of_string name] in (* sv_is_undef doesn't work properly XXX *) if sv_is_undef sv then None else Some (string_of_sv sv) method set_attr name value = call_method_void sv "attr" [sv_of_string name; sv_of_string value] (* The following isn't a real method. The return type of HTML::Form->inputs * isn't documented, but I wanted a list of input names (as strings) anyway. *) method input_names = let inputs = call_method_array sv "inputs" [] in let names = List.map (fun sv -> call_method sv "name" []) inputs in List.map string_of_sv names end let parse_document html_document base_uri = let svlist = call_class_method_array "HTML::Form" "parse" [sv_of_string html_document; sv_of_string base_uri] in List.map (new html_form) svlist let parse_response (res : http_response) = let svlist = call_class_method_array "HTML::Form" "parse" [res#sv] in List.map (new html_form) svlist perl4caml-0.9.5/wrappers/pl_Net_Google_Spelling.ml0000644000076400007640000000251510762251735021564 0ustar rjonesrjones(** Wrapper around Perl [Net::Google::Spelling] class. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_Net_Google_Spelling.ml,v 1.4 2008-03-01 13:02:21 rich Exp $ *) open Perl let _ = eval "use Net::Google::Spelling" class net_google_spelling sv = object (self) method key = string_of_sv (call_method sv "key" []) method set_key v = call_method_void sv "key" [sv_of_string v] method phrase phrases = string_of_sv (call_method sv "phrase" (List.map sv_of_string phrases)) method suggest = string_of_sv (call_method sv "suggest" []) end (* let new_ = ... *) perl4caml-0.9.5/wrappers/pl_HTTP_Headers.ml0000644000076400007640000000241110762251735020112 0ustar rjonesrjones(** Wrapper around Perl [HTTP::Message] class. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_HTTP_Headers.ml,v 1.3 2008-03-01 13:02:21 rich Exp $ *) open Perl let _ = eval "use HTTP::Headers" class http_headers sv = object (self) method sv = sv method header key = string_of_sv (call_method sv "header" [sv_of_string key]) method set_header key value = call_method_void sv "header" [sv_of_string key; sv_of_string value] method as_string = string_of_sv (call_method sv "as_string" []) end perl4caml-0.9.5/wrappers/pl_HTML_Element.ml0000644000076400007640000000622310762251735020122 0ustar rjonesrjones(** Wrapper around Perl [HTML::Element] class. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_HTML_Element.ml,v 1.5 2008-03-01 13:02:21 rich Exp $ *) open Perl let _ = eval "use HTML::Element" type 'a content_t = Element of 'a | String of string class html_element sv = let rec assocs_of_svlist = function [] -> [] | [x] -> failwith "HTML::Element all_attr returned odd-length list!" | svname :: svvalue :: xs -> (string_of_sv svname, string_of_sv svvalue) :: assocs_of_svlist xs in let rec list_of_svlist = function [] -> [] | sv :: xs -> string_of_sv sv :: list_of_svlist xs in object (self) method sv = sv method attr name = string_of_sv (call_method sv "attr" [sv_of_string name]) method set_attr name value = call_method_void sv "attr" [sv_of_string name; sv_of_string value] method tag = string_of_sv (call_method sv "tag" []) method set_tag tag = call_method_void sv "tag" [sv_of_string tag] method parent = let sv = call_method sv "parent" [] in new html_element sv method set_parent (parent : html_element) = call_method_void sv "parent" [parent#sv] method content_list = let svlist = call_method_array sv "content_list" [] in List.map (fun c -> (* Not very satisfactory, but sv_type fails to discern the type * for some reason. XXX *) let str = string_of_sv c in let marker = "HTML::Element=HASH(" in let marker_len = String.length marker in if String.length str > marker_len && String.sub str 0 marker_len = marker then Element (new html_element c) else String (string_of_sv c) ) svlist method all_attr = let svlist = call_method_array sv "all_attr" [] in assocs_of_svlist svlist method all_attr_names = let svlist = call_method_array sv "all_attr_names" [] in list_of_svlist svlist method all_external_attr = let svlist = call_method_array sv "all_external_attr" [] in assocs_of_svlist svlist method all_external_attr_names = let svlist = call_method_array sv "all_external_attr_names" [] in list_of_svlist svlist end (* Note that "new" is a reserved word, so I've appended an _ character. *) let new_ tag attrs = let rec loop = function [] -> [] | (name, value) :: xs -> sv_of_string name :: sv_of_string value :: loop xs in let sv = call_class_method "HTML::Element" "new" (sv_of_string tag :: loop attrs) in new html_element sv perl4caml-0.9.5/wrappers/pl_HTTP_Cookies.ml0000644000076400007640000000421410762251735020136 0ustar rjonesrjones(** Wrapper around Perl [HTTP::Cookies] class. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_HTTP_Cookies.ml,v 1.2 2008-03-01 13:02:21 rich Exp $ *) open Perl let _ = eval "use HTTP::Cookies" class http_cookies sv = object (self) method sv = sv method save ?filename () = let args = match filename with None -> [] | Some filename -> [sv_of_string filename] in call_method_void sv "save" args method load ?filename () = let args = match filename with None -> [] | Some filename -> [sv_of_string filename] in call_method_void sv "load" args method revert () = call_method_void sv "revert" [] method as_string ?skip_discardables () = let args = match skip_discardables with None -> [] | Some b -> [sv_of_bool b] in string_of_sv (call_method sv "as_string" args) end let new_ ?file ?autosave ?ignore_discard ?hide_cookie2 () = let args = ref [] in let may f = function None -> () | Some v -> f v in may (fun v -> args := sv_of_string "file" :: sv_of_string v :: !args) file; may (fun v -> args := sv_of_string "autosave" :: sv_of_bool v :: !args) autosave; may (fun v -> args := sv_of_string "ignore_discard" :: sv_of_bool v :: !args) ignore_discard; may (fun v -> args := sv_of_string "hide_cookie2" :: sv_of_bool v :: !args) hide_cookie2; let sv = call_class_method "HTTP::Cookies" "new" !args in new http_cookies sv perl4caml-0.9.5/wrappers/pl_HTML_TreeBuilder.ml0000644000076400007640000000321410762251735020734 0ustar rjonesrjones(** Wrapper around Perl [HTML::TreeBuilder] class. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_HTML_TreeBuilder.ml,v 1.4 2008-03-01 13:02:21 rich Exp $ *) open Perl open Pl_HTML_Parser open Pl_HTML_Element let _ = eval "use HTML::TreeBuilder" class html_treebuilder sv = object (self) inherit html_parser sv method elementify = let sv = call_method sv "elementify" [] in new html_element sv end (* Note that "new" is a reserved word, so I've appended an _ character. *) let new_ () = let sv = call_class_method "HTML::TreeBuilder" "new" [] in new html_treebuilder sv let new_from_file filename = let sv = call_class_method "HTML::TreeBuilder" "new_from_file" [sv_of_string filename] in new html_treebuilder sv let new_from_content content = let sv = call_class_method "HTML::TreeBuilder" "new_from_content" [sv_of_string content] in new html_treebuilder sv perl4caml-0.9.5/wrappers/pl_Date_Format.ml0000644000076400007640000000405410762251735020072 0ustar rjonesrjones(** Wrapper around Perl [Date::Format] class. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_Date_Format.ml,v 1.2 2008-03-01 13:02:21 rich Exp $ *) open Perl let _ = eval "use Date::Format qw()" let language lang = call_class_method_void "Date::Format" "language" [sv_of_string lang] (* This is just provided for your convenience so you can pass the resulting * list of SVs directly to the second argument of {!Pl_Date_Format.strftime}. *) let localtime () = call_array ~fn:"localtime" [] let time2str ?zone templ time = let args = [sv_of_string templ; sv_of_float time] @ match zone with None -> [] | Some zone -> [sv_of_string zone] in string_of_sv (call ~fn:"Date::Format::time2str" args) let strftime ?zone templ time = let args = (sv_of_string templ :: time) @ match zone with None -> [] | Some zone -> [sv_of_string zone] in string_of_sv (call ~fn:"Date::Format::strftime" args) let ctime ?zone time = let args = [sv_of_float time] @ match zone with None -> [] | Some zone -> [sv_of_string zone] in string_of_sv (call ~fn:"Date::Format::ctime" args) let asctime ?zone time = let args = [sv_of_float time] @ match zone with None -> [] | Some zone -> [sv_of_string zone] in string_of_sv (call ~fn:"Date::Format::asctime" args) perl4caml-0.9.5/wrappers/pl_HTTP_Request_Common.ml0000644000076400007640000000326110762251735021503 0ustar rjonesrjones(** Wrapper around Perl [HTTP::Request::Common] class. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_HTTP_Request_Common.ml,v 1.2 2008-03-01 13:02:21 rich Exp $ *) open Perl open Pl_HTTP_Request let _ = eval "use HTTP::Request::Common" let get, head, put = let dofn fn url headers = let args = sv_of_string url :: List.fold_right (fun (k, v) rest -> sv_of_string k :: sv_of_string v :: rest) headers [] in new http_request (call ~fn args) in let get = dofn "GET" in let head = dofn "HEAD" in let put = dofn "PUT" in get, head, put let post url ?form headers = let hv = hv_empty () in (match form with | None -> () | Some xs -> List.iter (fun (k, v) -> hv_set hv k (sv_of_string v)) xs); let args = sv_of_string url :: hashref hv :: List.fold_right (fun (k, v) rest -> sv_of_string k :: sv_of_string v :: rest) headers [] in new http_request (call ~fn:"POST" args) perl4caml-0.9.5/wrappers/pl_HTTP_Request.ml0000644000076400007640000000361610762251735020177 0ustar rjonesrjones(** Wrapper around Perl [HTTP::Request] class. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_HTTP_Request.ml,v 1.5 2008-03-01 13:02:21 rich Exp $ *) open Perl open Pl_HTTP_Message open Pl_URI let _ = eval "use HTTP::Request" class http_request sv = object (self) inherit http_message sv method sv = sv method method_ = string_of_sv (call_method sv "method" []) method set_method meth = call_method_void sv "method" [sv_of_string meth] method uri = string_of_sv (call_method sv "uri" []) method set_uri uri = call_method_void sv "uri" [sv_of_string uri] method as_string = string_of_sv (call_method sv "as_string" []) end let new_ meth ?uri_obj ?uri (* ?header ?content *) () = let sv = match uri_obj, uri with None, None -> failwith ("Pl_HTTP_Request.new_ must be called with either a "^ "~uri_obj (URI object) or ~uri (string) parameter.") | Some (uri_obj : uri), None -> call_class_method "HTTP::Request" "new" [sv_of_string meth; uri_obj#sv] | _, Some uri -> call_class_method "HTTP::Request" "new" [sv_of_string meth; sv_of_string uri] in new http_request sv perl4caml-0.9.5/wrappers/pl_Template.ml0000644000076400007640000001644510762251735017467 0ustar rjonesrjones(** Wrapper around Perl [Template] class (Template Toolkit). *) (* Copyright (C) 2003 Dave Benjamin . This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_Template.ml,v 1.3 2008-03-01 13:02:21 rich Exp $ *) open Perl let _ = eval "use Template" exception Not_implemented exception Error of string module Variant = struct type t = | Null | String of string | Int of int | Float of float | Bool of bool | Array of t list | Hash of (string * t) list;; end let rec sv_of_variant = function | Variant.Null -> sv_undef () | Variant.String s -> sv_of_string s | Variant.Int i -> sv_of_int i | Variant.Float f -> sv_of_float f | Variant.Bool b -> sv_of_bool b | Variant.Array xs -> arrayref (av_of_sv_list (List.map sv_of_variant xs)) | Variant.Hash xs -> hashref (let hv = hv_empty () in List.iter (fun (k, v) -> hv_set hv k (sv_of_variant v)) xs; hv );; let hv_of_string_pair_list pairs = let hv = hv_empty () in List.iter (fun (k, v) -> hv_set hv k (sv_of_string v)) pairs; hv class template sv = object (self) method process file vars = let output = sv_of_string "" in let args = [sv_of_string file; sv_of_variant vars; scalarref output] in let result = call_method sv "process" args in if not (sv_is_true result) then raise (Error self#error) else string_of_sv output method error = string_of_sv (call_method sv "error" []) end let may f = function None -> () | Some v -> f v let new_ ?start_tag ?end_tag ?tag_style ?pre_chomp ?post_chomp ?trim ?interpolate ?anycase ?include_path ?delimiter ?absolute ?relative ?default ?blocks ?auto_reset ?recursion ?variables ?constants ?constant_namespace ?namespace ?pre_process ?post_process ?process ?wrapper ?error ?errors ?eval_perl ?output ?output_path ?debug ?debug_format ?cache_size ?compile_ext ?compile_dir ?plugins ?plugin_base ?load_perl ?filters ?v1dollar ?load_templates ?load_plugins ?load_filters ?tolerant ?service ?context ?stash ?parser ?grammar () = let args = ref [] in may (fun v -> args := sv_of_string "START_TAG" :: sv_of_string v :: !args) start_tag; may (fun v -> args := sv_of_string "END_TAG" :: sv_of_string v :: !args) end_tag; may (fun v -> args := sv_of_string "TAG_STYLE" :: sv_of_string v :: !args) tag_style; may (fun v -> args := sv_of_string "PRE_CHOMP" :: sv_of_bool v :: !args) pre_chomp; may (fun v -> args := sv_of_string "POST_CHOMP" :: sv_of_bool v :: !args) post_chomp; may (fun v -> args := sv_of_string "TRIM" :: sv_of_bool v :: !args) trim; may (fun v -> args := sv_of_string "INTERPOLATE" :: sv_of_bool v :: !args) interpolate; may (fun v -> args := sv_of_string "ANYCASE" :: sv_of_bool v :: !args) anycase; may (fun v -> args := sv_of_string "INCLUDE_PATH" :: arrayref (av_of_string_list v) :: !args) include_path; may (fun v -> args := sv_of_string "DELIMITER" :: sv_of_string v :: !args) delimiter; may (fun v -> args := sv_of_string "ABSOLUTE" :: sv_of_bool v :: !args) absolute; may (fun v -> args := sv_of_string "RELATIVE" :: sv_of_bool v :: !args) relative; may (fun v -> args := sv_of_string "DEFAULT" :: sv_of_string v :: !args) default; may (fun v -> args := sv_of_string "BLOCKS" :: hashref (hv_of_string_pair_list v) :: !args) blocks; may (fun v -> args := sv_of_string "AUTO_RESET" :: sv_of_bool v :: !args) auto_reset; may (fun v -> args := sv_of_string "RECURSION" :: sv_of_bool v :: !args) recursion; may (fun v -> args := sv_of_string "VARIABLES" :: sv_of_variant v :: !args) variables; may (fun v -> args := sv_of_string "CONSTANTS" :: sv_of_variant v :: !args) constants; may (fun v -> args := sv_of_string "CONSTANT_NAMESPACE" :: sv_of_string v :: !args) constant_namespace; may (fun v -> args := sv_of_string "NAMESPACE" :: sv_of_variant v :: !args) namespace; may (fun v -> args := sv_of_string "PRE_PROCESS" :: arrayref (av_of_string_list v) :: !args) pre_process; may (fun v -> args := sv_of_string "POST_PROCESS" :: arrayref (av_of_string_list v) :: !args) post_process; may (fun v -> args := sv_of_string "PROCESS" :: arrayref (av_of_string_list v) :: !args) process; may (fun v -> args := sv_of_string "WRAPPER" :: arrayref (av_of_string_list v) :: !args) wrapper; may (fun v -> args := sv_of_string "ERROR" :: sv_of_string v :: !args) error; may (fun v -> args := sv_of_string "ERRORS" :: hashref (hv_of_string_pair_list v) :: !args) errors; may (fun v -> args := sv_of_string "EVAL_PERL" :: sv_of_bool v :: !args) eval_perl; may (fun v -> raise Not_implemented) output; may (fun v -> raise Not_implemented) output_path; may (fun v -> args := sv_of_string "DEBUG" :: sv_of_string v :: !args) debug; may (fun v -> args := sv_of_string "DEBUG_FORMAT" :: sv_of_string v :: !args) debug_format; may (fun v -> args := sv_of_string "CACHE_SIZE" :: sv_of_int v :: !args) cache_size; may (fun v -> args := sv_of_string "COMPILE_EXT" :: sv_of_string v :: !args) compile_ext; may (fun v -> args := sv_of_string "COMPILE_DIR" :: sv_of_string v :: !args) compile_dir; may (fun v -> args := sv_of_string "PLUGINS" :: hashref (hv_of_string_pair_list v) :: !args) plugins; may (fun v -> args := sv_of_string "PLUGIN_BASE" :: arrayref (av_of_string_list v) :: !args) plugin_base; may (fun v -> args := sv_of_string "LOAD_PERL" :: sv_of_bool v :: !args) load_perl; may (fun v -> raise Not_implemented) filters; may (fun v -> args := sv_of_string "V1DOLLAR" :: sv_of_bool v :: !args) v1dollar; may (fun v -> raise Not_implemented) load_templates; may (fun v -> raise Not_implemented) load_plugins; may (fun v -> raise Not_implemented) load_filters; may (fun v -> args := sv_of_string "TOLERANT" :: sv_of_bool v :: !args) tolerant; may (fun v -> raise Not_implemented) service; may (fun v -> raise Not_implemented) context; may (fun v -> raise Not_implemented) stash; may (fun v -> raise Not_implemented) parser; may (fun v -> raise Not_implemented) grammar; let sv = call_class_method "Template" "new" !args in new template sv perl4caml-0.9.5/wrappers/pl_Net_Google_Response.ml0000644000076400007640000000471010762251735021604 0ustar rjonesrjones(** Wrapper around Perl [Net::Google::Reponse] class. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_Net_Google_Response.ml,v 1.4 2008-03-01 13:02:21 rich Exp $ *) open Perl let _ = eval "use Net::Google::Response" class net_google_response sv = object (self) method documentFiltering = bool_of_sv (call_method sv "documentFiltering" []) method searchComments = string_of_sv (call_method sv "searchComments" []) method estimateTotalResultsNumber = int_of_sv (call_method sv "estimateTotalResultsNumber" []) method estimateIsExact = bool_of_sv (call_method sv "estimateIsExact" []) method searchQuery = string_of_sv (call_method sv "searchQuery" []) method startIndex = int_of_sv (call_method sv "startIndex" []) method endIndex = int_of_sv (call_method sv "endIndex" []) method searchTips = string_of_sv (call_method sv "searchTips" []) method directoryCategories = let sv = call_method sv "directoryCategories" [] in let av = deref_array sv in av_map (fun sv -> new net_google_response sv) av method searchTime = float_of_sv (call_method sv "searchTime" []) method toString = string_of_sv (call_method sv "toString" []) method title = string_of_sv (call_method sv "title" []) method url = string_of_sv (call_method sv "URL" []) method snippet = string_of_sv (call_method sv "snippet" []) method cachedSize = string_of_sv (call_method sv "cachedSize" []) method directoryTitle = string_of_sv (call_method sv "directoryTitle" []) method summary = string_of_sv (call_method sv "summary" []) method hostName = string_of_sv (call_method sv "hostName" []) (* method directoryCategory *) end (* let new_ = ... *) perl4caml-0.9.5/wrappers/pl_Date_Parse.ml0000644000076400007640000000264010330373423017701 0ustar rjonesrjones(** Wrapper around Perl [Date::Parse] class. * * Copyright (C) 2003 Merjis Ltd. * * $Id: pl_Date_Parse.ml,v 1.1 2003/11/19 16:28:23 rich Exp $ *) open Perl let _ = eval "use Date::Parse qw()" (* XXX languages not supported yet - when it is supported, it'll be in * [pl_Date_Language] anyway, not here -- RWMJ *) let str2time ?zone date = let args = [sv_of_string date] @ match zone with None -> [] | Some zone -> [sv_of_string zone] in let sv = call ~fn:"Date::Parse::str2time" args in if sv_is_undef sv then invalid_arg "Date::Parse: Could not parse date"; float_of_sv sv let strptime ?zone date = let args = [sv_of_string date] @ match zone with None -> [] | Some zone -> [sv_of_string zone] in let svs = call_array ~fn:"Date::Parse::strptime" args in match svs with [] -> invalid_arg "Date::Parse: Could not parse date" | [ ss; mm; hh; day; month; year; zone ] -> ((if sv_is_undef ss then None else Some (int_of_sv ss)), (if sv_is_undef mm then None else Some (int_of_sv mm)), (if sv_is_undef hh then None else Some (int_of_sv hh)), (if sv_is_undef day then None else Some (int_of_sv day)), (if sv_is_undef month then None else Some (int_of_sv month)), (if sv_is_undef year then None else Some (int_of_sv year)), (if sv_is_undef zone then None else Some (string_of_sv zone))) | _ -> failwith "Pl_Date_Parse: invalid list returned by strptime" perl4caml-0.9.5/wrappers/pl_Net_Google.ml0000644000076400007640000000576410762251735017740 0ustar rjonesrjones(** Wrapper around Perl [Net::Google] class. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_Net_Google.ml,v 1.4 2008-03-01 13:02:21 rich Exp $ *) open Perl open Pl_Net_Google_Cache open Pl_Net_Google_Search open Pl_Net_Google_Spelling let _ = eval "use Net::Google" let may f = function None -> () | Some v -> f v class net_google sv = object (self) method search ?key ?starts_at ?max_results ?lr ?ie ?oe ?safe ?filter () = let args = ref [] in may (fun v -> args := sv_of_string "key" :: sv_of_string v :: !args) key; may (fun v -> args := sv_of_string "starts_at" :: sv_of_int v :: !args) starts_at; may (fun v -> args := sv_of_string "max_results" :: sv_of_int v :: !args) max_results; may (fun v -> args := sv_of_string "lr" :: sv_of_string v :: !args) lr; may (fun v -> args := sv_of_string "ie" :: sv_of_string v :: !args) ie; may (fun v -> args := sv_of_string "oe" :: sv_of_string v :: !args) oe; may (fun v -> args := sv_of_string "safe" :: sv_of_bool v :: !args) safe; may (fun v -> args := sv_of_string "filter" :: sv_of_bool v :: !args) filter; let sv = call_method sv "search" !args in new net_google_search sv method spelling ?key ?phrase ?debug () = let args = ref [] in may (fun v -> args := sv_of_string "key" :: sv_of_string v :: !args) key; may (fun v -> args := sv_of_string "phrase" :: sv_of_string v :: !args) phrase; may (fun v -> args := sv_of_string "debug" :: sv_of_int v :: !args) debug; let sv = call_method sv "spelling" !args in new net_google_spelling sv method cache ?key ?url ?debug () = let args = ref [] in may (fun v -> args := sv_of_string "key" :: sv_of_string v :: !args) key; may (fun v -> args := sv_of_string "url" :: sv_of_string v :: !args) url; may (fun v -> args := sv_of_string "debug" :: sv_of_int v :: !args) debug; let sv = call_method sv "cache" !args in new net_google_cache sv end let new_ ?key ?debug () = let args = ref [] in may (fun v -> args := sv_of_string "key" :: sv_of_string v :: !args) key; may (fun v -> args := sv_of_string "debug" :: sv_of_int v :: !args) debug; let sv = call_class_method "Net::Google" "new" !args in new net_google sv perl4caml-0.9.5/wrappers/pl_Data_Dumper.ml0000644000076400007640000000243010762251735020066 0ustar rjonesrjones(** Wrapper around Perl [Data::Dumper] class. *) (* Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: pl_Data_Dumper.ml,v 1.3 2008-03-01 13:02:21 rich Exp $ *) open Perl let _ = eval "use Data::Dumper" class data_dumper (sv : sv) = object (self) method sv = sv end let new_ r = let sv = call_class_method "Data::Dumper" "new" [r] in new data_dumper sv let dump r = string_of_sv (call_class_method "Data::Dumper" "Dump" [r]) let dump_hv hv = dump (arrayref (av_of_sv_list [hashref hv])) let dump_av av = dump (arrayref av) perl4caml-0.9.5/.depend0000644000076400007640000000727210762251535014260 0ustar rjonesrjonesperl.cmo: perl.cmi perl.cmx: perl.cmi examples/google.cmo: wrappers/pl_Net_Google.cmo examples/google.cmx: wrappers/pl_Net_Google.cmx examples/loadpage.cmo: wrappers/pl_LWP_UserAgent.cmo \ wrappers/pl_HTTP_Request.cmo wrappers/pl_HTML_TreeBuilder.cmo \ wrappers/pl_HTML_Element.cmo examples/loadpage.cmx: wrappers/pl_LWP_UserAgent.cmx \ wrappers/pl_HTTP_Request.cmx wrappers/pl_HTML_TreeBuilder.cmx \ wrappers/pl_HTML_Element.cmx examples/parsedate.cmo: wrappers/pl_Date_Parse.cmo \ wrappers/pl_Date_Format.cmo examples/parsedate.cmx: wrappers/pl_Date_Parse.cmx \ wrappers/pl_Date_Format.cmx examples/test.cmo: perl.cmi examples/test.cmx: perl.cmx wrappers/pl_Data_Dumper.cmo: perl.cmi wrappers/pl_Data_Dumper.cmx: perl.cmx wrappers/pl_Date_Calc.cmo: perl.cmi wrappers/pl_Date_Calc.cmx: perl.cmx wrappers/pl_Date_Format.cmo: perl.cmi wrappers/pl_Date_Format.cmx: perl.cmx wrappers/pl_Date_Parse.cmo: perl.cmi wrappers/pl_Date_Parse.cmx: perl.cmx wrappers/pl_HTML_Element.cmo: perl.cmi wrappers/pl_HTML_Element.cmx: perl.cmx wrappers/pl_HTML_Form.cmo: wrappers/pl_HTTP_Response.cmo perl.cmi wrappers/pl_HTML_Form.cmx: wrappers/pl_HTTP_Response.cmx perl.cmx wrappers/pl_HTML_Parser.cmo: perl.cmi wrappers/pl_HTML_Parser.cmx: perl.cmx wrappers/pl_HTML_TreeBuilder.cmo: wrappers/pl_HTML_Parser.cmo \ wrappers/pl_HTML_Element.cmo perl.cmi wrappers/pl_HTML_TreeBuilder.cmx: wrappers/pl_HTML_Parser.cmx \ wrappers/pl_HTML_Element.cmx perl.cmx wrappers/pl_HTTP_Cookies.cmo: perl.cmi wrappers/pl_HTTP_Cookies.cmx: perl.cmx wrappers/pl_HTTP_Headers.cmo: perl.cmi wrappers/pl_HTTP_Headers.cmx: perl.cmx wrappers/pl_HTTP_Message.cmo: wrappers/pl_HTTP_Headers.cmo perl.cmi wrappers/pl_HTTP_Message.cmx: wrappers/pl_HTTP_Headers.cmx perl.cmx wrappers/pl_HTTP_Request_Common.cmo: wrappers/pl_HTTP_Request.cmo perl.cmi wrappers/pl_HTTP_Request_Common.cmx: wrappers/pl_HTTP_Request.cmx perl.cmx wrappers/pl_HTTP_Request.cmo: wrappers/pl_URI.cmo \ wrappers/pl_HTTP_Message.cmo perl.cmi wrappers/pl_HTTP_Request.cmx: wrappers/pl_URI.cmx \ wrappers/pl_HTTP_Message.cmx perl.cmx wrappers/pl_HTTP_Response.cmo: wrappers/pl_HTTP_Request.cmo \ wrappers/pl_HTTP_Message.cmo perl.cmi wrappers/pl_HTTP_Response.cmx: wrappers/pl_HTTP_Request.cmx \ wrappers/pl_HTTP_Message.cmx perl.cmx wrappers/pl_LWP_UserAgent.cmo: wrappers/pl_HTTP_Response.cmo \ wrappers/pl_HTTP_Request.cmo wrappers/pl_HTTP_Cookies.cmo perl.cmi wrappers/pl_LWP_UserAgent.cmx: wrappers/pl_HTTP_Response.cmx \ wrappers/pl_HTTP_Request.cmx wrappers/pl_HTTP_Cookies.cmx perl.cmx wrappers/pl_Net_Google_Cache.cmo: perl.cmi wrappers/pl_Net_Google_Cache.cmx: perl.cmx wrappers/pl_Net_Google.cmo: wrappers/pl_Net_Google_Spelling.cmo \ wrappers/pl_Net_Google_Search.cmo wrappers/pl_Net_Google_Cache.cmo \ perl.cmi wrappers/pl_Net_Google.cmx: wrappers/pl_Net_Google_Spelling.cmx \ wrappers/pl_Net_Google_Search.cmx wrappers/pl_Net_Google_Cache.cmx \ perl.cmx wrappers/pl_Net_Google_Response.cmo: perl.cmi wrappers/pl_Net_Google_Response.cmx: perl.cmx wrappers/pl_Net_Google_Search.cmo: wrappers/pl_Net_Google_Response.cmo \ perl.cmi wrappers/pl_Net_Google_Search.cmx: wrappers/pl_Net_Google_Response.cmx \ perl.cmx wrappers/pl_Net_Google_Spelling.cmo: perl.cmi wrappers/pl_Net_Google_Spelling.cmx: perl.cmx wrappers/pl_Template.cmo: perl.cmi wrappers/pl_Template.cmx: perl.cmx wrappers/pl_URI.cmo: perl.cmi wrappers/pl_URI.cmx: perl.cmx wrappers/pl_WWW_Mechanize.cmo: wrappers/pl_LWP_UserAgent.cmo \ wrappers/pl_HTTP_Response.cmo wrappers/pl_HTML_Form.cmo perl.cmi wrappers/pl_WWW_Mechanize.cmx: wrappers/pl_LWP_UserAgent.cmx \ wrappers/pl_HTTP_Response.cmx wrappers/pl_HTML_Form.cmx perl.cmx perl4caml-0.9.5/perl_c.c0000644000076400007640000006334410762251735014434 0ustar rjonesrjones/* Interface to Perl from OCaml. Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: perl_c.c,v 1.25 2008-03-01 13:02:21 rich Exp $ */ #include #include #include #include #include #define CAML_NAME_SPACE 1 #include #include #include #include #include #include #include #include /* Perl requires the interpreter to be called literally 'my_perl'! */ static PerlInterpreter *my_perl; /* Get the concrete value from an optional field. */ static value unoption (value option, value deflt); /* Wrap up an arbitrary void pointer in an opaque OCaml object. */ static value Val_voidptr (void *ptr); /* Unwrap an arbitrary void pointer from an opaque OCaml object. */ #define Voidptr_val(type,rv) ((type *) Field ((rv), 0)) #if PERL4CAML_REFCOUNTING_EXPERIMENTAL /* Unwrap a custom block. */ #define Xv_val(rv) (*((void **)Data_custom_val(rv))) /* Wrap up an SV, AV or HV in a custom OCaml object which will decrement * the reference count on finalization. */ static value Val_xv (SV *sv); #else #define Xv_val(rv) Voidptr_val (SV, (rv)) #define Val_xv(sv) Val_voidptr ((sv)) #endif /* Hide Perl types in opaque OCaml objects. */ #define Val_perl(pl) (Val_voidptr ((pl))) #define Perl_val(plv) (Voidptr_val (PerlInterpreter, (plv))) #define Val_sv(sv) (Val_xv ((sv))) #define Sv_val(svv) ((SV *) Xv_val (svv)) #define Val_av(av) (Val_xv ((SV *)(av))) #define Av_val(avv) ((AV *) Xv_val (avv)) #define Val_hv(hv) (Val_xv ((SV *)(hv))) #define Hv_val(hvv) ((HV *) Xv_val (hvv)) #define Val_he(he) (Val_voidptr ((he))) #define He_val(hev) (Voidptr_val (HE, (hev))) static void xs_init (pTHX) { char *file = __FILE__; EXTERN_C void boot_DynaLoader (pTHX_ CV* cv); newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); } CAMLprim value perl4caml_init (value unit) { CAMLparam1 (unit); int argc = 4; static char *argv[] = { "", "-w", "-e", "0", NULL }; PERL_SYS_INIT (&argc, &argv); my_perl = perl_alloc (); perl_construct (my_perl); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_parse (my_perl, xs_init, argc, argv, (char **) NULL); /*perl_run (my_perl);*/ CAMLreturn (Val_unit); } CAMLprim value perl4caml_int_of_sv (value svv) { CAMLparam1 (svv); SV *sv = Sv_val (svv); CAMLreturn (Val_int (SvIV (sv))); } CAMLprim value perl4caml_sv_of_int (value iv) { CAMLparam1 (iv); CAMLreturn (Val_sv (newSViv (Int_val (iv)))); } CAMLprim value perl4caml_float_of_sv (value svv) { CAMLparam1 (svv); SV *sv = Sv_val (svv); CAMLlocal1 (f); f = caml_copy_double (SvNV (sv)); CAMLreturn (f); } CAMLprim value perl4caml_sv_of_float (value fv) { CAMLparam1 (fv); CAMLreturn (Val_sv (newSVnv (Double_val (fv)))); } CAMLprim value perl4caml_string_of_sv (value svv) { CAMLparam1 (svv); SV *sv = Sv_val (svv); char *str; STRLEN len; CAMLlocal1 (strv); str = SvPV (sv, len); strv = caml_alloc_string (len); memcpy (String_val (strv), str, len); CAMLreturn (strv); } CAMLprim value perl4caml_sv_of_string (value strv) { CAMLparam1 (strv); CAMLreturn (Val_sv (newSVpv (String_val (strv), caml_string_length (strv)))); } CAMLprim value perl4caml_sv_is_true (value svv) { CAMLparam1 (svv); SV *sv = Sv_val (svv); CAMLreturn (SvTRUE (sv) ? Val_true : Val_false); } CAMLprim value perl4caml_sv_undef (value unit) { CAMLparam1 (unit); /*CAMLreturn (Val_sv (newSV (0)));*/ CAMLreturn (Val_sv (&PL_sv_undef)); } CAMLprim value perl4caml_sv_is_undef (value svv) { CAMLparam1 (svv); SV *sv = Sv_val (svv); CAMLreturn (!SvPOK (sv) && !SvIOK (sv) && SvTYPE (sv) == SVt_NULL ? Val_true : Val_false); } CAMLprim value perl4caml_sv_yes (value unit) { CAMLparam1 (unit); CAMLreturn (Val_sv (&PL_sv_yes)); } CAMLprim value perl4caml_sv_no (value unit) { CAMLparam1 (unit); CAMLreturn (Val_sv (&PL_sv_no)); } static int sv_type (SV *sv) { switch (SvTYPE (sv)) { case SVt_IV: return 1; case SVt_NV: return 2; case SVt_PV: return 3; case SVt_RV: return 4; case SVt_PVAV: return 5; case SVt_PVHV: return 6; case SVt_PVCV: return 7; case SVt_PVGV: return 8; case SVt_PVMG: return 9; default: return 0; } } CAMLprim value perl4caml_sv_type (value svv) { CAMLparam1 (svv); SV *sv = Sv_val (svv); CAMLreturn (Val_int (sv_type (sv))); } CAMLprim value perl4caml_address_of_sv (value svv) { CAMLparam1 (svv); SV *sv = Sv_val (svv); CAMLreturn (caml_copy_nativeint ((long) sv)); } CAMLprim value perl4caml_address_of_av (value avv) { CAMLparam1 (avv); AV *av = Av_val (avv); CAMLreturn (caml_copy_nativeint ((long) av)); } CAMLprim value perl4caml_address_of_hv (value hvv) { CAMLparam1 (hvv); HV *hv = Hv_val (hvv); CAMLreturn (caml_copy_nativeint ((long) hv)); } 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_reftype (value svv) { CAMLparam1 (svv); SV *sv = Sv_val (svv); if (!SvROK (sv)) caml_invalid_argument ("reftype: SV is not a reference"); CAMLreturn (Val_int (sv_type (SvRV (sv)))); } CAMLprim value perl4caml_deref (value svv) { CAMLparam1 (svv); CAMLlocal1 (rsvv); SV *sv = Sv_val (svv); if (!SvROK (sv)) caml_invalid_argument ("deref: SV is not a reference"); switch (SvTYPE (SvRV (sv))) { case SVt_IV: case SVt_NV: case SVt_PV: case SVt_RV: case SVt_PVMG: break; default: caml_invalid_argument ("deref: SV is not a reference to a scalar"); } sv = SvRV (sv); /* Increment the reference count because we're creating another * value pointing at the referenced SV. */ sv = SvREFCNT_inc (sv); rsvv = Val_sv (sv); CAMLreturn (rsvv); } CAMLprim value perl4caml_deref_array (value svv) { CAMLparam1 (svv); CAMLlocal1 (ravv); SV *sv = Sv_val (svv); if (!SvROK (sv)) caml_invalid_argument ("deref_array: SV is not a reference"); switch (SvTYPE (SvRV (sv))) { case SVt_PVAV: break; default: caml_invalid_argument ("deref_array: SV is not a reference to an array"); } sv = SvRV (sv); /* Increment the reference count because we're creating another * value pointing at the referenced AV. */ sv = SvREFCNT_inc (sv); ravv = Val_av ((AV *) sv); CAMLreturn (ravv); } CAMLprim value perl4caml_deref_hash (value svv) { CAMLparam1 (svv); CAMLlocal1 (rhvv); SV *sv = Sv_val (svv); if (!SvROK (sv)) caml_invalid_argument ("deref_hash: SV is not a reference"); switch (SvTYPE (SvRV (sv))) { case SVt_PVHV: break; default: caml_invalid_argument ("deref_hash: SV is not a reference to a hash"); } sv = SvRV (sv); /* Increment the reference count because we're creating another * value pointing at the referenced HV. */ sv = SvREFCNT_inc (sv); rhvv = Val_hv ((HV *) sv); CAMLreturn (rhvv); } CAMLprim value perl4caml_av_empty (value unit) { CAMLparam1 (unit); AV *av = newAV (); CAMLreturn (Val_av (av)); } /* We don't know in advance how long the list will be, which makes this * a little harder. */ CAMLprim value perl4caml_av_of_sv_list (value svlistv) { CAMLparam1 (svlistv); CAMLlocal1 (svv); SV *sv, **svlist = 0; int alloc = 0, size = 0; AV *av; for (; svlistv != Val_int (0); svlistv = Field (svlistv, 1)) { svv = Field (svlistv, 0); sv = Sv_val (svv); if (size >= alloc) { alloc = alloc == 0 ? 1 : alloc * 2; svlist = realloc (svlist, alloc * sizeof (SV *)); } svlist[size++] = sv; } av = av_make (size, svlist); if (alloc > 0) free (svlist); /* Free memory allocated to SV list. */ CAMLreturn (Val_av (av)); } /* XXX av_map would be faster if we also had sv_list_of_av. */ CAMLprim value perl4caml_av_push (value avv, value svv) { CAMLparam2 (avv, svv); AV *av = Av_val (avv); SV *sv = Sv_val (svv); av_push (av, sv); CAMLreturn (Val_unit); } CAMLprim value perl4caml_av_pop (value avv) { CAMLparam1 (avv); AV *av = Av_val (avv); SV *sv = av_pop (av); /* Increment the reference count because we're creating another * value pointing at the referenced AV. */ sv = SvREFCNT_inc (sv); CAMLreturn (Val_sv (sv)); } CAMLprim value perl4caml_av_unshift (value avv, value svv) { CAMLparam2 (avv, svv); AV *av = Av_val (avv); SV *sv = Sv_val (svv); av_unshift (av, 1); SvREFCNT_inc (sv); if (av_store (av, 0, sv) == 0) SvREFCNT_dec (sv); CAMLreturn (Val_unit); } CAMLprim value perl4caml_av_shift (value avv) { CAMLparam1 (avv); AV *av = Av_val (avv); SV *sv = av_shift (av); /* Increment the reference count because we're creating another * value pointing at the referenced AV. */ sv = SvREFCNT_inc (sv); CAMLreturn (Val_sv (sv)); } CAMLprim value perl4caml_av_length (value avv) { CAMLparam1 (avv); AV *av = Av_val (avv); CAMLreturn (Val_int (av_len (av) + 1)); } CAMLprim value perl4caml_av_set (value avv, value i, value svv) { CAMLparam3 (avv, i, svv); AV *av = Av_val (avv); SV *sv = Sv_val (svv); SvREFCNT_inc (sv); if (av_store (av, Int_val (i), sv) == 0) SvREFCNT_dec (sv); CAMLreturn (Val_unit); } CAMLprim value perl4caml_av_get (value avv, value i) { CAMLparam2 (avv, i); AV *av = Av_val (avv); SV **svp = av_fetch (av, Int_val (i), 0); if (svp == 0) caml_invalid_argument ("av_get: index out of bounds"); /* Increment the reference count because we're creating another * value pointing at the referenced AV. */ *svp = SvREFCNT_inc (*svp); CAMLreturn (Val_sv (*svp)); } CAMLprim value perl4caml_av_clear (value avv) { CAMLparam1 (avv); AV *av = Av_val (avv); av_clear (av); CAMLreturn (Val_unit); } CAMLprim value perl4caml_av_undef (value avv) { CAMLparam1 (avv); AV *av = Av_val (avv); av_undef (av); CAMLreturn (Val_unit); } CAMLprim value perl4caml_av_extend (value avv, value i) { CAMLparam2 (avv, i); AV *av = Av_val (avv); av_extend (av, Int_val (i)); CAMLreturn (Val_unit); } 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), caml_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), caml_string_length (key), 0); if (svp == 0) caml_raise_not_found (); /* Increment the reference count because we're creating another * value pointing at the referenced SV. */ SvREFCNT_inc (*svp); 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), caml_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), caml_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_hv_iterinit (value hvv) { CAMLparam1 (hvv); HV *hv = Hv_val (hvv); int i = hv_iterinit (hv); CAMLreturn (caml_copy_int32 (i)); } CAMLprim value perl4caml_hv_iternext (value hvv) { CAMLparam1 (hvv); CAMLlocal1 (hev); HV *hv = Hv_val (hvv); HE *he = hv_iternext (hv); if (he == NULL) caml_raise_not_found (); hev = Val_he (he); CAMLreturn (hev); } CAMLprim value perl4caml_hv_iterkey (value hev) { CAMLparam1 (hev); CAMLlocal1 (strv); HE *he = He_val (hev); I32 len; char *str = hv_iterkey (he, &len); strv = caml_alloc_string (len); memcpy (String_val (strv), str, len); CAMLreturn (strv); } CAMLprim value perl4caml_hv_iterval (value hvv, value hev) { CAMLparam2 (hvv, hev); CAMLlocal1 (svv); HV *hv = Hv_val (hvv); HE *he = He_val (hev); SV *sv = hv_iterval (hv, he); SvREFCNT_inc (sv); svv = Val_sv (sv); CAMLreturn (svv); } CAMLprim value perl4caml_hv_iternextsv (value hvv) { CAMLparam1 (hvv); CAMLlocal3 (strv, svv, rv); HV *hv = Hv_val (hvv); char *str; I32 len; SV *sv = hv_iternextsv (hv, &str, &len); if (sv == NULL) caml_raise_not_found (); SvREFCNT_inc (sv); svv = Val_sv (sv); strv = caml_alloc_string (len); memcpy (String_val (strv), str, len); /* Construct a tuple (strv, svv). */ rv = caml_alloc_tuple (2); Field (rv, 0) = strv; Field (rv, 1) = svv; CAMLreturn (rv); } CAMLprim value perl4caml_get_sv (value optcreate, value name) { CAMLparam2 (optcreate, name); CAMLlocal1 (create); SV *sv; create = unoption (optcreate, Val_false); sv = get_sv (String_val (name), create == Val_true ? TRUE : FALSE); if (sv == NULL) caml_raise_not_found (); /* Increment the reference count because we're creating another * value pointing at the referenced SV. */ SvREFCNT_inc (sv); CAMLreturn (Val_sv (sv)); } CAMLprim value perl4caml_get_av (value optcreate, value name) { CAMLparam2 (optcreate, name); CAMLlocal1 (create); AV *av; create = unoption (optcreate, Val_false); av = get_av (String_val (name), create == Val_true ? TRUE : FALSE); if (av == NULL) caml_raise_not_found (); /* Increment the reference count because we're creating another * value pointing at the AV. */ SvREFCNT_inc (av); 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) caml_raise_not_found (); /* Increment the reference count because we're creating another * value pointing at the HV. */ SvREFCNT_inc (hv); CAMLreturn (Val_hv (hv)); } static inline void check_perl_failure () { SV *errsv = get_sv ("@", TRUE); if (SvTRUE (errsv)) /* Equivalent of $@ in Perl. */ { CAMLlocal1 (errv); STRLEN n_a; const char *err = SvPV (errsv, n_a); errv = caml_copy_string (err); caml_raise_with_arg (*caml_named_value ("perl4caml_perl_failure"), errv); } } CAMLprim value perl4caml_call (value optsv, value optfnname, value arglist) { CAMLparam3 (optsv, optfnname, arglist); dSP; int count; SV *sv; CAMLlocal3 (errv, svv, fnname); ENTER; SAVETMPS; /* Push the parameter list. */ PUSHMARK (SP); /* Iteration over the linked list. */ for (; arglist != Val_int (0); arglist = Field (arglist, 1)) { svv = Field (arglist, 0); sv = Sv_val (svv); XPUSHs (sv_2mortal (newSVsv (sv))); } PUTBACK; if (optsv != Val_int (0)) { svv = unoption (optsv, Val_false); sv = Sv_val (svv); count = call_sv (sv, G_EVAL|G_SCALAR); } else if (optfnname != Val_int (0)) { fnname = unoption (optfnname, Val_false); count = call_pv (String_val (fnname), G_EVAL|G_SCALAR); } else { fprintf (stderr, "Perl.call: must supply either 'sv' or 'fn' parameters."); abort (); } SPAGAIN; assert (count == 1); /* Pretty sure it should never be anything else. */ /* Pop return value off the stack. Note that the return value on the * stack is mortal, so we need to take a copy. */ sv = newSVsv (POPs); PUTBACK; FREETMPS; LEAVE; check_perl_failure (); svv = Val_sv (sv); CAMLreturn (svv); } CAMLprim value perl4caml_call_array (value optsv, value optfnname, value arglist) { CAMLparam3 (optsv, optfnname, arglist); dSP; int i, count; SV *sv; CAMLlocal5 (errv, svv, fnname, list, cons); ENTER; SAVETMPS; /* Push the parameter list. */ PUSHMARK (SP); /* Iteration over the linked list. */ for (; arglist != Val_int (0); arglist = Field (arglist, 1)) { svv = Field (arglist, 0); sv = Sv_val (svv); XPUSHs (sv_2mortal (newSVsv (sv))); } PUTBACK; if (optsv != Val_int (0)) { svv = unoption (optsv, Val_false); sv = Sv_val (svv); count = call_sv (sv, G_EVAL|G_ARRAY); } else if (optfnname != Val_int (0)) { fnname = unoption (optfnname, Val_false); count = call_pv (String_val (fnname), G_EVAL|G_ARRAY); } else { fprintf (stderr, "Perl.call_array: must supply either 'sv' or 'fn' parameters."); abort (); } SPAGAIN; /* Pop all the return values off the stack into a list. Values on the * stack are mortal, so we must copy them. */ list = Val_int (0); for (i = 0; i < count; ++i) { SV *sv; cons = caml_alloc (2, 0); Field (cons, 1) = list; list = cons; sv = newSVsv (POPs); Field (cons, 0) = Val_sv (sv); } /* Restore the stack. */ PUTBACK; FREETMPS; LEAVE; check_perl_failure (); CAMLreturn (list); } CAMLprim value perl4caml_call_void (value optsv, value optfnname, value arglist) { CAMLparam3 (optsv, optfnname, arglist); dSP; int count; SV *sv; CAMLlocal3 (errv, svv, fnname); ENTER; SAVETMPS; /* Push the parameter list. */ PUSHMARK (SP); /* Iteration over the linked list. */ for (; arglist != Val_int (0); arglist = Field (arglist, 1)) { svv = Field (arglist, 0); sv = Sv_val (svv); XPUSHs (sv_2mortal (newSVsv (sv))); } PUTBACK; if (optsv != Val_int (0)) { svv = unoption (optsv, Val_false); sv = Sv_val (svv); count = call_sv (sv, G_EVAL|G_VOID); } else if (optfnname != Val_int (0)) { fnname = unoption (optfnname, Val_false); count = call_pv (String_val (fnname), G_EVAL|G_VOID|G_DISCARD); } else { fprintf (stderr, "Perl.call_void: must supply either 'sv' or 'fn' parameters."); abort (); } SPAGAIN; assert (count == 0); /* Restore the stack. */ PUTBACK; FREETMPS; LEAVE; check_perl_failure (); CAMLreturn (Val_unit); } CAMLprim value perl4caml_eval (value expr) { CAMLparam1 (expr); dSP; SV *sv; CAMLlocal2 (errv, svv); sv = eval_pv (String_val (expr), G_SCALAR); check_perl_failure (); svv = Val_sv (sv); CAMLreturn (svv); } CAMLprim value perl4caml_call_method (value ref, value name, value arglist) { CAMLparam3 (ref, name, arglist); dSP; int count; SV *sv; CAMLlocal2 (errv, svv); ENTER; SAVETMPS; /* Push the parameter list. */ PUSHMARK (SP); sv = Sv_val (ref); XPUSHs (sv_2mortal (newSVsv (sv))); /* Iteration over the linked list. */ for (; arglist != Val_int (0); arglist = Field (arglist, 1)) { svv = Field (arglist, 0); sv = Sv_val (svv); XPUSHs (sv_2mortal (newSVsv (sv))); } PUTBACK; count = call_method (String_val (name), G_EVAL|G_SCALAR); SPAGAIN; assert (count == 1); /* Pretty sure it should never be anything else. */ /* Pop return value off the stack. Note that the return value on the * stack is mortal, so we need to take a copy. */ sv = newSVsv (POPs); PUTBACK; FREETMPS; LEAVE; check_perl_failure (); svv = Val_sv (sv); CAMLreturn (svv); } CAMLprim value perl4caml_call_method_array (value ref, value name, value arglist) { CAMLparam3 (ref, name, arglist); dSP; int count, i; SV *sv; CAMLlocal4 (errv, svv, list, cons); ENTER; SAVETMPS; /* Push the parameter list. */ PUSHMARK (SP); sv = Sv_val (ref); XPUSHs (sv_2mortal (newSVsv (sv))); /* Iteration over the linked list. */ for (; arglist != Val_int (0); arglist = Field (arglist, 1)) { svv = Field (arglist, 0); sv = Sv_val (svv); XPUSHs (sv_2mortal (newSVsv (sv))); } PUTBACK; count = call_method (String_val (name), G_EVAL|G_ARRAY); SPAGAIN; /* Pop all return values off the stack. Note that the return values on the * stack are mortal, so we need to take a copy. */ list = Val_int (0); for (i = 0; i < count; ++i) { SV *sv; cons = caml_alloc (2, 0); Field (cons, 1) = list; list = cons; sv = newSVsv (POPs); Field (cons, 0) = Val_sv (sv); } /* Restore the stack. */ PUTBACK; FREETMPS; LEAVE; check_perl_failure (); CAMLreturn (list); } CAMLprim value perl4caml_call_method_void (value ref, value name, value arglist) { CAMLparam3 (ref, name, arglist); dSP; int count; SV *sv; CAMLlocal2 (errv, svv); ENTER; SAVETMPS; /* Push the parameter list. */ PUSHMARK (SP); sv = Sv_val (ref); XPUSHs (sv_2mortal (newSVsv (sv))); /* Iteration over the linked list. */ for (; arglist != Val_int (0); arglist = Field (arglist, 1)) { svv = Field (arglist, 0); sv = Sv_val (svv); XPUSHs (sv_2mortal (newSVsv (sv))); } PUTBACK; count = call_method (String_val (name), G_EVAL|G_VOID|G_DISCARD); SPAGAIN; assert (count == 0); /* Restore the stack. */ PUTBACK; FREETMPS; LEAVE; check_perl_failure (); CAMLreturn (Val_unit); } CAMLprim value perl4caml_call_class_method (value classname, value name, value arglist) { CAMLparam3 (classname, name, arglist); dSP; int count; SV *sv; CAMLlocal2 (errv, svv); ENTER; SAVETMPS; /* Push the parameter list. */ PUSHMARK (SP); XPUSHs (sv_2mortal (newSVpv (String_val (classname), 0))); /* Iteration over the linked list. */ for (; arglist != Val_int (0); arglist = Field (arglist, 1)) { svv = Field (arglist, 0); sv = Sv_val (svv); XPUSHs (sv_2mortal (newSVsv (sv))); } PUTBACK; count = call_method (String_val (name), G_EVAL|G_SCALAR); SPAGAIN; assert (count == 1); /* Pretty sure it should never be anything else. */ /* Pop return value off the stack. Note that the return value on the * stack is mortal, so we need to take a copy. */ sv = newSVsv (POPs); PUTBACK; FREETMPS; LEAVE; check_perl_failure (); svv = Val_sv (sv); CAMLreturn (svv); } CAMLprim value perl4caml_call_class_method_array (value classname, value name, value arglist) { CAMLparam3 (classname, name, arglist); dSP; int count, i; SV *sv; CAMLlocal4 (errv, svv, list, cons); ENTER; SAVETMPS; /* Push the parameter list. */ PUSHMARK (SP); XPUSHs (sv_2mortal (newSVpv (String_val (classname), 0))); /* Iteration over the linked list. */ for (; arglist != Val_int (0); arglist = Field (arglist, 1)) { svv = Field (arglist, 0); sv = Sv_val (svv); XPUSHs (sv_2mortal (newSVsv (sv))); } PUTBACK; count = call_method (String_val (name), G_EVAL|G_ARRAY); SPAGAIN; /* Pop all return values off the stack. Note that the return values on the * stack are mortal, so we need to take a copy. */ list = Val_int (0); for (i = 0; i < count; ++i) { cons = caml_alloc (2, 0); Field (cons, 1) = list; list = cons; Field (cons, 0) = Val_sv (newSVsv (POPs)); } /* Restore the stack. */ PUTBACK; FREETMPS; LEAVE; check_perl_failure (); CAMLreturn (list); } CAMLprim value perl4caml_call_class_method_void (value classname, value name, value arglist) { CAMLparam3 (classname, name, arglist); dSP; int count; SV *sv; CAMLlocal2 (errv, svv); ENTER; SAVETMPS; /* Push the parameter list. */ PUSHMARK (SP); XPUSHs (sv_2mortal (newSVpv (String_val (classname), 0))); /* Iteration over the linked list. */ for (; arglist != Val_int (0); arglist = Field (arglist, 1)) { svv = Field (arglist, 0); sv = Sv_val (svv); XPUSHs (sv_2mortal (newSVsv (sv))); } PUTBACK; count = call_method (String_val (name), G_EVAL|G_VOID|G_DISCARD); SPAGAIN; assert (count == 0); /* Restore the stack. */ PUTBACK; FREETMPS; LEAVE; check_perl_failure (); CAMLreturn (Val_unit); } static value Val_voidptr (void *ptr) { CAMLparam0 (); CAMLlocal1 (rv); rv = caml_alloc (1, Abstract_tag); Field(rv, 0) = (value) ptr; CAMLreturn (rv); } #if PERL4CAML_REFCOUNTING_EXPERIMENTAL static void xv_finalize (value v) { /*fprintf (stderr, "about to decrement %p\n", Xv_val (v));*/ SvREFCNT_dec ((SV *) Xv_val (v)); } static struct custom_operations xv_custom_operations = { "xv_custom_operations", xv_finalize, custom_compare_default, custom_hash_default, custom_serialize_default, custom_deserialize_default }; static value Val_xv (SV *sv) { CAMLparam0 (); CAMLlocal1 (rv); rv = caml_alloc_custom (&xv_custom_operations, sizeof (void *), 0, 1); Xv_val (rv) = sv; CAMLreturn (rv); } #endif /* PERL4CAML_REFCOUNTING_EXPERIMENTAL */ static value unoption (value option, value deflt) { if (option == Val_int (0)) /* "None" */ return deflt; else /* "Some 'a" */ return Field (option, 0); } perl4caml-0.9.5/perl.ml0000644000076400007640000001542210762251735014312 0ustar rjonesrjones(* Interface to Perl from OCaml. Copyright (C) 2003 Merjis Ltd. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: perl.ml,v 1.16 2008-03-01 13:02:21 rich Exp $ *) type sv type av type hv exception Perl_failure of string (* Initialization. This must happen first, otherwise other parts of the * program will segfault because of a missing interpreter. *) external c_init : unit -> unit = "perl4caml_init" let () = Callback.register_exception "perl4caml_perl_failure" (Perl_failure ""); c_init (); (* Initialise C code. *) () external int_of_sv : sv -> int = "perl4caml_int_of_sv" external sv_of_int : int -> sv = "perl4caml_sv_of_int" external float_of_sv : sv -> float = "perl4caml_float_of_sv" external sv_of_float : float -> sv = "perl4caml_sv_of_float" external string_of_sv : sv -> string = "perl4caml_string_of_sv" external sv_of_string : string -> sv = "perl4caml_sv_of_string" external sv_is_true : sv -> bool = "perl4caml_sv_is_true" external sv_undef : unit -> sv = "perl4caml_sv_undef" external sv_is_undef : sv -> bool = "perl4caml_sv_is_undef" external sv_yes : unit -> sv = "perl4caml_sv_yes" external sv_no : unit -> sv = "perl4caml_sv_no" let sv_true () = sv_of_int 1 let sv_false () = sv_of_int 0 let bool_of_sv = sv_is_true let sv_of_bool b = if b then sv_true () else sv_false () type sv_t = SVt_NULL | SVt_IV | SVt_NV | SVt_PV | SVt_RV | SVt_PVAV | SVt_PVHV | SVt_PVCV | SVt_PVGV | SVt_PVMG external sv_type : sv -> sv_t = "perl4caml_sv_type" let string_of_sv_t = function SVt_NULL -> "SVt_NULL" | SVt_IV -> "SVt_IV" | SVt_NV -> "SVt_NV" | SVt_PV -> "SVt_PV" | SVt_RV -> "SVt_RV" | SVt_PVAV -> "SVt_PVAV" | SVt_PVHV -> "SVt_PVHV" | SVt_PVCV -> "SVt_PVCV" | SVt_PVGV -> "SVt_PVGV" | SVt_PVMG -> "SVt_PVMG" external reftype : sv -> sv_t = "perl4caml_reftype" external address_of_sv : sv -> Nativeint.t = "perl4caml_address_of_sv" external address_of_av : av -> Nativeint.t = "perl4caml_address_of_av" external address_of_hv : hv -> Nativeint.t = "perl4caml_address_of_hv" external scalarref : sv -> sv = "perl4caml_scalarref" external arrayref : av -> sv = "perl4caml_arrayref" external hashref : hv -> sv = "perl4caml_hashref" external deref : sv -> sv = "perl4caml_deref" external deref_array : sv -> av = "perl4caml_deref_array" external deref_hash : sv -> hv = "perl4caml_deref_hash" external av_empty : unit -> av = "perl4caml_av_empty" external av_of_sv_list : sv list -> av = "perl4caml_av_of_sv_list" external av_push : av -> sv -> unit = "perl4caml_av_push" external av_pop : av -> sv = "perl4caml_av_pop" external av_shift : av -> sv = "perl4caml_av_shift" external av_unshift : av -> sv -> unit = "perl4caml_av_unshift" external av_length : av -> int = "perl4caml_av_length" external av_set : av -> int -> sv -> unit = "perl4caml_av_set" external av_get : av -> int -> sv = "perl4caml_av_get" external av_clear : av -> unit = "perl4caml_av_clear" external av_undef : av -> unit = "perl4caml_av_undef" external av_extend : av -> int -> unit = "perl4caml_av_extend" let av_map f av = let list = ref [] in for i = 0 to av_length av - 1 do list := f (av_get av i) :: !list done; List.rev !list let list_of_av av = let list = ref [] in for i = 0 to av_length av - 1 do list := av_get av i :: !list done; List.rev !list let av_of_string_list strs = av_of_sv_list (List.map sv_of_string strs) external hv_empty : unit -> hv = "perl4caml_hv_empty" external hv_set : hv -> string -> sv -> unit = "perl4caml_hv_set" external hv_get : hv -> string -> sv = "perl4caml_hv_get" external hv_exists : hv -> string -> bool = "perl4caml_hv_exists" external hv_delete : hv -> string -> unit = "perl4caml_hv_delete" external hv_clear : hv -> unit = "perl4caml_hv_clear" external hv_undef : hv -> unit = "perl4caml_hv_undef" type he external hv_iterinit : hv -> Int32.t = "perl4caml_hv_iterinit" external hv_iternext : hv -> he = "perl4caml_hv_iternext" external hv_iterkey : he -> string = "perl4caml_hv_iterkey" external hv_iterval : hv -> he -> sv = "perl4caml_hv_iterval" external hv_iternextsv : hv -> string * sv = "perl4caml_hv_iternextsv" let hv_of_assoc xs = let hv = hv_empty () in List.iter (fun (k, v) -> hv_set hv k v) xs; hv let assoc_of_hv hv = ignore (hv_iterinit hv); (* Someone please rewrite this to make it tail-rec! - Rich. XXX *) let rec loop acc = try let k, v = hv_iternextsv hv in loop ((k, v) :: acc) with Not_found -> acc in loop [] let hv_keys hv = ignore (hv_iterinit hv); (* Someone please rewrite this to make it tail-rec! - Rich. XXX *) let rec loop acc = try let he = hv_iternext hv in let k = hv_iterkey he in loop (k :: acc) with Not_found -> acc in loop [] let hv_values hv = ignore (hv_iterinit hv); (* Someone please rewrite this to make it tail-rec! - Rich. XXX *) let rec loop acc = try let he = hv_iternext hv in let v = hv_iterval hv he in loop (v :: acc) with Not_found -> acc in loop [] external get_sv : ?create:bool -> string -> sv = "perl4caml_get_sv" external get_av : ?create:bool -> string -> av = "perl4caml_get_av" external get_hv : ?create:bool -> string -> hv = "perl4caml_get_hv" external call : ?sv:sv -> ?fn:string -> sv list -> sv = "perl4caml_call" external call_array : ?sv:sv -> ?fn:string -> sv list -> sv list = "perl4caml_call_array" external call_void : ?sv:sv -> ?fn:string -> sv list -> unit = "perl4caml_call_void" external eval : string -> sv = "perl4caml_eval" external call_method : sv -> string -> sv list -> sv = "perl4caml_call_method" external call_method_array : sv -> string -> sv list -> sv list = "perl4caml_call_method_array" external call_method_void : sv -> string -> sv list -> unit = "perl4caml_call_method_void" external call_class_method : string -> string -> sv list -> sv = "perl4caml_call_class_method" external call_class_method_array : string -> string -> sv list -> sv list = "perl4caml_call_class_method_array" external call_class_method_void : string -> string -> sv list -> unit = "perl4caml_call_class_method_void" perl4caml-0.9.5/Makefile.config0000644000076400007640000000454210762251735015723 0ustar rjonesrjones# perl4caml configuration -*- Makefile -*- # Copyright (C) 2003 Merjis Ltd. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library 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 # Library General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this library; see the file COPYING. If not, write to # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # $Id: Makefile.config,v 1.27 2008-03-01 13:02:21 rich Exp $ # PERLINCDIR # Directory containing the Perl include files, eg. . PERLINCDIR := $(shell perl -MConfig -e 'print "$$Config{archlib}/CORE"') # OCAMLLIBDIR # This is where we will install perl4caml (actually in the /perl subdirectory # of this, so you will need to add '-I +perl' when compiling programs). OCAMLLIBDIR := $(shell ocamlc -where) # EXTRA_CFLAGS # You can specify extra flags to be passed to gcc here. # # One flag you might want to pass here is # # -DPERL4CAML_REFCOUNTING_EXPERIMENTAL=1 # # which will turn on experimental support for reference counting. # Without this none of the Perl structures that you allocate will get # freed. With this we try to map Perl's reference counting onto # OCaml's garbage collection by using finalizers. Although the # feature is marked "EXPERIMENTAL", I have fixed most of the bugs # and it's now turned on by default. #EXTRA_CFLAGS := EXTRA_CFLAGS := -DPERL4CAML_REFCOUNTING_EXPERIMENTAL=1 #EXTRA_CFLAGS := -I/Users/rich/OCaml/lib/ocaml/std-lib #EXTRA_CFLAGS := -g # DYNALOADER_HACK # XXX Hack required by ocamlopt, and sometimes ocamlc. # To work out what this should be, try: # `perl -MExtUtils::Embed -e ldopts' DYNALOADER_HACK := $(shell perl -MExtUtils::Embed -e ldopts | egrep -o '/[^[:space:]]*DynaLoader.a') #DYNALOADER_HACK := /usr/lib/perl/5.8/auto/DynaLoader/DynaLoader.a #DYNALOADER_HACK := /System/Library/Perl/5.8.1/darwin-thread-multi-2level/auto/DynaLoader/DynaLoader.a # PACKAGE and VERSION PACKAGE := perl4caml VERSION := 0.9.5 perl4caml-0.9.5/Makefile0000644000076400007640000001355310762251735014461 0ustar rjonesrjones# Interface to Perl from OCaml. # Copyright (C) 2003 Merjis Ltd. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library 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 # Library General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this library; see the file COPYING. If not, write to # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # $Id: Makefile,v 1.33 2008-03-01 13:02:21 rich Exp $ include Makefile.config OCAMLC := ocamlc OCAMLOPT := ocamlopt OCAMLMKLIB := ocamlmklib OCAMLDEP := ocamldep OCAMLDOC := ocamldoc OCAMLCINCS := -I wrappers OCAMLOPTINCS := $(OCAMLCINCS) OCAMLCFLAGS := -w s -g $(OCAMLCINCS) OCAMLOPTFLAGS := -w s $(OCAMLOPTINCS) PERLCFLAGS := $(shell perl -e 'use Config; print $$Config{ccflags};') CC := gcc CFLAGS := -fPIC -Wall -Wno-unused \ -I$(OCAMLLIBDIR) \ -I$(PERLINCDIR) $(PERLCFLAGS) \ $(EXTRA_CFLAGS) $(EXTRA_EXTRA_CFLAGS) LIBPERL := $(shell perl -MExtUtils::Embed -e ldopts) SED := sed OCAMLDOCFLAGS := -html -stars -sort $(OCAMLCINCS) WRAPPERS := \ wrappers/pl_Data_Dumper.cmo \ wrappers/pl_Date_Calc.cmo \ wrappers/pl_Date_Format.cmo \ wrappers/pl_Date_Parse.cmo \ wrappers/pl_Net_Google_Cache.cmo \ wrappers/pl_Net_Google_Response.cmo \ wrappers/pl_Net_Google_Search.cmo \ wrappers/pl_Net_Google_Spelling.cmo \ wrappers/pl_Net_Google.cmo \ wrappers/pl_HTML_Element.cmo \ wrappers/pl_HTML_Parser.cmo \ wrappers/pl_HTML_TreeBuilder.cmo \ wrappers/pl_URI.cmo \ wrappers/pl_HTTP_Cookies.cmo \ wrappers/pl_HTTP_Headers.cmo \ wrappers/pl_HTTP_Message.cmo \ wrappers/pl_HTTP_Request.cmo \ wrappers/pl_HTTP_Request_Common.cmo \ wrappers/pl_HTTP_Response.cmo \ wrappers/pl_HTML_Form.cmo \ wrappers/pl_LWP_UserAgent.cmo \ wrappers/pl_Template.cmo \ wrappers/pl_WWW_Mechanize.cmo all: perl4caml.cma perl4caml.cmxa META all-examples html perl4caml.cma: perl.cmo perl_c.o $(WRAPPERS) $(OCAMLMKLIB) -o perl4caml $(LIBPERL) $^ perl4caml.cmxa: perl.cmx perl_c.o $(WRAPPERS:.cmo=.cmx) $(OCAMLMKLIB) -o perl4caml $(LIBPERL) $^ all-examples: examples/test.bc examples/loadpage.bc examples/google.bc \ examples/test.opt examples/loadpage.opt examples/google.opt \ examples/parsedate.bc examples/parsedate.opt TEST_PROGRAMS := $(patsubst %.ml,%.bc,$(wildcard test/*.ml)) \ $(patsubst %.ml,%.opt,$(wildcard test/*.ml)) test: $(TEST_PROGRAMS) run-tests check: test run-tests: @fails=0; count=0; \ export LD_LIBRARY_PATH=`pwd`:$$LD_LIBRARY_PATH; \ for prog in $(TEST_PROGRAMS); do \ if ! $$prog; then \ echo Test $$prog failed; \ fails=$$(($$fails+1)); \ fi; \ count=$$(($$count+1)); \ done; \ if [ $$fails -eq 0 ]; then \ echo All tests succeeded.; \ exit 0; \ else \ echo $$fails/$$count tests failed.; \ exit 1; \ fi %.bc: %.cmo $(OCAMLC) $(OCAMLCFLAGS) perl4caml.cma $^ -o $@ %.opt: %.cmx $(OCAMLOPT) $(OCAMLOPTFLAGS) -cclib -L. perl4caml.cmxa \ $(DYNALOADER_HACK) $^ -o $@ %.cmi: %.mli $(OCAMLC) $(OCAMLCFLAGS) -c $< %.cmo: %.ml $(OCAMLC) $(OCAMLCFLAGS) -c $< %.cmx: %.ml $(OCAMLOPT) $(OCAMLOPTFLAGS) -c $< .SUFFIXES: .mli .ml .cmi .cmo .cmx META: META.in Makefile.config $(SED) -e 's/@PACKAGE@/$(PACKAGE)/' \ -e 's/@VERSION@/$(VERSION)/' \ < $< > $@ # Clean. JUNKFILES = core *~ *.bak *.cmi *.cmo *.cmx *.cma *.cmxa *.o *.a *.so \ *.bc *.opt clean: rm -f META for d in . examples test wrappers; do \ (cd $$d; rm -f $(JUNKFILES)); \ done # Build dependencies. ifeq ($(wildcard .depend),.depend) include .depend endif depend: .depend .depend: $(wildcard *.ml) $(wildcard *.mli) $(wildcard examples/*.ml) \ $(wildcard wrappers/*.ml) $(OCAMLDEP) $(OCAMLCINCS) *.mli *.ml examples/*.ml wrappers/*.ml \ > .depend # Install. install: rm -rf $(DESTDIR)$(OCAMLLIBDIR)/perl install -c -m 0755 -d $(DESTDIR)$(OCAMLLIBDIR)/perl install -c -m 0755 -d $(DESTDIR)$(OCAMLLIBDIR)/stublibs install -c -m 0644 perl.cmi perl.mli perl4caml.cma perl4caml.cmxa \ perl4caml.a libperl4caml.a META \ $(WRAPPERS:.cmo=.ml) $(WRAPPERS:.cmo=.cmi) \ $(DESTDIR)$(OCAMLLIBDIR)/perl install -c -m 0644 dllperl4caml.so $(DESTDIR)$(OCAMLLIBDIR)/stublibs # Distribution. dist: $(MAKE) check-manifest rm -rf $(PACKAGE)-$(VERSION) mkdir $(PACKAGE)-$(VERSION) tar -cf - -T MANIFEST | tar -C $(PACKAGE)-$(VERSION) -xf - tar zcf $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE)-$(VERSION) rm -rf $(PACKAGE)-$(VERSION) ls -l $(PACKAGE)-$(VERSION).tar.gz check-manifest: @for d in `find -type d -name CVS | grep -v '^\./debian/'`; \ do \ b=`dirname $$d`/; \ awk -F/ '$$1 != "D" {print $$2}' $$d/Entries | \ sed -e "s|^|$$b|" -e "s|^\./||"; \ done | sort > .check-manifest; \ sort MANIFEST > .orig-manifest; \ diff -u .orig-manifest .check-manifest; rv=$$?; \ rm -f .orig-manifest .check-manifest; \ exit $$rv # Debian packages. dpkg: @if [ 0 != `cvs -q update | wc -l` ]; then \ echo Please commit all changes to CVS first.; \ exit 1; \ fi $(MAKE) dist rm -rf /tmp/dbuild mkdir /tmp/dbuild cp $(PACKAGE)-$(VERSION).tar.gz \ /tmp/dbuild/$(PACKAGE)_$(VERSION).orig.tar.gz export CVSROOT=`cat CVS/Root`; \ cd /tmp/dbuild && \ cvs export \ -d $(PACKAGE)-$(VERSION) \ -D now merjis/test/perl4caml cd /tmp/dbuild/$(PACKAGE)-$(VERSION) && dpkg-buildpackage -rfakeroot rm -rf /tmp/dbuild/$(PACKAGE)-$(VERSION) ls -l /tmp/dbuild # Documentation. html: html/index.html html/index.html: $(wildcard *.ml) $(wildcard *.mli) $(wildcard wrappers/*.ml) rm -rf html mkdir html -$(OCAMLDOC) $(OCAMLDOCFLAGS) -d html $^ .PHONY: depend dist check-manifest html dpkg test run-testsperl4caml-0.9.5/AUTHORS0000644000076400007640000000031610330373424014051 0ustar rjonesrjonesRichard W.M. Jones (rich@annexia.org) - Main developer. Olivier Andrieu - Helped me to work around OCaml initialization bug. Dave Benjamin (dave at 3dex dot com) - Implemented Template Toolkit wrapper.perl4caml-0.9.5/examples/0000775000076400007640000000000010762251536014631 5ustar rjonesrjonesperl4caml-0.9.5/examples/.cvsignore0000644000076400007640000000005110330373422016611 0ustar rjonesrjones*.cmi *.cmo *.cmx *.cma *.cmxa *.bc *.optperl4caml-0.9.5/examples/test.ml0000644000076400007640000000365210330373422016134 0ustar rjonesrjones(* Simple test of the API. * Copyright (C) 2003 Merjis Ltd. * $Id: test.ml,v 1.7 2004/11/25 22:16:17 rich Exp $ *) open Printf let () = (* Perform a full collection - good way to find bugs in initialization code*) Gc.full_major (); (* Load "test.pl". *) Perl.eval "require 'examples/test.pl'"; (* Call some subroutines in [test.pl]. *) let sv = Perl.call ~fn:"return_one" [] in printf "return_one returned %d\n" (Perl.int_of_sv sv); flush stdout; let sv = Perl.call ~fn:"adder" [Perl.sv_of_int 3; Perl.sv_of_int 4] in printf "adder (3, 4) = %d\n" (Perl.int_of_sv sv); flush stdout; let svlist = Perl.call_array ~fn:"return_array" [] in print_string "array returned:"; List.iter ( fun sv -> printf " %d" (Perl.int_of_sv sv); ) svlist; printf "\n"; flush stdout; let sv = Perl.sv_of_string "return_one" in let sv = Perl.call ~sv [] in printf "return_one returned %d\n" (Perl.int_of_sv sv); flush stdout; (* Call a Perl closure. *) let sv = Perl.call ~fn:"return_closure" [] in let sv = Perl.call ~sv [Perl.sv_of_int 3; Perl.sv_of_int 4] in printf "closure returned %d\n" (Perl.int_of_sv sv); flush stdout; (* Evaluate a simple expression. *) Perl.eval "$a = 3"; printf "$a contains %d\n" (Perl.int_of_sv (Perl.get_sv "a")); flush stdout; (* Test calling methods in the "TestClass" class. *) let obj = Perl.call_class_method "TestClass" "new" [] in let sv = Perl.call_method obj "get_foo" [] in printf "TestClass.foo is %d\n" (Perl.int_of_sv sv); flush stdout; Perl.call_method obj "set_foo" [Perl.sv_of_int 2]; let sv = Perl.call_method obj "get_foo" [] in printf "TestClass.foo is %d\n" (Perl.int_of_sv sv); flush stdout; (* Create an undef value and test it. *) let undef = Perl.sv_undef () in printf "sv_is_undef (undef) = %s\n" (string_of_bool (Perl.sv_is_undef undef)); (* Perform a full collection - good way to find GC/allocation bugs. *) Gc.full_major () perl4caml-0.9.5/examples/parsedate.ml0000644000076400007640000000133310330373422017117 0ustar rjonesrjones(* Example program which uses Date::Parse. * Copyright (C) 2003 Merjis Ltd. * $Id: parsedate.ml,v 1.2 2003/12/11 17:41:52 rich Exp $ *) open Printf open Pl_Date_Parse open Pl_Date_Format let () = (* Parse dates passed on the command line. *) if Array.length Sys.argv <= 1 then eprintf "parsedate [list of quoted date strings ...]\n" else ( let strings = List.tl (Array.to_list Sys.argv) in List.iter (fun s -> printf "input string = '%s' ->\n" s; let t = str2time s in printf "\ttime_t = %f\n" t; let s = ctime t in printf "\tconverted back to string = %s\n" s; printf "\n" ) strings ); (* Perform a full collection - good way to find GC/allocation bugs. *) Gc.full_major () perl4caml-0.9.5/examples/google.ml0000644000076400007640000000160110330373422016421 0ustar rjonesrjones(* Example program which uses Net::Google to query Google. * You will need to have a Google API key in ~/.googlekey for this to work. * Copyright (C) 2003 Merjis Ltd. * $Id: google.ml,v 1.4 2003/12/11 17:41:52 rich Exp $ *) open Printf open Pl_Net_Google let () = (* Load Google API key. *) let home = Sys.getenv "HOME" in let chan = open_in (home ^ "/.googlekey") in let key = input_line chan in close_in chan; (* Create the Google query object. *) let google = Pl_Net_Google.new_ ~key () in (* Search. *) let search = google#search () in search#set_query "merjis"; search#set_max_results 5; printf "Top 5 results for \"merjis\":\n"; flush stdout; List.iter (fun response -> printf "* %s\n \n\n" response#title response#url ) search#results; (* Perform a full collection - good way to find GC/allocation bugs. *) Gc.full_major () perl4caml-0.9.5/examples/test.pl0000644000076400007640000000074410330373422016136 0ustar rjonesrjonesuse lib "examples"; use TestClass; print "this is loading the 'test.pl' script!\n"; sub return_one { print "this is the 'return_one' function!\n"; 1 } sub return_array { print "this is the 'return_array' function!\n"; (1, 2, 3) } sub return_closure { sub { $_[0] * $_[1] } } sub dies { print "this is the 'dies' function! about to die now ...\n"; die "this is the exception message from 'dies'"; } sub adder { $_[0] + $_[1] } perl4caml-0.9.5/examples/TestClass.pm0000644000076400007640000000041510330373422017060 0ustar rjonesrjonespackage TestClass; sub new { my $class = shift; my $self = { foo => 1 }; bless $self, $class; } sub get_foo { my $self = shift; $self->{foo} } sub set_foo { my $self = shift; my $value = shift; $self->{foo} = $value } 1; perl4caml-0.9.5/examples/loadpage.ml0000644000076400007640000000304610330373422016726 0ustar rjonesrjones(* Example program which uses LWP::UserAgent and HTML::TreeBuilder to * download an HTTP page and parse it. * Copyright (C) 2003 Merjis Ltd. * $Id: loadpage.ml,v 1.5 2003/12/11 17:41:52 rich Exp $ *) open Printf open Pl_LWP_UserAgent open Pl_HTTP_Request open Pl_HTML_TreeBuilder open Pl_HTML_Element let () = let site = if Array.length Sys.argv >= 2 then Sys.argv.(1) else "http://www.merjis.com/" in (* Create the UserAgent object. *) let ua = Pl_LWP_UserAgent.new_ ~env_proxy:true () in (* Fetch the page. *) let req = Pl_HTTP_Request.new_ "GET" ~uri:site () in let res = ua#request req in if not res#is_success then failwith ("Error while fetching " ^ site ^ ": " ^ res#status_line); (* Extract the content of the page. *) let content = res#content in (* Parse it using HTML::TreeBuilder. *) let tree = Pl_HTML_TreeBuilder.new_from_content content in (* Turn the tree into an HTML::Element. *) let tree = tree#elementify in (* Print out the resulting tree. *) let rec print root = let tag = root#tag in let attrs = root#all_external_attr in let subnodes = root#content_list in printf "Start tag: %s\n" tag; List.iter (fun (name, value) -> printf "\tAttr: %s=\"%s\"\n" name value) attrs; List.iter (fun node -> match node with Element node -> print node | String str -> printf "String: %s\n" str) subnodes; printf "End tag: %s\n" tag in print tree; (* Perform a full collection - good way to find GC/allocation bugs. *) Gc.full_major ()